javac ast indices: clear indices when indices was corrupted; do not fail a compilation IDEA-169031

This commit is contained in:
Dmitry Batkovich
2017-03-03 16:06:39 +03:00
parent 1e1c15d6de
commit 54e91d549e
4 changed files with 62 additions and 54 deletions
@@ -72,7 +72,7 @@ public class BackwardReferenceIndexBuilder extends ModuleLevelBuilder {
myCompiledTargets.clear();
}
BackwardReferenceIndexWriter.closeIfNeed();
BackwardReferenceIndexWriter.closeIfNeed(false);
}
@Override
@@ -89,7 +89,7 @@ public class BackwardReferenceIndexBuilder extends ModuleLevelBuilder {
if (writer != null) {
final Exception cause = writer.getRebuildRequestCause();
if (cause != null) {
throw new RebuildRequestedException(cause);
BackwardReferenceIndexWriter.closeIfNeed(true);
}
if (dirtyFilesHolder.hasRemovedFiles()) {
@@ -22,6 +22,7 @@ import org.jetbrains.jps.backwardRefs.index.CompiledFileData;
import org.jetbrains.jps.javac.ast.api.JavacDef;
import org.jetbrains.jps.javac.ast.api.JavacRef;
import java.io.IOException;
import java.util.*;
public class BackwardReferenceIndexUtil {
@@ -29,47 +30,53 @@ public class BackwardReferenceIndexUtil {
Collection<? extends JavacRef> refs,
List<JavacDef> defs,
final BackwardReferenceIndexWriter writer) {
final int fileId = writer.enumeratePath(filePath);
int funExprId = 0;
final Map<LightRef, Void> definitions = new HashMap<>(defs.size());
final Map<LightRef, Collection<LightRef>> backwardHierarchyMap = new HashMap<>();
try {
final int fileId = writer.enumeratePath(filePath);
int funExprId = 0;
for (JavacDef def : defs) {
if (def instanceof JavacDef.JavacClassDef) {
JavacRef.JavacClass sym = (JavacRef.JavacClass)def.getDefinedElement();
final LightRef.JavaLightClassRef aClass = writer.asClassUsage(sym);
definitions.put(aClass, null);
final Map<LightRef, Void> definitions = new HashMap<>(defs.size());
final Map<LightRef, Collection<LightRef>> backwardHierarchyMap = new HashMap<>();
final JavacRef[] superClasses = ((JavacDef.JavacClassDef)def).getSuperClasses();
for (JavacRef superClass : superClasses) {
LightRef.JavaLightClassRef superClassRef = writer.asClassUsage(superClass);
for (JavacDef def : defs) {
if (def instanceof JavacDef.JavacClassDef) {
JavacRef.JavacClass sym = (JavacRef.JavacClass)def.getDefinedElement();
final LightRef.JavaLightClassRef aClass = writer.asClassUsage(sym);
definitions.put(aClass, null);
Collection<LightRef> children = backwardHierarchyMap.get(superClassRef);
if (children == null) {
backwardHierarchyMap.put(superClassRef, children = new SmartList<>());
final JavacRef[] superClasses = ((JavacDef.JavacClassDef)def).getSuperClasses();
for (JavacRef superClass : superClasses) {
LightRef.JavaLightClassRef superClassRef = writer.asClassUsage(superClass);
Collection<LightRef> children = backwardHierarchyMap.get(superClassRef);
if (children == null) {
backwardHierarchyMap.put(superClassRef, children = new SmartList<>());
}
children.add(aClass);
}
children.add(aClass);
}
else if (def instanceof JavacDef.JavacFunExprDef) {
final LightRef.JavaLightClassRef functionalType = writer.asClassUsage(def.getDefinedElement());
int id = funExprId++;
LightRef.JavaLightFunExprDef result = new LightRef.JavaLightFunExprDef(id);
definitions.put(result, null);
ContainerUtil.getOrCreate(backwardHierarchyMap, functionalType,
(Factory<Collection<LightRef>>)() -> new SmartList<>()).add(result);
}
}
else if (def instanceof JavacDef.JavacFunExprDef) {
final LightRef.JavaLightClassRef functionalType = writer.asClassUsage(def.getDefinedElement());
int id = funExprId++;
LightRef.JavaLightFunExprDef result = new LightRef.JavaLightFunExprDef(id);
definitions.put(result, null);
ContainerUtil.getOrCreate(backwardHierarchyMap, functionalType,
(Factory<Collection<LightRef>>)() -> new SmartList<>()).add(result);
Map<LightRef, Void> convertedRefs = new HashMap<>(refs.size());
for (JavacRef ref : refs) {
LightRef key = writer.enumerateNames(ref);
if (key != null) {
convertedRefs.put(key, null);
}
}
writer.writeData(fileId, new CompiledFileData(backwardHierarchyMap, convertedRefs, definitions));
}
Map<LightRef, Void> convertedRefs = new HashMap<>(refs.size());
for (JavacRef ref : refs) {
LightRef key = writer.enumerateNames(ref);
if (key != null) {
convertedRefs.put(key, null);
}
catch (IOException e) {
writer.setRebuildCause(e);
}
writer.writeData(fileId, new CompiledFileData(backwardHierarchyMap, convertedRefs, definitions));
}
}
@@ -15,6 +15,7 @@
*/
package org.jetbrains.jps.backwardRefs;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.SystemProperties;
import com.intellij.util.indexing.InvertedIndex;
import org.jetbrains.annotations.NotNull;
@@ -49,12 +50,20 @@ public class BackwardReferenceIndexWriter {
return myIndex.getRebuildRequestCause();
}
public static void closeIfNeed() {
void setRebuildCause(Exception e) {
myIndex.setRebuildRequestCause(e);
}
public static void closeIfNeed(boolean clearIndex) {
if (ourInstance != null) {
File dir = clearIndex ? ourInstance.myIndex.getIndicesDir() : null;
try {
ourInstance.close();
} finally {
ourInstance = null;
if (dir != null) {
FileUtil.delete(dir);
}
}
}
}
@@ -97,11 +106,11 @@ public class BackwardReferenceIndexWriter {
return SystemProperties.getBooleanProperty(PROP_KEY, false);
}
synchronized LightRef.JavaLightClassRef asClassUsage(JavacRef aClass) {
synchronized LightRef.JavaLightClassRef asClassUsage(JavacRef aClass) throws IOException {
return new LightRef.JavaLightClassRef(id(aClass, myIndex.getByteSeqEum()));
}
void processDeletedFiles(Collection<String> files) {
void processDeletedFiles(Collection<String> files) throws IOException {
for (String file : files) {
writeData(enumeratePath(new File(file).getPath()), null);
}
@@ -113,13 +122,8 @@ public class BackwardReferenceIndexWriter {
}
}
synchronized int enumeratePath(String file) {
try {
return myIndex.getFilePathEnumerator().enumerate(file);
}
catch (IOException e) {
throw new BuildDataCorruptedException(e);
}
synchronized int enumeratePath(String file) throws IOException {
return myIndex.getFilePathEnumerator().enumerate(file);
}
private void close() {
@@ -127,7 +131,7 @@ public class BackwardReferenceIndexWriter {
}
@Nullable
LightRef enumerateNames(JavacRef ref) {
LightRef enumerateNames(JavacRef ref) throws IOException {
NameEnumerator nameEnumerator = myIndex.getByteSeqEum();
if (ref instanceof JavacRef.JavacClass) {
if (!isPrivate(ref) && !((JavacRef.JavacClass)ref).isAnonymous()) {
@@ -157,18 +161,12 @@ public class BackwardReferenceIndexWriter {
return ref.getModifiers().contains(Modifier.PRIVATE);
}
private int id(JavacRef ref, NameEnumerator nameEnumerator) {
private static int id(JavacRef ref, NameEnumerator nameEnumerator) throws IOException {
return id(ref.getName(), nameEnumerator);
}
private int id(String name, NameEnumerator nameEnumerator) {
try {
return nameEnumerator.enumerate(name);
}
catch (IOException ex) {
myIndex.setRebuildRequestCause(ex);
return 0;
}
private static int id(String name, NameEnumerator nameEnumerator) throws IOException {
return nameEnumerator.enumerate(name);
}
private static boolean isRebuildInAllJavaModules(CompileContext context) {
@@ -140,6 +140,10 @@ public class CompilerBackwardReferenceIndex {
return myRebuildRequestCause;
}
File getIndicesDir() {
return myIndicesDir;
}
public static void removeIndexFiles(File buildDir) {
final File indexDir = getIndexDir(buildDir);
if (indexDir.exists()) {
@@ -192,7 +196,6 @@ public class CompilerBackwardReferenceIndex {
}
void setRebuildRequestCause(Exception e) {
LOG.error(e);
myRebuildRequestCause = e;
}