Merge remote-tracking branch 'origin/master'

This commit is contained in:
James Strachan
2011-12-20 17:28:53 +00:00
19 changed files with 346 additions and 110 deletions
@@ -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) {
@@ -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++;