Merge remote branch 'origin/master'

This commit is contained in:
Alex Tkachman
2011-12-30 14:57:49 +02:00
11 changed files with 304 additions and 100 deletions
@@ -173,6 +173,12 @@ public class CompileEnvironment {
return; return;
} }
try {
System.out.println("module file text: " + FileUtil.loadFile(new File(moduleFile)));
} catch (Exception e) {
e.printStackTrace();
}
final String directory = new File(moduleFile).getParent(); final String directory = new File(moduleFile).getParent();
for (IModuleBuilder moduleBuilder : moduleSetBuilder.getModules()) { for (IModuleBuilder moduleBuilder : moduleSetBuilder.getModules()) {
ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory); ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory);
@@ -83,10 +83,10 @@ public class JavaPackageScope extends JetScopeImpl {
PsiField field = psiClassForPackage.findFieldByName(name, true); PsiField field = psiClassForPackage.findFieldByName(name, true);
if (field == null) { if (field == null) {
return null; return Collections.emptySet();
} }
if (!field.hasModifierProperty(PsiModifier.STATIC)) { if (!field.hasModifierProperty(PsiModifier.STATIC)) {
return null; return Collections.emptySet();
} }
// TODO: cache // TODO: cache
@@ -0,0 +1,151 @@
package org.jetbrains.jet.lang.descriptors;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* @author svtk
*/
public class ClassDescriptorBoundToReceiver implements ClassDescriptor {
private ClassDescriptor classDescriptor;
private DeclarationDescriptor receiver;
public ClassDescriptorBoundToReceiver(ClassDescriptor classDescriptor, DeclarationDescriptor receiver) {
this.classDescriptor = classDescriptor;
this.receiver = receiver;
}
public ClassDescriptor getClassDescriptor() {
return classDescriptor;
}
public DeclarationDescriptor getReceiver() {
return receiver;
}
@NotNull
@Override
public JetScope getMemberScope(List<TypeProjection> typeArguments) {
return classDescriptor.getMemberScope(typeArguments);
}
@NotNull
@Override
public JetType getSuperclassType() {
return classDescriptor.getSuperclassType();
}
@NotNull
@Override
public Set<ConstructorDescriptor> getConstructors() {
return (Set)Sets.newHashSet(ImportsResolver.ImportResolver.addBoundToReceiver((Collection)classDescriptor.getConstructors(), receiver));
}
@Override
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
return classDescriptor.getUnsubstitutedPrimaryConstructor();
}
@Override
public boolean hasConstructors() {
return classDescriptor.hasConstructors();
}
@NotNull
@Override
public DeclarationDescriptor getOriginal() {
return classDescriptor.getOriginal();
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return classDescriptor.getContainingDeclaration();
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
return classDescriptor.getTypeConstructor();
}
@NotNull
@Override
public JetType getDefaultType() {
return classDescriptor.getDefaultType();
}
@NotNull
@Override
public ClassDescriptor substitute(TypeSubstitutor substitutor) {
return classDescriptor.substitute(substitutor);
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return classDescriptor.accept(visitor, data);
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
classDescriptor.acceptVoid(visitor);
}
@Override
public JetType getClassObjectType() {
return classDescriptor.getClassObjectType();
}
@Override
public boolean isClassObjectAValue() {
return classDescriptor.isClassObjectAValue();
}
@NotNull
@Override
public ClassKind getKind() {
return classDescriptor.getKind();
}
@NotNull
@Override
public Modality getModality() {
return classDescriptor.getModality();
}
@NotNull
@Override
public Visibility getVisibility() {
return classDescriptor.getVisibility();
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
return ReceiverDescriptor.NO_RECEIVER;
}
@Override
public List<AnnotationDescriptor> getAnnotations() {
return classDescriptor.getAnnotations();
}
@NotNull
@Override
public String getName() {
return classDescriptor.getName();
}
}
@@ -83,8 +83,7 @@ public interface Errors {
SimpleDiagnosticFactory LABEL_NAME_CLASH = SimpleDiagnosticFactory.create(WARNING, "There is more than one label with such a name in this scope"); SimpleDiagnosticFactory LABEL_NAME_CLASH = SimpleDiagnosticFactory.create(WARNING, "There is more than one label with such a name in this scope");
SimpleDiagnosticFactory EXPRESSION_EXPECTED_NAMESPACE_FOUND = SimpleDiagnosticFactory.create(ERROR, "Expression expected, but a namespace name found"); SimpleDiagnosticFactory EXPRESSION_EXPECTED_NAMESPACE_FOUND = SimpleDiagnosticFactory.create(ERROR, "Expression expected, but a namespace name found");
SimpleDiagnosticFactory CANNOT_IMPORT_OBJECT_MEMBERS = SimpleDiagnosticFactory.create(ERROR, "Cannot import members of object separately, use full paths or try to move members to namespace level"); ParameterizedDiagnosticFactory1<DeclarationDescriptor> CANNOT_IMPORT_FROM_ELEMENT = ParameterizedDiagnosticFactory1.create(ERROR, "Cannot import from ''{0}''", NAME);
SimpleDiagnosticFactory CANNOT_IMPORT_VARIABLE_MEMBERS = SimpleDiagnosticFactory.create(ERROR, "Cannot import members of variable separately, use full paths");
SimpleDiagnosticFactory CANNOT_INFER_PARAMETER_TYPE = SimpleDiagnosticFactory.create(ERROR, "Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) => ...} notation"); SimpleDiagnosticFactory CANNOT_INFER_PARAMETER_TYPE = SimpleDiagnosticFactory.create(ERROR, "Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) => ...} notation");
@@ -1,13 +1,17 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Collections2; import com.google.common.collect.Collections2;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.psi.JetObjectDeclarationName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
@@ -211,4 +215,29 @@ public class DescriptorUtils {
} }
return null; return null;
} }
@NotNull
public static Function<DeclarationDescriptor, DeclarationDescriptor> getAddBoundToReceiverFunction(@NotNull final DeclarationDescriptor receiver) {
return new Function<DeclarationDescriptor, DeclarationDescriptor>() {
@Override
public DeclarationDescriptor apply(@Nullable DeclarationDescriptor descriptor) {
if (descriptor instanceof FunctionDescriptor) {
return new FunctionDescriptorBoundToReceiver((FunctionDescriptor) descriptor, receiver);
}
if (descriptor instanceof VariableDescriptor) {
return new VariableDescriptorBoundToReceiver((VariableDescriptor) descriptor, receiver);
}
if (descriptor instanceof ClassDescriptor) {
return new ClassDescriptorBoundToReceiver((ClassDescriptor) descriptor, receiver);
}
return descriptor;
}
};
}
//todo
public static boolean isObjectDescriptor(@NotNull VariableDescriptor descriptor, BindingTrace bindingTrace) {
PsiElement element = bindingTrace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
return element instanceof JetObjectDeclarationName;
}
} }
@@ -1,6 +1,5 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Function;
import com.google.common.collect.Collections2; import com.google.common.collect.Collections2;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -55,13 +54,10 @@ public class ImportsResolver {
public static class ImportResolver { public static class ImportResolver {
private final BindingTrace trace; private final BindingTrace trace;
private final boolean firstPhase; private final boolean firstPhase;
// flag is used not to invoke code that resolves members from objects and variables; functionality is under discuss so far, see KT-876
private final boolean importMembersFromObjectsAndVars;
public ImportResolver(BindingTrace trace, boolean firstPhase) { public ImportResolver(BindingTrace trace, boolean firstPhase) {
this.trace = trace; this.trace = trace;
this.firstPhase = firstPhase; this.firstPhase = firstPhase;
this.importMembersFromObjectsAndVars = false;
} }
public void processImportReference(JetImportDirective importDirective, WritableScope namespaceScope, JetScope outerScope) { public void processImportReference(JetImportDirective importDirective, WritableScope namespaceScope, JetScope outerScope) {
@@ -82,27 +78,21 @@ public class ImportsResolver {
} }
JetSimpleNameExpression referenceExpression = getLastReference(importedReference); JetSimpleNameExpression referenceExpression = getLastReference(importedReference);
if (importDirective.isAllUnder()) { if (importDirective.isAllUnder()) {
if (referenceExpression == null || !canImportMembersFrom(descriptors, referenceExpression)) return;
for (DeclarationDescriptor descriptor : descriptors) { for (DeclarationDescriptor descriptor : descriptors) {
if (firstPhase) { if (firstPhase) {
if (descriptor instanceof NamespaceDescriptor) { if (descriptor instanceof NamespaceDescriptor) {
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope()); namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
} }
continue;
} }
else if (descriptor instanceof VariableDescriptor) { if (descriptor instanceof VariableDescriptor) {
if (!importMembersFromObjectsAndVars) {
trace.report(CANNOT_IMPORT_OBJECT_MEMBERS.on(referenceExpression != null ? referenceExpression : importedReference));
continue;
}
JetType type = ((VariableDescriptor) descriptor).getOutType(); JetType type = ((VariableDescriptor) descriptor).getOutType();
if (type != null) { if (type != null) {
namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, type.getMemberScope())); namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, type.getMemberScope()));
} }
} }
else if (descriptor instanceof ClassDescriptor) { else if (descriptor instanceof ClassDescriptor) {
if (!importMembersFromObjectsAndVars) {
trace.report(CANNOT_IMPORT_VARIABLE_MEMBERS.on(referenceExpression != null ? referenceExpression : importedReference));
continue;
}
namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, ((ClassDescriptor) descriptor).getDefaultType().getMemberScope())); namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, ((ClassDescriptor) descriptor).getDefaultType().getMemberScope()));
} }
} }
@@ -120,20 +110,17 @@ public class ImportsResolver {
} }
} }
private void importDeclarationAlias(WritableScope namespaceScope, String aliasName, DeclarationDescriptor descriptor) { private static void importDeclarationAlias(WritableScope namespaceScope, String aliasName, DeclarationDescriptor descriptor) {
if (firstPhase) { if (descriptor instanceof ClassifierDescriptor) {
if (descriptor instanceof ClassifierDescriptor) { namespaceScope.importClassifierAlias(aliasName, (ClassifierDescriptor) descriptor);
namespaceScope.importClassifierAlias(aliasName, (ClassifierDescriptor) descriptor);
}
if (descriptor instanceof NamespaceDescriptor) {
namespaceScope.importNamespaceAlias(aliasName, (NamespaceDescriptor) descriptor);
}
return;
} }
if (descriptor instanceof FunctionDescriptor) { else if (descriptor instanceof NamespaceDescriptor) {
namespaceScope.importNamespaceAlias(aliasName, (NamespaceDescriptor) descriptor);
}
else if (descriptor instanceof FunctionDescriptor) {
namespaceScope.importFunctionAlias(aliasName, (FunctionDescriptor) descriptor); namespaceScope.importFunctionAlias(aliasName, (FunctionDescriptor) descriptor);
} }
if (descriptor instanceof VariableDescriptor) { else if (descriptor instanceof VariableDescriptor) {
namespaceScope.importVariableAlias(aliasName, (VariableDescriptor) descriptor); namespaceScope.importVariableAlias(aliasName, (VariableDescriptor) descriptor);
} }
} }
@@ -163,15 +150,16 @@ public class ImportsResolver {
JetExpression selectorExpression = importedReference.getSelectorExpression(); JetExpression selectorExpression = importedReference.getSelectorExpression();
assert selectorExpression instanceof JetSimpleNameExpression; assert selectorExpression instanceof JetSimpleNameExpression;
JetSimpleNameExpression selector = (JetSimpleNameExpression) selectorExpression; JetSimpleNameExpression selector = (JetSimpleNameExpression) selectorExpression;
JetSimpleNameExpression lastReference = getLastReference(receiverExpression);
if (lastReference == null || !canImportMembersFrom(declarationDescriptors, lastReference)) {
return Collections.emptyList();
}
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) { for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
if (declarationDescriptor instanceof NamespaceDescriptor) { if (declarationDescriptor instanceof NamespaceDescriptor) {
return lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope()); return lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope());
} }
if (declarationDescriptor instanceof ClassDescriptor) { if (declarationDescriptor instanceof ClassDescriptor) {
JetSimpleNameExpression classReference = getLastReference(receiverExpression); return lookupObjectMembers(selector, lastReference, (ClassDescriptor) declarationDescriptor);
if (classReference != null) {
return lookupObjectMembers(selector, classReference, (ClassDescriptor) declarationDescriptor);
}
} }
if (declarationDescriptor instanceof VariableDescriptor) { if (declarationDescriptor instanceof VariableDescriptor) {
return lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor); return lookupVariableMembers(selector, (VariableDescriptor) declarationDescriptor);
@@ -180,50 +168,64 @@ public class ImportsResolver {
return Collections.emptyList(); return Collections.emptyList();
} }
private boolean canImportMembersFrom(@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull JetSimpleNameExpression reference) {
if (firstPhase) return true;
if (descriptors.size() == 1) {
return canImportMembersFrom(descriptors.iterator().next(), reference, trace);
}
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
boolean canImport = false;
for (DeclarationDescriptor descriptor : descriptors) {
canImport |= canImportMembersFrom(descriptor, reference, temporaryTrace);
}
if (!canImport) {
temporaryTrace.commit();
}
return canImport;
}
private boolean canImportMembersFrom(@NotNull DeclarationDescriptor descriptor, @NotNull JetSimpleNameExpression reference, @NotNull BindingTrace trace) {
assert !firstPhase;
if (descriptor instanceof NamespaceDescriptor) {
return true;
}
if (descriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
JetType classObjectType = classDescriptor.getClassObjectType();
if (classObjectType == null) {
trace.report(NO_CLASS_OBJECT.on(reference, classDescriptor));
return false;
}
return true;
}
if (descriptor instanceof VariableDescriptor && DescriptorUtils.isObjectDescriptor((VariableDescriptor) descriptor, trace)) {
return true;
}
trace.report(CANNOT_IMPORT_FROM_ELEMENT.on(reference, descriptor));
return false;
}
@NotNull @NotNull
private Collection<DeclarationDescriptor> lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull JetSimpleNameExpression classReference, @NotNull ClassDescriptor classDescriptor) { private Collection<DeclarationDescriptor> lookupObjectMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull JetSimpleNameExpression classReference, @NotNull ClassDescriptor classDescriptor) {
if (firstPhase) return Collections.emptyList(); if (firstPhase) return Collections.emptyList();
JetType classObjectType = classDescriptor.getClassObjectType(); JetType classObjectType = classDescriptor.getClassObjectType();
if (classObjectType == null || !classDescriptor.isClassObjectAValue()) { assert classObjectType != null;
trace.report(NO_CLASS_OBJECT.on(classReference, classDescriptor));
return Collections.emptyList();
}
Collection<DeclarationDescriptor> members = lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope()); Collection<DeclarationDescriptor> members = lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope());
if (!importMembersFromObjectsAndVars) {
trace.report(CANNOT_IMPORT_OBJECT_MEMBERS.on(memberReference));
return Collections.emptyList();
}
return addBoundToReceiver(members, classDescriptor); return addBoundToReceiver(members, classDescriptor);
} }
@NotNull
private Collection<DeclarationDescriptor> lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) { private Collection<DeclarationDescriptor> lookupVariableMembers(@NotNull JetSimpleNameExpression memberReference, @NotNull VariableDescriptor variableDescriptor) {
if (firstPhase) return Collections.emptyList(); if (firstPhase) return Collections.emptyList();
JetType variableType = variableDescriptor.getReturnType(); JetType variableType = variableDescriptor.getReturnType();
if (variableType == null) return Collections.emptyList(); if (variableType == null) return Collections.emptyList();
Collection<DeclarationDescriptor> members = lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope()); Collection<DeclarationDescriptor> members = lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope());
if (!importMembersFromObjectsAndVars) {
trace.report(CANNOT_IMPORT_VARIABLE_MEMBERS.on(memberReference));
return Collections.emptyList();
}
return addBoundToReceiver(members, variableDescriptor); return addBoundToReceiver(members, variableDescriptor);
} }
@NotNull @NotNull
private static Collection<DeclarationDescriptor> addBoundToReceiver(@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull final DeclarationDescriptor implicitReceiver) { public static Collection<DeclarationDescriptor> addBoundToReceiver(@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull final DeclarationDescriptor receiver) {
return Collections2.transform(descriptors, new Function<DeclarationDescriptor, DeclarationDescriptor>() { return Collections2.transform(descriptors, DescriptorUtils.getAddBoundToReceiverFunction(receiver));
@Override
public DeclarationDescriptor apply(@Nullable DeclarationDescriptor descriptor) {
if (descriptor instanceof FunctionDescriptor) {
return new FunctionDescriptorBoundToReceiver((FunctionDescriptor) descriptor, implicitReceiver);
}
if (descriptor instanceof VariableDescriptor) {
return new VariableDescriptorBoundToReceiver((VariableDescriptor) descriptor, implicitReceiver);
}
return descriptor;
}
});
} }
@NotNull @NotNull
@@ -101,9 +101,8 @@ public class TypeHierarchyResolver {
visitClassOrObject( visitClassOrObject(
klass, klass,
(Map) context.getClasses(), (Map) context.getClasses(),
owner, mutableClassDescriptor
outerScope, );
mutableClassDescriptor);
owner.addClassifierDescriptor(mutableClassDescriptor); owner.addClassifierDescriptor(mutableClassDescriptor);
} }
@@ -126,9 +125,8 @@ public class TypeHierarchyResolver {
visitClassOrObject( visitClassOrObject(
enumEntry, enumEntry,
(Map) context.getClasses(), (Map) context.getClasses(),
classObjectDescriptor, mutableClassDescriptor
outerScope, );
mutableClassDescriptor);
classObjectDescriptor.addClassifierDescriptor(mutableClassDescriptor); classObjectDescriptor.addClassifierDescriptor(mutableClassDescriptor);
} }
} }
@@ -140,7 +138,7 @@ public class TypeHierarchyResolver {
return ClassObjectStatus.NOT_ALLOWED; return ClassObjectStatus.NOT_ALLOWED;
} }
}; };
visitClassOrObject(declaration, (Map) context.getObjects(), owner, scope, mutableClassDescriptor); visitClassOrObject(declaration, (Map) context.getObjects(), mutableClassDescriptor);
createPrimaryConstructorForObject((JetDeclaration) declaration, mutableClassDescriptor); createPrimaryConstructorForObject((JetDeclaration) declaration, mutableClassDescriptor);
context.getTrace().record(BindingContext.CLASS, declaration, mutableClassDescriptor); context.getTrace().record(BindingContext.CLASS, declaration, mutableClassDescriptor);
return mutableClassDescriptor; return mutableClassDescriptor;
@@ -157,19 +155,18 @@ public class TypeHierarchyResolver {
} }
} }
private void visitClassOrObject(@NotNull JetClassOrObject declaration, Map<JetClassOrObject, MutableClassDescriptor> map, NamespaceLike owner, JetScope outerScope, MutableClassDescriptor mutableClassDescriptor) { private void visitClassOrObject(@NotNull JetClassOrObject declaration, Map<JetClassOrObject, MutableClassDescriptor> map, MutableClassDescriptor mutableClassDescriptor) {
mutableClassDescriptor.setName(JetPsiUtil.safeName(declaration.getName())); mutableClassDescriptor.setName(JetPsiUtil.safeName(declaration.getName()));
map.put(declaration, mutableClassDescriptor); map.put(declaration, mutableClassDescriptor);
// declaringScopes.put((JetDeclaration) declaration, outerScope);
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution(); JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
collectNamespacesAndClassifiers(classScope, outerScopeForStatic, mutableClassDescriptor, declaration.getDeclarations()); JetScope scopeForStatic = declaration instanceof JetObjectDeclaration ? classScope : outerScopeForStatic;
collectNamespacesAndClassifiers(classScope, scopeForStatic, mutableClassDescriptor, declaration.getDeclarations());
} }
@Override @Override
public void visitTypedef(JetTypedef typedef) { public void visitTypedef(JetTypedef typedef) {
// context.getTrace().getErrorHandler().genericError(typedef.getNode(), "Unsupported [TopDownAnalyzer]");
context.getTrace().report(UNSUPPORTED.on(typedef, "TypeHierarchyResolver")); context.getTrace().report(UNSUPPORTED.on(typedef, "TypeHierarchyResolver"));
} }
@@ -180,11 +177,9 @@ public class TypeHierarchyResolver {
NamespaceLike.ClassObjectStatus status = owner.setClassObjectDescriptor(createClassDescriptorForObject(objectDeclaration, owner, outerScopeForStatic)); NamespaceLike.ClassObjectStatus status = owner.setClassObjectDescriptor(createClassDescriptorForObject(objectDeclaration, owner, outerScopeForStatic));
switch (status) { switch (status) {
case DUPLICATE: case DUPLICATE:
// context.getTrace().getErrorHandler().genericError(classObject.getNode(), "Only one class object is allowed per class");
context.getTrace().report(MANY_CLASS_OBJECTS.on(classObject)); context.getTrace().report(MANY_CLASS_OBJECTS.on(classObject));
break; break;
case NOT_ALLOWED: case NOT_ALLOWED:
// context.getTrace().getErrorHandler().genericError(classObject.getNode(), "A class object is not allowed here");
context.getTrace().report(CLASS_OBJECT_NOT_ALLOWED.on(classObject)); context.getTrace().report(CLASS_OBJECT_NOT_ALLOWED.on(classObject));
break; break;
} }
@@ -366,7 +361,6 @@ public class TypeHierarchyResolver {
} }
} }
if (node != null) { if (node != null) {
// context.getTrace().getErrorHandler().genericError(node, "There's a cycle in the inheritance hierarchy for this type");
context.getTrace().report(CYCLIC_INHERITANCE_HIERARCHY.on(node)); context.getTrace().report(CYCLIC_INHERITANCE_HIERARCHY.on(node));
} }
} }
@@ -7,6 +7,7 @@ import com.google.common.collect.SetMultimap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.util.CommonSuppliers; import org.jetbrains.jet.util.CommonSuppliers;
@@ -22,6 +23,7 @@ public class ScopeBoundToReceiver implements JetScope {
private SetMultimap<String, VariableDescriptor> propertiesMap; private SetMultimap<String, VariableDescriptor> propertiesMap;
private SetMultimap<String, FunctionDescriptor> functionsMap; private SetMultimap<String, FunctionDescriptor> functionsMap;
private Map<DeclarationDescriptor, DeclarationDescriptor> descriptorsBoundToReceiver; private Map<DeclarationDescriptor, DeclarationDescriptor> descriptorsBoundToReceiver;
private Function<DeclarationDescriptor, DeclarationDescriptor> addBoundToReceiverFunction;
public static ScopeBoundToReceiver create(DeclarationDescriptor implicitReceiver, JetScope memberScope) { public static ScopeBoundToReceiver create(DeclarationDescriptor implicitReceiver, JetScope memberScope) {
return new ScopeBoundToReceiver(implicitReceiver, memberScope); return new ScopeBoundToReceiver(implicitReceiver, memberScope);
@@ -36,6 +38,13 @@ public class ScopeBoundToReceiver implements JetScope {
return receiver; return receiver;
} }
public Function<DeclarationDescriptor, DeclarationDescriptor> getAddBoundToReceiverFunction() {
if (addBoundToReceiverFunction == null) {
addBoundToReceiverFunction = DescriptorUtils.getAddBoundToReceiverFunction(receiver);
}
return addBoundToReceiverFunction;
}
private SetMultimap<String, VariableDescriptor> getPropertiesMap() { private SetMultimap<String, VariableDescriptor> getPropertiesMap() {
if (propertiesMap == null) { if (propertiesMap == null) {
propertiesMap = CommonSuppliers.newLinkedHashSetHashSetMultimap(); propertiesMap = CommonSuppliers.newLinkedHashSetHashSetMultimap();
@@ -60,7 +69,7 @@ public class ScopeBoundToReceiver implements JetScope {
@Nullable @Nullable
@Override @Override
public ClassifierDescriptor getClassifier(@NotNull String name) { public ClassifierDescriptor getClassifier(@NotNull String name) {
return scope.getClassifier(name); return getMemberBoundToReceiver(scope.getClassifier(name));
} }
@Nullable @Nullable
@@ -75,12 +84,7 @@ public class ScopeBoundToReceiver implements JetScope {
if (getPropertiesMap().containsKey(name)) { if (getPropertiesMap().containsKey(name)) {
return getPropertiesMap().get(name); return getPropertiesMap().get(name);
} }
return getMembersBoundToReceiver(name, getPropertiesMap(), scope.getProperties(name), new Function<VariableDescriptor, VariableDescriptor>() { return getMembersBoundToReceiver(name, getPropertiesMap(), scope.getProperties(name));
@Override
public VariableDescriptor apply(VariableDescriptor property) {
return new VariableDescriptorBoundToReceiver(property, receiver);
}
});
} }
@Nullable @Nullable
@@ -89,25 +93,25 @@ public class ScopeBoundToReceiver implements JetScope {
return scope.getLocalVariable(name); return scope.getLocalVariable(name);
} }
private <D extends DeclarationDescriptor> Set<D> getMembersBoundToReceiver(String name, SetMultimap<String, D> cache, Set<D> oldMembers, Function<D, D> transformation) { private <D extends DeclarationDescriptor> Set<D> getMembersBoundToReceiver(String name, SetMultimap<String, D> cache, Set<D> oldMembers) {
for (D oldMember : oldMembers) { for (D oldMember : oldMembers) {
cache.put(name, transformation.apply(oldMember)); cache.put(name, getMemberBoundToReceiver(oldMember));
} }
return cache.get(name); return cache.get(name);
} }
private <D extends DeclarationDescriptor> D getMemberBoundToReceiver(D oldMember) {
return (D)getAddBoundToReceiverFunction().apply(oldMember);
}
@NotNull @NotNull
@Override @Override
public Set<FunctionDescriptor> getFunctions(@NotNull String name) { public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
if (getFunctionsMap().containsKey(name)) { if (getFunctionsMap().containsKey(name)) {
return getFunctionsMap().get(name); return getFunctionsMap().get(name);
} }
return getMembersBoundToReceiver(name, getFunctionsMap(), scope.getFunctions(name), new Function<FunctionDescriptor, FunctionDescriptor>() { return getMembersBoundToReceiver(name, getFunctionsMap(), scope.getFunctions(name));
@Override
public FunctionDescriptor apply(FunctionDescriptor function) {
return new FunctionDescriptorBoundToReceiver(function, receiver);
}
});
} }
@NotNull @NotNull
@@ -5,23 +5,29 @@ import b.B //class
import b.foo //function import b.foo //function
import b.ext //extension function import b.ext //extension function
import b.value //property import b.value //property
import b.C.<!CANNOT_IMPORT_OBJECT_MEMBERS!>bar<!> //function from class object import b.C.bar //function from class object
import b.C.<!CANNOT_IMPORT_OBJECT_MEMBERS!>cValue<!> //property from class object import b.C.cValue //property from class object
import b.constant.<!CANNOT_IMPORT_VARIABLE_MEMBERS!>fff<!> //function from val import b.<!CANNOT_IMPORT_FROM_ELEMENT!>constant<!>.fff //function from val
import b.constant.<!CANNOT_IMPORT_VARIABLE_MEMBERS!>dValue<!> //property from val import b.<!CANNOT_IMPORT_FROM_ELEMENT!>constant<!>.dValue //property from val
import b.E.<!CANNOT_IMPORT_OBJECT_MEMBERS!>f<!> //val from class object import b.constant
import b.E.f //val from class object
import <!UNRESOLVED_REFERENCE!>smth<!>.illegal import <!UNRESOLVED_REFERENCE!>smth<!>.illegal
import b.C.<!UNRESOLVED_REFERENCE!>smth<!>.illegal
import <!CANNOT_IMPORT_FROM_ELEMENT!>bar<!>.smth
import <!CANNOT_IMPORT_FROM_ELEMENT!>bar<!>.*
fun test(arg: B) { fun test(arg: B) {
foo(value) foo(value)
arg.ext() arg.ext()
<!UNRESOLVED_REFERENCE!>bar<!>() bar()
foo(<!UNRESOLVED_REFERENCE!>cValue<!>) foo(cValue)
<!UNRESOLVED_REFERENCE!>fff<!>(<!UNRESOLVED_REFERENCE!>dValue<!>) <!UNRESOLVED_REFERENCE!>fff<!>(<!UNRESOLVED_REFERENCE!>dValue<!>)
<!UNRESOLVED_REFERENCE!>f<!>.f() constant.fff(constant.dValue)
f.f()
} }
// FILE:b.kt // FILE:b.kt
@@ -59,17 +65,19 @@ class F() {
fun f() {} fun f() {}
} }
fun bar() {}
//FILE:c.kt //FILE:c.kt
package c package c
import <!CANNOT_IMPORT_OBJECT_MEMBERS!>C<!>.* import C.*
object C { object C {
fun f() { fun f() {
} }
val i = 3 val i = 348
} }
fun foo() { fun foo() {
if (<!UNRESOLVED_REFERENCE!>i<!> == 3) <!UNRESOLVED_REFERENCE!>f<!>() if (i == 3) f()
} }
@@ -0,0 +1,11 @@
// KT-587 Unresolved reference
class Main {
class object {
class States() {
class object {
public val N: States = States() // : States unresolved
}
}
}
}