Fixing dependencies & nested modules

This commit is contained in:
Andrey Breslav
2011-10-30 12:03:10 +03:00
parent 473779befa
commit fc01eb2dcf
6 changed files with 92 additions and 81 deletions
@@ -1,23 +1,95 @@
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Sets;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.ex.CompilerPathsEx;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamespace; import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import java.util.Set;
/** /**
* @author abreslav * @author abreslav
*/ */
public class AnalyzerFacade { public class AnalyzerFacade {
private static final AnalyzingUtils ANALYZING_UTILS = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS);
private final static Key<CachedValue<BindingContext>> BINDING_CONTEXT = Key.create("BINDING_CONTEXT");
private static final Object lock = new Object();
public static BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { public static BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
return AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespace(namespace, flowDataTraceFactory); return ANALYZING_UTILS.analyzeNamespace(namespace, flowDataTraceFactory);
} }
public static BindingContext analyzeFileWithCache(@NotNull JetFile file) { public static BindingContext analyzeFileWithCache(@NotNull final JetFile file) {
return AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeFileWithCache(file); return analyzeFileWithCache(ANALYZING_UTILS, file);
} }
public static BindingContext analyzeFileWithCache(@NotNull final AnalyzingUtils analyzingUtils, @NotNull final JetFile file) {
// TODO : Synchronization?
CachedValue<BindingContext> bindingContextCachedValue = file.getUserData(BINDING_CONTEXT);
if (bindingContextCachedValue == null) {
bindingContextCachedValue = CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider<BindingContext>() {
@Override
public Result<BindingContext> compute() {
synchronized (lock) {
final Project project = file.getProject();
final Set<JetDeclaration> namespaces = Sets.newLinkedHashSet();
ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
if (rootManager != null && !ApplicationManager.getApplication().isUnitTestMode()) {
VirtualFile[] contentRoots = rootManager.getContentRoots();
CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() {
@Override
protected void acceptFile(VirtualFile file, String fileRoot, String filePath) {
if (!(file.getName().endsWith(".kt") || file.getName().endsWith(".kts"))) return;
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile instanceof JetFile) {
namespaces.add(((JetFile) psiFile).getRootNamespace());
}
}
});
}
else {
namespaces.add(file.getRootNamespace());
}
try {
BindingContext bindingContext = analyzingUtils.analyzeNamespaces(project, namespaces, JetControlFlowDataTraceFactory.EMPTY);
return new Result<BindingContext>(bindingContext, PsiModificationTracker.MODIFICATION_COUNT);
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Throwable e) {
e.printStackTrace();
BindingTraceContext bindingTraceContext = new BindingTraceContext();
bindingTraceContext.report(Errors.EXCEPTION_WHILE_ANALYZING.on(file, e));
return new Result<BindingContext>(bindingTraceContext.getBindingContext(), PsiModificationTracker.MODIFICATION_COUNT);
}
}
}
}, false);
file.putUserData(BINDING_CONTEXT, bindingContextCachedValue);
}
return bindingContextCachedValue.getValue();
}
} }
@@ -1,18 +1,9 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Lists;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.ex.CompilerPathsEx;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.psi.PsiElement;
import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElementVisitor;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.*;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
@@ -20,27 +11,20 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamespace; import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
//import org.jetbrains.jet.lang.resolve.java.JavaPackageScope;
//import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
/** /**
* @author abreslav * @author abreslav
*/ */
public class AnalyzingUtils { public class AnalyzingUtils {
private final static Key<CachedValue<BindingContext>> BINDING_CONTEXT = Key.create("BINDING_CONTEXT");
private static final Object lock = new Object();
public static AnalyzingUtils getInstance(@NotNull ImportingStrategy importingStrategy) { public static AnalyzingUtils getInstance(@NotNull ImportingStrategy importingStrategy) {
return new AnalyzingUtils(importingStrategy); return new AnalyzingUtils(importingStrategy);
} }
@@ -78,7 +62,7 @@ public class AnalyzingUtils {
return analyzeNamespaces(project, declarations, flowDataTraceFactory); return analyzeNamespaces(project, declarations, flowDataTraceFactory);
} }
public BindingContext analyzeNamespaces(@NotNull Project project, @NotNull List<? extends JetDeclaration> declarations, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { public BindingContext analyzeNamespaces(@NotNull Project project, @NotNull Collection<? extends JetDeclaration> declarations, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
BindingTraceContext bindingTraceContext = new BindingTraceContext(); BindingTraceContext bindingTraceContext = new BindingTraceContext();
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project); JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project);
@@ -121,54 +105,4 @@ public class AnalyzingUtils {
return bindingTraceContext.getBindingContext(); return bindingTraceContext.getBindingContext();
} }
public BindingContext analyzeFileWithCache(@NotNull final JetFile file) {
// TODO : Synchronization?
CachedValue<BindingContext> bindingContextCachedValue = file.getUserData(BINDING_CONTEXT);
if (bindingContextCachedValue == null) {
bindingContextCachedValue = CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider<BindingContext>() {
@Override
public Result<BindingContext> compute() {
synchronized (lock) {
final Project project = file.getProject();
final List<JetDeclaration> namespaces = Lists.newArrayList();
ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
if (rootManager != null && !ApplicationManager.getApplication().isUnitTestMode()) {
VirtualFile[] contentRoots = rootManager.getContentRoots();
CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() {
@Override
protected void acceptFile(VirtualFile file, String fileRoot, String filePath) {
if (!(file.getName().endsWith(".kt") || file.getName().endsWith(".kts"))) return;
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile instanceof JetFile) {
namespaces.add(((JetFile) psiFile).getRootNamespace());
}
}
});
}
else {
namespaces.add(file.getRootNamespace());
}
try {
// JetNamespace rootNamespace = file.getRootNamespace();
BindingContext bindingContext = analyzeNamespaces(project, namespaces, JetControlFlowDataTraceFactory.EMPTY);
return new Result<BindingContext>(bindingContext, PsiModificationTracker.MODIFICATION_COUNT);
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Throwable e) {
e.printStackTrace();
BindingTraceContext bindingTraceContext = new BindingTraceContext();
// bindingTraceContext.getErrorHandler().genericError(file.getNode(), e.getClass().getSimpleName() + ": " + e.getMessage());
bindingTraceContext.report(Errors.EXCEPTION_WHILE_ANALYZING.on(file, e));
return new Result<BindingContext>(bindingTraceContext.getBindingContext(), PsiModificationTracker.MODIFICATION_COUNT);
}
}
}
}, false);
file.putUserData(BINDING_CONTEXT, bindingContextCachedValue);
}
return bindingContextCachedValue.getValue();
}
} }
@@ -4,12 +4,15 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List;
/** /**
* @author abreslav * @author abreslav
@@ -23,7 +26,7 @@ public class TopDownAnalyzer {
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope outerScope, @NotNull JetScope outerScope,
NamespaceLike owner, NamespaceLike owner,
@NotNull List<? extends JetDeclaration> declarations, @NotNull Collection<? extends JetDeclaration> declarations,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
process(semanticServices, trace, outerScope, owner, declarations, flowDataTraceFactory, false); process(semanticServices, trace, outerScope, owner, declarations, flowDataTraceFactory, false);
} }
@@ -33,7 +36,7 @@ public class TopDownAnalyzer {
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope outerScope, @NotNull JetScope outerScope,
NamespaceLike owner, NamespaceLike owner,
@NotNull List<? extends JetDeclaration> declarations, @NotNull Collection<? extends JetDeclaration> declarations,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
boolean declaredLocally) { boolean declaredLocally) {
TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace); TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace);
@@ -36,7 +36,7 @@ public class TypeHierarchyResolver {
this.context = context; this.context = context;
} }
public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<? extends JetDeclaration> declarations) { public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull Collection<? extends JetDeclaration> declarations) {
collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes
processTypeImports(); processTypeImports();
@@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.ImportingStrategy; import org.jetbrains.jet.lang.resolve.ImportingStrategy;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -80,7 +81,7 @@ public class CheckerTestUtilTest extends JetLiteFixture {
} }
public void test(PsiFile psiFile) { public void test(PsiFile psiFile) {
BindingContext bindingContext = AnalyzingUtils.getInstance(ImportingStrategy.NONE).analyzeFileWithCache((JetFile) psiFile); BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE), (JetFile) psiFile);
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString(); String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString();
List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList(); List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList();
@@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.ImportingStrategy; import org.jetbrains.jet.lang.resolve.ImportingStrategy;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import java.util.List; import java.util.List;
@@ -39,7 +40,7 @@ public class QuickJetPsiCheckerTest extends JetLiteFixture {
createAndCheckPsiFile(name, clearText); createAndCheckPsiFile(name, clearText);
JetFile jetFile = (JetFile) myFile; JetFile jetFile = (JetFile) myFile;
BindingContext bindingContext = AnalyzingUtils.getInstance(ImportingStrategy.NONE).analyzeFileWithCache(jetFile); BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE), jetFile);
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, bindingContext.getDiagnostics(), new CheckerTestUtil.DiagnosticDiffCallbacks() { CheckerTestUtil.diagnosticsDiff(diagnosedRanges, bindingContext.getDiagnostics(), new CheckerTestUtil.DiagnosticDiffCallbacks() {
@Override @Override