Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -85,7 +85,7 @@ public class AnalyzerFacade {
|
||||
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project);
|
||||
return AnalyzingUtils.analyzeNamespacesWithGivenTrace(
|
||||
project,
|
||||
JavaBridgeConfiguration.createJavaBridgeConfiguration(project, bindingTraceContext, StandardConfiguration.createStandardConfiguration(project, semanticServices)),
|
||||
JavaBridgeConfiguration.createJavaBridgeConfiguration(project, bindingTraceContext, StandardConfiguration.createStandardConfiguration(project)),
|
||||
declarations,
|
||||
filesToAnalyzeCompletely,
|
||||
flowDataTraceFactory,
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithTextRange;
|
||||
import org.jetbrains.jet.lang.diagnostics.Severity;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
@@ -50,6 +51,7 @@ public class CheckerTestUtil {
|
||||
}
|
||||
|
||||
public interface DiagnosticDiffCallbacks {
|
||||
@NotNull PsiFile getFile();
|
||||
void missingDiagnostic(String type, int expectedStart, int expectedEnd);
|
||||
void unexpectedDiagnostic(String type, int actualStart, int actualEnd);
|
||||
}
|
||||
@@ -129,6 +131,7 @@ public class CheckerTestUtil {
|
||||
|
||||
private static void unexpectedDiagnostics(List<Diagnostic> actual, DiagnosticDiffCallbacks callbacks) {
|
||||
for (Diagnostic diagnostic : actual) {
|
||||
if (!diagnostic.getFactory().getPsiFile(diagnostic).equals(callbacks.getFile())) continue;
|
||||
TextRange textRange = getTextRange(diagnostic);
|
||||
callbacks.unexpectedDiagnostic(diagnostic.getFactory().getName(), textRange.getStartOffset(), textRange.getEndOffset());
|
||||
}
|
||||
@@ -136,6 +139,7 @@ public class CheckerTestUtil {
|
||||
|
||||
private static void missingDiagnostics(DiagnosticDiffCallbacks callbacks, DiagnosedRange currentExpected) {
|
||||
for (String type : currentExpected.getDiagnostics()) {
|
||||
if (!currentExpected.getFile().equals(callbacks.getFile())) return;
|
||||
callbacks.missingDiagnostic(type, currentExpected.getStart(), currentExpected.getEnd());
|
||||
}
|
||||
}
|
||||
@@ -393,6 +397,7 @@ public class CheckerTestUtil {
|
||||
private final int start;
|
||||
private int end;
|
||||
private final Multiset<String> diagnostics = HashMultiset.create();
|
||||
private PsiFile file;
|
||||
|
||||
private DiagnosedRange(int start) {
|
||||
this.start = start;
|
||||
@@ -417,5 +422,14 @@ public class CheckerTestUtil {
|
||||
public void addDiagnostic(String diagnostic) {
|
||||
diagnostics.add(diagnostic);
|
||||
}
|
||||
|
||||
public void setFile(@NotNull PsiFile file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiFile getFile() {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.jetbrains.jet.lang.psi.JetImportDirective;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.ImportsResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
|
||||
/**
|
||||
@@ -15,24 +14,19 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
*/
|
||||
public class StandardConfiguration implements Configuration {
|
||||
private Project project;
|
||||
private JetSemanticServices services;
|
||||
|
||||
public static StandardConfiguration createStandardConfiguration(Project project, JetSemanticServices services) {
|
||||
return new StandardConfiguration(services, project);
|
||||
public static StandardConfiguration createStandardConfiguration(Project project) {
|
||||
return new StandardConfiguration(project);
|
||||
}
|
||||
|
||||
private StandardConfiguration(JetSemanticServices services, Project project) {
|
||||
this.services = services;
|
||||
private StandardConfiguration(Project project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefaultImports(@NotNull BindingTrace trace, @NotNull WritableScope rootScope) {
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
||||
JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, "std.*");
|
||||
if (ImportsResolver.importNamespace(importDirective, rootScope, temporaryTrace, services)) {
|
||||
temporaryTrace.commit();
|
||||
}
|
||||
new ImportsResolver.ImportResolver(trace, true).processImportReference(importDirective, rootScope, rootScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -74,9 +74,9 @@ public class AnalyzingUtils {
|
||||
@NotNull Configuration configuration,
|
||||
@NotNull Collection<? extends JetDeclaration> declarations,
|
||||
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
|
||||
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
|
||||
@NotNull JetSemanticServices semanticServices) {
|
||||
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
||||
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
||||
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project);
|
||||
return analyzeNamespacesWithGivenTrace(project, configuration, declarations, filesToAnalyzeCompletely, flowDataTraceFactory, bindingTraceContext, semanticServices);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public interface BindingContext {
|
||||
WritableSlice<JetReferenceExpression, DeclarationDescriptor> REFERENCE_TARGET = new BasicWritableSlice<JetReferenceExpression, DeclarationDescriptor>(DO_NOTHING);
|
||||
WritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>> RESOLVED_CALL = new BasicWritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>>(DO_NOTHING);
|
||||
|
||||
WritableSlice<JetReferenceExpression, Collection<? extends ResolvedCallImpl<? extends DeclarationDescriptor>>> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice<JetReferenceExpression, Collection<? extends ResolvedCallImpl<? extends DeclarationDescriptor>>>(DO_NOTHING);
|
||||
WritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>>(DO_NOTHING);
|
||||
|
||||
WritableSlice<JetExpression, FunctionDescriptor> LOOP_RANGE_ITERATOR = Slices.createSimpleSlice();
|
||||
WritableSlice<JetExpression, CallableDescriptor> LOOP_RANGE_HAS_NEXT = Slices.createSimpleSlice();
|
||||
|
||||
@@ -29,6 +29,7 @@ public class DeclarationResolver {
|
||||
resolveConstructorHeaders();
|
||||
resolveAnnotationStubsOnClassesAndConstructors();
|
||||
resolveFunctionAndPropertyHeaders();
|
||||
context.getImportsResolver().processMembersImports();
|
||||
}
|
||||
|
||||
private void resolveConstructorHeaders() {
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.UNRESOLVED_REFERENCE;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.UNSUPPORTED;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
* @author svtk
|
||||
*/
|
||||
public class ImportsResolver {
|
||||
private final TopDownAnalysisContext context;
|
||||
@@ -26,90 +28,188 @@ public class ImportsResolver {
|
||||
}
|
||||
|
||||
public void processTypeImports() {
|
||||
processImports(true);
|
||||
}
|
||||
|
||||
public void processMembersImports() {
|
||||
processImports(false);
|
||||
}
|
||||
|
||||
private void processImports(boolean firstPhase) {
|
||||
ImportResolver importResolver = new ImportResolver(context.getTrace(), firstPhase);
|
||||
for (JetNamespace jetNamespace : context.getNamespaceDescriptors().keySet()) {
|
||||
processImports(jetNamespace, context.getNamespaceScopes().get(jetNamespace), context.getDeclaringScopes().get(jetNamespace));
|
||||
WritableScope namespaceScope = context.getNamespaceScopes().get(jetNamespace);
|
||||
if (firstPhase) {
|
||||
context.getConfiguration().addDefaultImports(context.getTrace(), namespaceScope);
|
||||
}
|
||||
|
||||
List<JetImportDirective> importDirectives = jetNamespace.getImportDirectives();
|
||||
for (JetImportDirective importDirective : importDirectives) {
|
||||
importResolver.processImportReference(importDirective, namespaceScope, context.getDeclaringScopes().get(jetNamespace));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processImports(@NotNull JetNamespace namespace, @NotNull WritableScope namespaceScope, @NotNull JetScope outerScope) {
|
||||
context.getConfiguration().addDefaultImports(context.getTrace(), namespaceScope);
|
||||
public static class ImportResolver {
|
||||
private BindingTrace trace;
|
||||
private boolean firstPhase;
|
||||
|
||||
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
|
||||
for (JetImportDirective importDirective : importDirectives) {
|
||||
public ImportResolver(BindingTrace trace, boolean firstPhase) {
|
||||
this.trace = trace;
|
||||
this.firstPhase = firstPhase;
|
||||
}
|
||||
|
||||
public void processImportReference(JetImportDirective importDirective, WritableScope namespaceScope, JetScope outerScope) {
|
||||
if (importDirective.isAbsoluteInRootNamespace()) {
|
||||
context.getTrace().report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
|
||||
continue;
|
||||
trace.report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
|
||||
return;
|
||||
}
|
||||
if (importDirective.isAllUnder()) {
|
||||
importNamespace(importDirective, namespaceScope, context.getTrace(), context.getSemanticServices());
|
||||
JetExpression importedReference = importDirective.getImportedReference();
|
||||
if (importedReference == null) return;
|
||||
Collection<DeclarationDescriptor> descriptors;
|
||||
if (importedReference instanceof JetQualifiedExpression) {
|
||||
descriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) importedReference, namespaceScope);
|
||||
}
|
||||
else {
|
||||
ClassifierDescriptor classifierDescriptor = null;
|
||||
NamespaceDescriptor namespaceDescriptor = null;
|
||||
JetSimpleNameExpression referenceExpression = null;
|
||||
|
||||
JetExpression importedReference = importDirective.getImportedReference();
|
||||
if (importedReference instanceof JetDotQualifiedExpression) {
|
||||
JetDotQualifiedExpression reference = (JetDotQualifiedExpression) importedReference;
|
||||
JetType type = context.getSemanticServices().getTypeInferrerServices(context.getTrace()).getTypeWithNamespaces(namespaceScope, reference.getReceiverExpression());
|
||||
JetExpression selectorExpression = reference.getSelectorExpression();
|
||||
if (selectorExpression != null) {
|
||||
referenceExpression = (JetSimpleNameExpression) selectorExpression;
|
||||
String referencedName = referenceExpression.getReferencedName();
|
||||
if (type != null && referencedName != null) {
|
||||
classifierDescriptor = type.getMemberScope().getClassifier(referencedName);
|
||||
namespaceDescriptor = type.getMemberScope().getNamespace(referencedName);
|
||||
assert importedReference instanceof JetSimpleNameExpression;
|
||||
JetScope scope = importDirective.isAllUnder() ? namespaceScope : outerScope;
|
||||
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, scope);
|
||||
}
|
||||
if (importDirective.isAllUnder()) {
|
||||
if (firstPhase) {
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
if (descriptor instanceof NamespaceDescriptor) {
|
||||
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
JetSimpleNameExpression referenceExpression = getLastReference(importedReference);
|
||||
|
||||
String aliasName = importDirective.getAliasName();
|
||||
if (aliasName == null) {
|
||||
aliasName = referenceExpression != null ? referenceExpression.getReferencedName() : null;
|
||||
}
|
||||
if (aliasName == null) return;
|
||||
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
importDeclarationAlias(namespaceScope, aliasName, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private void importDeclarationAlias(WritableScope namespaceScope, String aliasName, DeclarationDescriptor descriptor) {
|
||||
if (firstPhase) {
|
||||
if (descriptor instanceof ClassifierDescriptor) {
|
||||
namespaceScope.importClassifierAlias(aliasName, (ClassifierDescriptor) descriptor);
|
||||
return;
|
||||
}
|
||||
if (descriptor instanceof NamespaceDescriptor) {
|
||||
namespaceScope.importNamespaceAlias(aliasName, (NamespaceDescriptor) descriptor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
namespaceScope.importFunctionAlias(aliasName, (FunctionDescriptor) descriptor);
|
||||
return;
|
||||
}
|
||||
if (descriptor instanceof VariableDescriptor) {
|
||||
namespaceScope.importVariableAlias(aliasName, (VariableDescriptor) descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JetSimpleNameExpression getLastReference(JetExpression importedReference) {
|
||||
if (importedReference instanceof JetDotQualifiedExpression) {
|
||||
JetDotQualifiedExpression reference = (JetDotQualifiedExpression) importedReference;
|
||||
JetExpression selectorExpression = reference.getSelectorExpression();
|
||||
return (selectorExpression != null) ? (JetSimpleNameExpression) selectorExpression : null;
|
||||
}
|
||||
assert importedReference instanceof JetSimpleNameExpression;
|
||||
return (JetSimpleNameExpression) importedReference;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<DeclarationDescriptor> lookupDescriptorsForQualifiedExpression(@NotNull JetQualifiedExpression importedReference, @NotNull JetScope outerScope) {
|
||||
JetExpression receiverExpression = importedReference.getReceiverExpression();
|
||||
Collection<DeclarationDescriptor> declarationDescriptors;
|
||||
if (receiverExpression instanceof JetQualifiedExpression) {
|
||||
declarationDescriptors = lookupDescriptorsForQualifiedExpression((JetQualifiedExpression) receiverExpression, outerScope);
|
||||
}
|
||||
else {
|
||||
assert receiverExpression instanceof JetSimpleNameExpression;
|
||||
declarationDescriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) receiverExpression, outerScope);
|
||||
}
|
||||
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
|
||||
JetExpression selectorExpression = importedReference.getSelectorExpression();
|
||||
assert selectorExpression instanceof JetSimpleNameExpression;
|
||||
JetSimpleNameExpression selector = (JetSimpleNameExpression) selectorExpression;
|
||||
if (declarationDescriptor instanceof NamespaceDescriptor) {
|
||||
return lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope());
|
||||
}
|
||||
if (declarationDescriptor instanceof ClassDescriptor) {
|
||||
JetSimpleNameExpression classReference = getLastReference(receiverExpression);
|
||||
if (classReference != null) {
|
||||
return lookupObjectMembers(selector, classReference, (ClassDescriptor) declarationDescriptor);
|
||||
}
|
||||
}
|
||||
if (declarationDescriptor instanceof VariableDescriptor) {
|
||||
return lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor);
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<DeclarationDescriptor> lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull JetSimpleNameExpression classReference, @NotNull ClassDescriptor classDescriptor) {
|
||||
if (firstPhase) return Collections.emptyList();
|
||||
JetType classObjectType = classDescriptor.getClassObjectType();
|
||||
if (classObjectType == null || !classDescriptor.isClassObjectAValue()) {
|
||||
trace.report(NO_CLASS_OBJECT.on(classReference, classDescriptor));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<DeclarationDescriptor> lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) {
|
||||
if (firstPhase) return Collections.emptyList();
|
||||
|
||||
JetType variableType = variableDescriptor.getReturnType();
|
||||
if (variableType == null) return Collections.emptyList();
|
||||
return lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<DeclarationDescriptor> lookupDescriptorsForSimpleNameReference(@NotNull JetSimpleNameExpression referenceExpression, @NotNull JetScope outerScope) {
|
||||
List<DeclarationDescriptor> descriptors = Lists.newArrayList();
|
||||
String referencedName = referenceExpression.getReferencedName();
|
||||
if (referencedName != null) {
|
||||
NamespaceDescriptor namespaceDescriptor = outerScope.getNamespace(referencedName);
|
||||
if (namespaceDescriptor != null) descriptors.add(namespaceDescriptor);
|
||||
|
||||
ClassifierDescriptor classifierDescriptor = outerScope.getClassifier(referencedName);
|
||||
if (classifierDescriptor != null) descriptors.add(classifierDescriptor);
|
||||
|
||||
Set<FunctionDescriptor> functionDescriptors = outerScope.getFunctions(referencedName);
|
||||
descriptors.addAll(functionDescriptors);
|
||||
|
||||
VariableDescriptor variableDescriptor = outerScope.getVariable(referencedName);
|
||||
if (variableDescriptor != null) descriptors.add(variableDescriptor);
|
||||
|
||||
}
|
||||
if (!firstPhase) {
|
||||
if (descriptors.size() == 1) {
|
||||
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.iterator().next());
|
||||
}
|
||||
else if (descriptors.size() > 1) {
|
||||
trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, descriptors);
|
||||
}
|
||||
else {
|
||||
assert importedReference instanceof JetSimpleNameExpression;
|
||||
referenceExpression = (JetSimpleNameExpression) importedReference;
|
||||
|
||||
String referencedName = referenceExpression.getReferencedName();
|
||||
if (referencedName != null) {
|
||||
classifierDescriptor = outerScope.getClassifier(referencedName);
|
||||
namespaceDescriptor = outerScope.getNamespace(referencedName);
|
||||
|
||||
if (classifierDescriptor == null && namespaceDescriptor == null) {
|
||||
context.getTrace().report(UNRESOLVED_REFERENCE.on(referenceExpression));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String aliasName = importDirective.getAliasName();
|
||||
if (aliasName == null) {
|
||||
aliasName = referenceExpression != null ? referenceExpression.getReferencedName() : null;
|
||||
}
|
||||
if (classifierDescriptor != null) {
|
||||
context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor);
|
||||
|
||||
if (aliasName != null) {
|
||||
namespaceScope.importClassifierAlias(aliasName, classifierDescriptor);
|
||||
}
|
||||
}
|
||||
if (namespaceDescriptor != null) {
|
||||
if (classifierDescriptor == null) {
|
||||
context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, namespaceDescriptor);
|
||||
}
|
||||
if (aliasName != null) {
|
||||
namespaceScope.importNamespaceAlias(aliasName, namespaceDescriptor);
|
||||
}
|
||||
trace.report(UNRESOLVED_REFERENCE.on(referenceExpression));
|
||||
}
|
||||
}
|
||||
return descriptors;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean importNamespace(JetImportDirective importDirective, WritableScope namespaceScope, @NotNull BindingTrace trace, @NotNull JetSemanticServices services) {
|
||||
JetExpression importedReference = importDirective.getImportedReference();
|
||||
if (importedReference != null) {
|
||||
ExpressionTypingServices typeInferrerServices = services.getTypeInferrerServices(trace);
|
||||
JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference);
|
||||
if (type != null) {
|
||||
namespaceScope.importScope(type.getMemberScope());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.Set;
|
||||
private final Configuration configuration;
|
||||
|
||||
private final DescriptorResolver descriptorResolver;
|
||||
private final ImportsResolver importsResolver;
|
||||
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
|
||||
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
|
||||
protected final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
|
||||
@@ -48,6 +49,7 @@ import java.util.Set;
|
||||
this.trace = new ObservableBindingTrace(trace);
|
||||
this.semanticServices = semanticServices;
|
||||
this.descriptorResolver = semanticServices.getClassDescriptorResolver(trace);
|
||||
this.importsResolver = new ImportsResolver(this);
|
||||
this.analyzeCompletely = analyzeCompletely;
|
||||
this.configuration = configuration;
|
||||
this.declaredLocally = declaredLocally;
|
||||
@@ -100,6 +102,10 @@ import java.util.Set;
|
||||
return descriptorResolver;
|
||||
}
|
||||
|
||||
public ImportsResolver getImportsResolver() {
|
||||
return importsResolver;
|
||||
}
|
||||
|
||||
public Map<JetClass, MutableClassDescriptor> getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
@@ -32,19 +32,17 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||
*/
|
||||
public class TypeHierarchyResolver {
|
||||
private final TopDownAnalysisContext context;
|
||||
private final ImportsResolver importsResolver;
|
||||
private LinkedList<MutableClassDescriptor> topologicalOrder;
|
||||
|
||||
|
||||
public TypeHierarchyResolver(TopDownAnalysisContext context) {
|
||||
this.context = context;
|
||||
this.importsResolver = new ImportsResolver(context);
|
||||
}
|
||||
|
||||
public void process(@NotNull JetScope outerScope, @NotNull NamespaceLike owner, @NotNull Collection<? extends JetDeclaration> declarations) {
|
||||
collectNamespacesAndClassifiers(outerScope, outerScope, owner, declarations); // namespaceScopes, classes
|
||||
|
||||
importsResolver.processTypeImports();
|
||||
context.getImportsResolver().processTypeImports();
|
||||
|
||||
createTypeConstructors(); // create type constructors for classes and generic parameters, supertypes are not filled in
|
||||
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
|
||||
|
||||
@@ -260,7 +260,11 @@ public class CallResolver {
|
||||
|
||||
@Override
|
||||
public <D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<ResolvedCallImpl<D>> candidates) {
|
||||
trace.record(AMBIGUOUS_REFERENCE_TARGET, reference, candidates);
|
||||
Collection<D> descriptors = Sets.newHashSet();
|
||||
for (ResolvedCallImpl<D> candidate : candidates) {
|
||||
descriptors.add(candidate.getCandidateDescriptor());
|
||||
}
|
||||
trace.record(AMBIGUOUS_REFERENCE_TARGET, reference, descriptors);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,6 +30,10 @@ public interface WritableScope extends JetScope {
|
||||
void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor);
|
||||
|
||||
void addNamespaceAlias(@NotNull String name, @NotNull NamespaceDescriptor namespaceDescriptor);
|
||||
|
||||
void addFunctionAlias(@NotNull String name, @NotNull FunctionDescriptor functionDescriptor);
|
||||
|
||||
void addVariableAlias(@NotNull String name, @NotNull VariableDescriptor variableDescriptor);
|
||||
|
||||
void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor);
|
||||
|
||||
@@ -42,5 +46,9 @@ public interface WritableScope extends JetScope {
|
||||
|
||||
void importClassifierAlias(@NotNull String importedClassifierName, @NotNull ClassifierDescriptor classifierDescriptor);
|
||||
|
||||
void importNamespaceAlias(String aliasName, NamespaceDescriptor namespaceDescriptor);
|
||||
void importNamespaceAlias(@NotNull String aliasName, @NotNull NamespaceDescriptor namespaceDescriptor);
|
||||
|
||||
void importFunctionAlias(@NotNull String aliasName, @NotNull FunctionDescriptor functionDescriptor);
|
||||
|
||||
void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor);
|
||||
}
|
||||
|
||||
@@ -68,13 +68,30 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importNamespaceAlias(String aliasName, NamespaceDescriptor namespaceDescriptor) {
|
||||
public void importNamespaceAlias(@NotNull String aliasName, @NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
allDescriptors.add(namespaceDescriptor);
|
||||
super.importNamespaceAlias(aliasName, namespaceDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importFunctionAlias(@NotNull String aliasName, @NotNull FunctionDescriptor functionDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
addFunctionDescriptor(functionDescriptor);
|
||||
super.importFunctionAlias(aliasName, functionDescriptor);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
addVariableDescriptor(variableDescriptor);
|
||||
super.importVariableAlias(aliasName, variableDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
@@ -240,6 +257,24 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
allDescriptors.add(namespaceDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFunctionAlias(@NotNull String name, @NotNull FunctionDescriptor functionDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
checkForRedeclaration(name, functionDescriptor);
|
||||
getFunctionGroups().put(name, functionDescriptor);
|
||||
allDescriptors.add(functionDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addVariableAlias(@NotNull String name, @NotNull VariableDescriptor variableDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
checkForRedeclaration(name, variableDescriptor);
|
||||
getVariableClassOrNamespaceDescriptors().put(name, variableDescriptor);
|
||||
allDescriptors.add(variableDescriptor);
|
||||
}
|
||||
|
||||
private void checkForRedeclaration(String name, DeclarationDescriptor classifierDescriptor) {
|
||||
DeclarationDescriptor originalDescriptor = getVariableClassOrNamespaceDescriptors().get(name);
|
||||
if (originalDescriptor != null) {
|
||||
|
||||
+17
-6
@@ -3,10 +3,7 @@ package org.jetbrains.jet.lang.resolve.scopes;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -173,12 +170,26 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
|
||||
|
||||
|
||||
@Override
|
||||
public void importNamespaceAlias(String aliasName, NamespaceDescriptor namespaceDescriptor) {
|
||||
public void importNamespaceAlias(@NotNull String aliasName, @NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
getCurrentIndividualImportScope().addNamespaceAlias(aliasName, namespaceDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void importFunctionAlias(@NotNull String aliasName, @NotNull FunctionDescriptor functionDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
getCurrentIndividualImportScope().addFunctionAlias(aliasName, functionDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importVariableAlias(@NotNull String aliasName, @NotNull VariableDescriptor variableDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
getCurrentIndividualImportScope().addVariableAlias(aliasName, variableDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration();
|
||||
|
||||
@@ -161,6 +161,20 @@ public class WriteThroughScope extends WritableScopeWithImports {
|
||||
writableWorker.addNamespaceAlias(name, namespaceDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addVariableAlias(@NotNull String name, @NotNull VariableDescriptor variableDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
writableWorker.addVariableAlias(name, variableDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFunctionAlias(@NotNull String name, @NotNull FunctionDescriptor functionDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
writableWorker.addFunctionAlias(name, functionDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
checkMayWrite();
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//FILE:a.kt
|
||||
namespace a
|
||||
|
||||
import b.B //class
|
||||
import b.foo //function
|
||||
import b.ext //extension function
|
||||
import b.value //property
|
||||
import b.C.bar //function from class object
|
||||
import b.C.cValue //property from class object
|
||||
|
||||
fun test(arg: B) {
|
||||
foo(value)
|
||||
arg.ext()
|
||||
}
|
||||
|
||||
//FILE:b.kt
|
||||
namespace b
|
||||
|
||||
class B() {}
|
||||
|
||||
fun foo(<!UNUSED_PARAMETER!>i<!>: Int) {}
|
||||
|
||||
fun B.ext() {}
|
||||
|
||||
val value = 0
|
||||
|
||||
class C() {
|
||||
class object {
|
||||
fun bar() {}
|
||||
val cValue = 1
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.jetbrains.jet.checkers;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetLiteFixture;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
@@ -79,7 +80,7 @@ public class CheckerTestUtilTest extends JetLiteFixture {
|
||||
this.expected = expectedMessages;
|
||||
}
|
||||
|
||||
public void test(PsiFile psiFile) {
|
||||
public void test(final @NotNull PsiFile psiFile) {
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeOneNamespaceWithJavaIntegration(
|
||||
((JetFile) psiFile).getRootNamespace(),
|
||||
JetControlFlowDataTraceFactory.EMPTY);
|
||||
@@ -88,6 +89,9 @@ public class CheckerTestUtilTest extends JetLiteFixture {
|
||||
|
||||
List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList();
|
||||
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
||||
for (CheckerTestUtil.DiagnosedRange diagnosedRange : diagnosedRanges) {
|
||||
diagnosedRange.setFile(psiFile);
|
||||
}
|
||||
|
||||
List<Diagnostic> diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile);
|
||||
Collections.sort(diagnostics, CheckerTestUtil.DIAGNOSTIC_COMPARATOR);
|
||||
@@ -98,6 +102,12 @@ public class CheckerTestUtilTest extends JetLiteFixture {
|
||||
final List<String> actualMessages = Lists.newArrayList();
|
||||
|
||||
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, diagnostics, new CheckerTestUtil.DiagnosticDiffCallbacks() {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiFile getFile() {
|
||||
return psiFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void missingDiagnostic(String type, int expectedStart, int expectedEnd) {
|
||||
String message = "Missing " + type + " at " + expectedStart + " to " + expectedEnd;
|
||||
|
||||
@@ -52,10 +52,19 @@ public class JetDiagnosticsTest extends JetLiteFixture {
|
||||
expectedText = textWithMarkers;
|
||||
clearText = CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
||||
jetFile = createCheckAndReturnPsiFile(fileName, clearText);
|
||||
for (CheckerTestUtil.DiagnosedRange diagnosedRange : diagnosedRanges) {
|
||||
diagnosedRange.setFile(jetFile);
|
||||
}
|
||||
}
|
||||
|
||||
public void getActualText(BindingContext bindingContext, StringBuilder actualText) {
|
||||
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, jetFile), new CheckerTestUtil.DiagnosticDiffCallbacks() {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiFile getFile() {
|
||||
return jetFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void missingDiagnostic(String type, int expectedStart, int expectedEnd) {
|
||||
String message = "Missing " + type + DiagnosticUtils.atLocation(jetFile, new TextRange(expectedStart, expectedEnd));
|
||||
@@ -95,7 +104,7 @@ public class JetDiagnosticsTest extends JetLiteFixture {
|
||||
bindingContext = AnalyzerFacade.analyzeNamespacesWithJavaIntegration(getProject(), namespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
|
||||
}
|
||||
else {
|
||||
bindingContext = AnalyzingUtils.analyzeNamespaces(getProject(), Configuration.EMPTY, namespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY, JetSemanticServices.createSemanticServices(getProject()));
|
||||
bindingContext = AnalyzingUtils.analyzeNamespaces(getProject(), Configuration.EMPTY, namespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
|
||||
}
|
||||
|
||||
StringBuilder actualText = new StringBuilder();
|
||||
|
||||
@@ -95,7 +95,7 @@ public class DebugInfoAnnotator implements Annotator {
|
||||
target = labelTarget.getText();
|
||||
}
|
||||
else {
|
||||
Collection<? extends ResolvedCallImpl<? extends DeclarationDescriptor>> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
|
||||
if (declarationDescriptors != null) {
|
||||
target = "[" + declarationDescriptors.size() + " descriptors]";
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public abstract class JetPsiReference implements PsiPolyVariantReference {
|
||||
if (psiElement != null) {
|
||||
return psiElement;
|
||||
}
|
||||
Collection<? extends ResolvedCallImpl<? extends DeclarationDescriptor>> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
if (declarationDescriptors != null) return null;
|
||||
return file;
|
||||
}
|
||||
@@ -89,12 +89,12 @@ public abstract class JetPsiReference implements PsiPolyVariantReference {
|
||||
protected ResolveResult[] doMultiResolve() {
|
||||
JetFile file = (JetFile) getElement().getContainingFile();
|
||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
||||
Collection<? extends ResolvedCallImpl<? extends DeclarationDescriptor>> resolvedCalls = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
if (resolvedCalls == null) return ResolveResult.EMPTY_ARRAY;
|
||||
ResolveResult[] results = new ResolveResult[resolvedCalls.size()];
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
if (declarationDescriptors == null) return ResolveResult.EMPTY_ARRAY;
|
||||
ResolveResult[] results = new ResolveResult[declarationDescriptors.size()];
|
||||
int i = 0;
|
||||
for (ResolvedCallImpl<? extends DeclarationDescriptor> resolvedCall : resolvedCalls) {
|
||||
PsiElement element = bindingContext.get(DESCRIPTOR_TO_DECLARATION, resolvedCall.getResultingDescriptor());
|
||||
for (DeclarationDescriptor descriptor : declarationDescriptors) {
|
||||
PsiElement element = bindingContext.get(DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||
if (element != null) {
|
||||
results[i] = new PsiElementResolveResult(element, true);
|
||||
i++;
|
||||
|
||||
Reference in New Issue
Block a user