Intermediate major refactorings for lazy resolve

This commit is contained in:
Nikolay Krasko
2012-05-11 18:58:54 +04:00
parent 5ac866ba3c
commit 2dba348ecb
17 changed files with 603 additions and 373 deletions
@@ -21,75 +21,15 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiAnnotation; import com.intellij.psi.*;
import com.intellij.psi.PsiAnnotationMemberValue;
import com.intellij.psi.PsiAnnotationMethod;
import com.intellij.psi.PsiAnnotationParameterList;
import com.intellij.psi.PsiArrayType;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiEllipsisType;
import com.intellij.psi.PsiLiteralExpression;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.PsiPrimitiveType;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeParameter;
import com.intellij.psi.PsiTypeParameterListOwner;
import jet.typeinfo.TypeInfoVariance; import jet.typeinfo.TypeInfoVariance;
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.CallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorWithVisibility;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.Modality;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.MutableClassDescriptorLite;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorParent;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.descriptors.Visibilities;
import org.jetbrains.jet.lang.descriptors.Visibility;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.NamespaceFactory;
import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.constants.ByteValue;
import org.jetbrains.jet.lang.resolve.constants.CharValue;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.DoubleValue;
import org.jetbrains.jet.lang.resolve.constants.FloatValue;
import org.jetbrains.jet.lang.resolve.constants.IntValue;
import org.jetbrains.jet.lang.resolve.constants.LongValue;
import org.jetbrains.jet.lang.resolve.constants.NullValue;
import org.jetbrains.jet.lang.resolve.constants.ShortValue;
import org.jetbrains.jet.lang.resolve.constants.StringValue; import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
@@ -101,14 +41,7 @@ import org.jetbrains.jet.rt.signature.JetSignatureReader;
import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* @author abreslav * @author abreslav
@@ -541,7 +474,7 @@ public class JavaDescriptorResolver {
MutableClassDescriptorLite classObject = createClassObjectDescriptor(classData.classDescriptor, psiClass); MutableClassDescriptorLite classObject = createClassObjectDescriptor(classData.classDescriptor, psiClass);
if (classObject != null) { if (classObject != null) {
classData.classDescriptor.setClassObjectDescriptor(classObject); classData.classDescriptor.getBuilder().setClassObjectDescriptor(classObject);
} }
trace.record(BindingContext.CLASS, psiClass, classData.classDescriptor); trace.record(BindingContext.CLASS, psiClass, classData.classDescriptor);
@@ -605,7 +538,8 @@ public class JavaDescriptorResolver {
checkPsiClassIsNotJet(psiClass); checkPsiClassIsNotJet(psiClass);
FqName fqName = new FqName(classObjectPsiClass.getQualifiedName()); FqName fqName = new FqName(classObjectPsiClass.getQualifiedName());
ResolverBinaryClassData classData = new ResolverBinaryClassData(classObjectPsiClass, fqName, new MutableClassDescriptorLite(containing, ClassKind.OBJECT)); ResolverBinaryClassData classData = new ResolverBinaryClassData(classObjectPsiClass, fqName,
new MutableClassDescriptorLite(containing, ClassKind.OBJECT));
classDescriptorCache.put(fqName, classData); classDescriptorCache.put(fqName, classData);
@@ -994,7 +928,7 @@ public class JavaDescriptorResolver {
JavaNamespaceDescriptor ns = new JavaNamespaceDescriptor( JavaNamespaceDescriptor ns = new JavaNamespaceDescriptor(
parentNs, parentNs,
Collections.<AnnotationDescriptor>emptyList(), // TODO Collections.<AnnotationDescriptor>emptyList(), // TODO
qualifiedName.isRoot() ? "<root>" : qualifiedName.shortName(), qualifiedName.isRoot() ? FqNameUnsafe.ROOT_NAME : qualifiedName.shortName(),
qualifiedName qualifiedName
); );
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.AbstractNamespaceDescriptorImpl; import org.jetbrains.jet.lang.descriptors.AbstractNamespaceDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorParent; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorParent;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.FqName;
@@ -49,6 +48,8 @@ public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl {
return memberScope; return memberScope;
} }
@NotNull
@Override
public FqName getQualifiedName() { public FqName getQualifiedName() {
return qualifiedName; return qualifiedName;
} }
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.FqName;
/**
* @author Nikolay Krasko
*/
public interface FqNamed {
@NotNull
FqName getQualifiedName();
}
@@ -46,8 +46,8 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
private final WritableScope scopeForSupertypeResolution; private final WritableScope scopeForSupertypeResolution;
private WritableScope scopeForInitializers = null; //contains members + primary constructor value parameters + map for backing fields private WritableScope scopeForInitializers = null; //contains members + primary constructor value parameters + map for backing fields
public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, public MutableClassDescriptor(@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetScope outerScope, ClassKind kind) { @NotNull JetScope outerScope, ClassKind kind, String name) {
super(containingDeclaration, kind); super(containingDeclaration, kind);
RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING; RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING;
@@ -64,38 +64,13 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
if (getKind() == ClassKind.TRAIT) { if (getKind() == ClassKind.TRAIT) {
setUpScopeForInitializers(this); setUpScopeForInitializers(this);
} }
setName(name);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull final MutableClassDescriptorLite classObjectDescriptor) {
ClassObjectStatus r = super.setClassObjectDescriptor(classObjectDescriptor);
if (r != ClassObjectStatus.OK) {
return r;
}
// Members of the class object are accessible from the class
// The scope must be lazy, because classObjectDescriptor may not by fully built yet
scopeForMemberResolution.importScope(new AbstractScopeAdapter() {
@NotNull
@Override
protected JetScope getWorkerScope() {
return classObjectDescriptor.getDefaultType().getMemberScope();
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
return classObjectDescriptor.getImplicitReceiver();
}
}
);
return ClassObjectStatus.OK;
}
@Override @Override
public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, @NotNull BindingTrace trace) { public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, @NotNull BindingTrace trace) {
super.addConstructor(constructorDescriptor, trace); super.addConstructor(constructorDescriptor, trace);
@@ -111,28 +86,6 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
} }
} }
@Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
super.addPropertyDescriptor(propertyDescriptor);
properties.add(propertyDescriptor);
if (propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
declaredCallableMembers.add(propertyDescriptor);
}
allCallableMembers.add(propertyDescriptor);
scopeForMemberResolution.addPropertyDescriptor(propertyDescriptor);
}
@Override
public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
super.addFunctionDescriptor(functionDescriptor);
functions.add(functionDescriptor);
if (functionDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
declaredCallableMembers.add(functionDescriptor);
}
allCallableMembers.add(functionDescriptor);
scopeForMemberResolution.addFunctionDescriptor(functionDescriptor);
}
@NotNull @NotNull
public Set<SimpleFunctionDescriptor> getFunctions() { public Set<SimpleFunctionDescriptor> getFunctions() {
return functions; return functions;
@@ -154,11 +107,6 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
} }
@Override @Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
super.addClassifierDescriptor(classDescriptor);
scopeForMemberResolution.addClassifierDescriptor(classDescriptor);
}
public void setTypeParameterDescriptors(List<TypeParameterDescriptor> typeParameters) { public void setTypeParameterDescriptors(List<TypeParameterDescriptor> typeParameters) {
super.setTypeParameterDescriptors(typeParameters); super.setTypeParameterDescriptors(typeParameters);
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
@@ -207,6 +155,7 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
this.scopeForInitializers = new WritableScopeImpl(scopeForMemberResolution, containingDeclaration, RedeclarationHandler.DO_NOTHING).setDebugName("Initializers").changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForInitializers = new WritableScopeImpl(scopeForMemberResolution, containingDeclaration, RedeclarationHandler.DO_NOTHING).setDebugName("Initializers").changeLockLevel(WritableScope.LockLevel.BOTH);
} }
@Override
public void lockScopes() { public void lockScopes() {
super.lockScopes(); super.lockScopes();
scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING);
@@ -214,4 +163,81 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
getWritableScopeForInitializers().changeLockLevel(WritableScope.LockLevel.READING); getWritableScopeForInitializers().changeLockLevel(WritableScope.LockLevel.READING);
} }
private NamespaceLikeBuilder builder = null;
@Override
public NamespaceLikeBuilder getBuilder() {
if (builder == null) {
final NamespaceLikeBuilder superBuilder = super.getBuilder();
builder = new NamespaceLikeBuilderDummy() {
@NotNull
@Override
public DeclarationDescriptor getOwnerForChildren() {
return superBuilder.getOwnerForChildren();
}
@Override
public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) {
superBuilder.addObjectDescriptor(objectDescriptor);
}
@Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
superBuilder.addClassifierDescriptor(classDescriptor);
scopeForMemberResolution.addClassifierDescriptor(classDescriptor);
}
@Override
public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
superBuilder.addFunctionDescriptor(functionDescriptor);
functions.add(functionDescriptor);
if (functionDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
declaredCallableMembers.add(functionDescriptor);
}
allCallableMembers.add(functionDescriptor);
scopeForMemberResolution.addFunctionDescriptor(functionDescriptor);
}
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull final MutableClassDescriptorLite classObjectDescriptor) {
ClassObjectStatus r = superBuilder.setClassObjectDescriptor(classObjectDescriptor);
if (r != ClassObjectStatus.OK) {
return r;
}
// Members of the class object are accessible from the class
// The scope must be lazy, because classObjectDescriptor may not by fully built yet
scopeForMemberResolution.importScope(new AbstractScopeAdapter() {
@NotNull
@Override
protected JetScope getWorkerScope() {
return classObjectDescriptor.getDefaultType().getMemberScope();
}
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
return classObjectDescriptor.getImplicitReceiver();
}
}
);
return ClassObjectStatus.OK;
}
@Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
superBuilder.addPropertyDescriptor(propertyDescriptor);
properties.add(propertyDescriptor);
if (propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
declaredCallableMembers.add(propertyDescriptor);
}
allCallableMembers.add(propertyDescriptor);
scopeForMemberResolution.addPropertyDescriptor(propertyDescriptor);
}
};
}
return builder;
}
} }
@@ -36,7 +36,8 @@ import java.util.*;
/** /**
* @author Stepan Koltsov * @author Stepan Koltsov
*/ */
public class MutableClassDescriptorLite extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLikeBuilder { public class MutableClassDescriptorLite extends MutableDeclarationDescriptor
implements ClassDescriptor, WithDeferredResolve {
private ConstructorDescriptor primaryConstructor; private ConstructorDescriptor primaryConstructor;
private final Set<ConstructorDescriptor> constructors = Sets.newLinkedHashSet(); private final Set<ConstructorDescriptor> constructors = Sets.newLinkedHashSet();
@@ -60,11 +61,21 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
private ClassReceiver implicitReceiver; private ClassReceiver implicitReceiver;
public MutableClassDescriptorLite(@NotNull DeclarationDescriptor containingDeclaration, ClassKind kind) { public MutableClassDescriptorLite(@NotNull DeclarationDescriptor containingDeclaration,
@NotNull ClassKind kind) {
super(containingDeclaration); super(containingDeclaration);
this.kind = kind; this.kind = kind;
} }
@Override
public void forceResolve() {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean isAlreadyResolved() {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
private static boolean isStatic(DeclarationDescriptor declarationDescriptor) { private static boolean isStatic(DeclarationDescriptor declarationDescriptor) {
if (declarationDescriptor instanceof NamespaceDescriptor) { if (declarationDescriptor instanceof NamespaceDescriptor) {
@@ -79,29 +90,6 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
} }
} }
@NotNull
@Override
public DeclarationDescriptor getOwnerForChildren() {
return this;
}
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) {
if (this.classObjectDescriptor != null) return ClassObjectStatus.DUPLICATE;
if (!isStatic(this.getContainingDeclaration())) {
return ClassObjectStatus.NOT_ALLOWED;
}
assert classObjectDescriptor.getKind() == ClassKind.OBJECT;
this.classObjectDescriptor = classObjectDescriptor;
return ClassObjectStatus.OK;
}
@NotNull @NotNull
@Override @Override
public TypeConstructor getTypeConstructor() { public TypeConstructor getTypeConstructor() {
@@ -258,20 +246,7 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
return classObjectDescriptor; return classObjectDescriptor;
} }
@Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
getScopeForMemberLookupAsWritableScope().addPropertyDescriptor(propertyDescriptor);
}
@Override
public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
getScopeForMemberLookupAsWritableScope().addFunctionDescriptor(functionDescriptor);
}
@Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
getScopeForMemberLookupAsWritableScope().addClassifierDescriptor(classDescriptor);
}
@NotNull @NotNull
@Override @Override
@@ -279,11 +254,6 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
return innerClassesScope; return innerClassesScope;
} }
@Override
public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) {
getScopeForMemberLookupAsWritableScope().addObjectDescriptor(objectDescriptor);
}
public void addSupertype(@NotNull JetType supertype) { public void addSupertype(@NotNull JetType supertype) {
if (!ErrorUtils.isErrorType(supertype)) { if (!ErrorUtils.isErrorType(supertype)) {
if (TypeUtils.getClassDescriptor(supertype) != null) { if (TypeUtils.getClassDescriptor(supertype) != null) {
@@ -341,4 +311,59 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
public void setAnnotations(List<AnnotationDescriptor> annotations) { public void setAnnotations(List<AnnotationDescriptor> annotations) {
this.annotations = annotations; this.annotations = annotations;
} }
private NamespaceLikeBuilder builder = null;
public NamespaceLikeBuilder getBuilder() {
if (builder == null) {
builder = new NamespaceLikeBuilderDummy() {
@NotNull
@Override
public DeclarationDescriptor getOwnerForChildren() {
return MutableClassDescriptorLite.this;
}
@Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
getScopeForMemberLookupAsWritableScope().addClassifierDescriptor(classDescriptor);
}
@Override
public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) {
getScopeForMemberLookupAsWritableScope().addObjectDescriptor(objectDescriptor);
}
@Override
public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
getScopeForMemberLookupAsWritableScope().addFunctionDescriptor(functionDescriptor);
}
@Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
getScopeForMemberLookupAsWritableScope().addPropertyDescriptor(propertyDescriptor);
}
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) {
if (getKind() == ClassKind.OBJECT) {
return ClassObjectStatus.NOT_ALLOWED;
}
if (MutableClassDescriptorLite.this.classObjectDescriptor != null) {
return ClassObjectStatus.DUPLICATE;
}
if (!isStatic(MutableClassDescriptorLite.this.getContainingDeclaration())) {
return ClassObjectStatus.NOT_ALLOWED;
}
assert classObjectDescriptor.getKind() == ClassKind.OBJECT;
MutableClassDescriptorLite.this.classObjectDescriptor = classObjectDescriptor;
return ClassObjectStatus.OK;
}
};
}
return builder;
}
} }
@@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.types.NamespaceType;
/** /**
* @author abreslav * @author abreslav
*/ */
public interface NamespaceDescriptor extends Annotated, Named, ClassOrNamespaceDescriptor, NamespaceDescriptorParent { public interface NamespaceDescriptor extends Annotated, Named, FqNamed, ClassOrNamespaceDescriptor, NamespaceDescriptorParent {
@NotNull @NotNull
JetScope getMemberScope(); JetScope getMemberScope();
@@ -17,7 +17,10 @@
package org.jetbrains.jet.lang.descriptors; package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import java.util.List; import java.util.List;
@@ -25,7 +28,7 @@ import java.util.List;
/** /**
* @author abreslav * @author abreslav
*/ */
public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl implements NamespaceLikeBuilder { public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl implements WithDeferredResolve {
private WritableScope memberScope; private WritableScope memberScope;
@@ -36,13 +39,11 @@ public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl imp
} }
public void initialize(@NotNull WritableScope memberScope) { public void initialize(@NotNull WritableScope memberScope) {
this.memberScope = memberScope; if (this.memberScope != null) {
} throw new IllegalStateException("Namespace member scope reinitialize");
}
@NotNull this.memberScope = memberScope;
@Override
public DeclarationDescriptor getOwnerForChildren() {
return this;
} }
@Override @Override
@@ -51,37 +52,64 @@ public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl imp
return memberScope; return memberScope;
} }
public NamespaceDescriptorImpl getNamespace(String name) {
return (NamespaceDescriptorImpl) memberScope.getDeclaredNamespace(name);
}
@Override @Override
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
memberScope.addNamespace(namespaceDescriptor); getMemberScope().addNamespace(namespaceDescriptor);
}
@NotNull
@Override
public FqName getQualifiedName() {
return DescriptorUtils.getFQName(this).toSafe();
}
private NamespaceLikeBuilder builder = null;
public NamespaceLikeBuilder getBuilder() {
if (builder == null) {
builder = new NamespaceLikeBuilder() {
@Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
getMemberScope().addClassifierDescriptor(classDescriptor);
}
@Override
public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) {
getMemberScope().addObjectDescriptor(objectDescriptor);
}
@Override
public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
getMemberScope().addFunctionDescriptor(functionDescriptor);
}
@Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
getMemberScope().addPropertyDescriptor(propertyDescriptor);
}
@NotNull
@Override
public DeclarationDescriptor getOwnerForChildren() {
return NamespaceDescriptorImpl.this;
}
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) {
throw new IllegalStateException("Must be guaranteed not to happen by the parser");
}
};
}
return builder;
} }
@Override @Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) { public void forceResolve() {
memberScope.addClassifierDescriptor(classDescriptor); //To change body of implemented methods use File | Settings | File Templates.
} }
@Override @Override
public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) { public boolean isAlreadyResolved() {
memberScope.addObjectDescriptor(objectDescriptor); return false; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
memberScope.addFunctionDescriptor(functionDescriptor);
}
@Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
memberScope.addPropertyDescriptor(propertyDescriptor);
}
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) {
throw new IllegalStateException("Must be guaranteed not to happen by the parser");
} }
} }
@@ -34,9 +34,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.jetbrains.jet.lang.diagnostics.Errors.CONSTRUCTOR_IN_TRAIT; import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.REDECLARATION;
import static org.jetbrains.jet.lang.diagnostics.Errors.SECONDARY_CONSTRUCTORS_ARE_NOT_SUPPORTED;
/** /**
* @author abreslav * @author abreslav
@@ -127,7 +125,7 @@ public class DeclarationResolver {
for (Map.Entry<JetFile, WritableScope> entry : context.getNamespaceScopes().entrySet()) { for (Map.Entry<JetFile, WritableScope> entry : context.getNamespaceScopes().entrySet()) {
JetFile namespace = entry.getKey(); JetFile namespace = entry.getKey();
WritableScope namespaceScope = entry.getValue(); WritableScope namespaceScope = entry.getValue();
NamespaceLikeBuilder namespaceDescriptor = context.getNamespaceDescriptors().get(namespace); NamespaceLikeBuilder namespaceDescriptor = context.getNamespaceDescriptors().get(namespace).getBuilder();
resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceScope, namespaceScope, namespaceDescriptor); resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceScope, namespaceScope, namespaceDescriptor);
} }
@@ -135,13 +133,14 @@ public class DeclarationResolver {
JetClass jetClass = entry.getKey(); JetClass jetClass = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue(); MutableClassDescriptor classDescriptor = entry.getValue();
resolveFunctionAndPropertyHeaders(jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(), resolveFunctionAndPropertyHeaders(
jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(),
classDescriptor.getScopeForInitializers(), classDescriptor.getScopeForMemberResolution(), classDescriptor.getScopeForInitializers(), classDescriptor.getScopeForMemberResolution(),
classDescriptor); classDescriptor.getBuilder());
// processPrimaryConstructor(classDescriptor, jetClass); // processPrimaryConstructor(classDescriptor, jetClass);
// for (JetSecondaryConstructor jetConstructor : jetClass.getSecondaryConstructors()) { // for (JetSecondaryConstructor jetConstructor : jetClass.getSecondaryConstructors()) {
// processSecondaryConstructor(classDescriptor, jetConstructor); // processSecondaryConstructor(classDescriptor, jetConstructor);
// } // }
} }
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) { for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
JetObjectDeclaration object = entry.getKey(); JetObjectDeclaration object = entry.getKey();
@@ -149,7 +148,7 @@ public class DeclarationResolver {
resolveFunctionAndPropertyHeaders(object.getDeclarations(), classDescriptor.getScopeForMemberResolution(), resolveFunctionAndPropertyHeaders(object.getDeclarations(), classDescriptor.getScopeForMemberResolution(),
classDescriptor.getScopeForInitializers(), classDescriptor.getScopeForMemberResolution(), classDescriptor.getScopeForInitializers(), classDescriptor.getScopeForMemberResolution(),
classDescriptor); classDescriptor.getBuilder());
} }
// TODO : Extensions // TODO : Extensions
@@ -186,17 +185,22 @@ public class DeclarationResolver {
@Override @Override
public void visitObjectDeclaration(JetObjectDeclaration declaration) { public void visitObjectDeclaration(JetObjectDeclaration declaration) {
PropertyDescriptor propertyDescriptor = descriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(namespaceLike.getOwnerForChildren(), declaration, context.getObjects().get(declaration), trace); PropertyDescriptor propertyDescriptor = descriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(
namespaceLike.getOwnerForChildren(), declaration, context.getObjects().get(declaration), trace);
namespaceLike.addPropertyDescriptor(propertyDescriptor); namespaceLike.addPropertyDescriptor(propertyDescriptor);
} }
@Override @Override
public void visitEnumEntry(JetEnumEntry enumEntry) { public void visitEnumEntry(JetEnumEntry enumEntry) {
if (enumEntry.getPrimaryConstructorParameterList() == null) { if (enumEntry.getPrimaryConstructorParameterList() == null) {
MutableClassDescriptorLite classObjectDescriptor = ((MutableClassDescriptor) namespaceLike).getClassObjectDescriptor(); // FIX: Bad cast
MutableClassDescriptorLite classObjectDescriptor =
((MutableClassDescriptorLite)namespaceLike.getOwnerForChildren()).getClassObjectDescriptor();
assert classObjectDescriptor != null; assert classObjectDescriptor != null;
PropertyDescriptor propertyDescriptor = descriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(classObjectDescriptor, enumEntry, context.getClasses().get(enumEntry), trace); PropertyDescriptor propertyDescriptor = descriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(
classObjectDescriptor.addPropertyDescriptor(propertyDescriptor); classObjectDescriptor, enumEntry, context.getClasses().get(enumEntry), trace);
classObjectDescriptor.getBuilder().addPropertyDescriptor(propertyDescriptor);
} }
} }
}); });
@@ -222,7 +226,7 @@ public class DeclarationResolver {
memberScope, memberScope,
parameter, trace parameter, trace
); );
classDescriptor.addPropertyDescriptor(propertyDescriptor); classDescriptor.getBuilder().addPropertyDescriptor(propertyDescriptor);
context.getPrimaryConstructorParameterProperties().put(parameter, propertyDescriptor); context.getPrimaryConstructorParameterProperties().put(parameter, propertyDescriptor);
} }
} }
@@ -72,7 +72,7 @@ public class DelegationResolver {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) declarationDescriptor; PropertyDescriptor propertyDescriptor = (PropertyDescriptor) declarationDescriptor;
if (propertyDescriptor.getModality().isOverridable()) { if (propertyDescriptor.getModality().isOverridable()) {
PropertyDescriptor copy = propertyDescriptor.copy(classDescriptor, true, CallableMemberDescriptor.Kind.DELEGATION, true); PropertyDescriptor copy = propertyDescriptor.copy(classDescriptor, true, CallableMemberDescriptor.Kind.DELEGATION, true);
classDescriptor.addPropertyDescriptor(copy); classDescriptor.getBuilder().addPropertyDescriptor(copy);
trace.record(DELEGATED, copy); trace.record(DELEGATED, copy);
} }
} }
@@ -80,7 +80,7 @@ public class DelegationResolver {
SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) declarationDescriptor; SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) declarationDescriptor;
if (functionDescriptor.getModality().isOverridable()) { if (functionDescriptor.getModality().isOverridable()) {
SimpleFunctionDescriptor copy = functionDescriptor.copy(classDescriptor, true, CallableMemberDescriptor.Kind.DELEGATION, true); SimpleFunctionDescriptor copy = functionDescriptor.copy(classDescriptor, true, CallableMemberDescriptor.Kind.DELEGATION, true);
classDescriptor.addFunctionDescriptor(copy); classDescriptor.getBuilder().addFunctionDescriptor(copy);
trace.record(DELEGATED, copy); trace.record(DELEGATED, copy);
} }
} }
@@ -29,6 +29,8 @@ import java.util.List;
*/ */
public class FqNameUnsafe { public class FqNameUnsafe {
public static final String ROOT_NAME = "<root>";
@NotNull @NotNull
private final String fqName; private final String fqName;
@@ -246,7 +248,7 @@ public class FqNameUnsafe {
@Override @Override
public String toString() { public String toString() {
return isRoot() ? "<root>" : fqName; return isRoot() ? ROOT_NAME : fqName;
} }
@Override @Override
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
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.ModuleConfiguration; import org.jetbrains.jet.lang.ModuleConfiguration;
@@ -61,14 +62,17 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
this.configuration = configuration; this.configuration = configuration;
} }
public NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(JetFile file, JetScope outerScope) { @NotNull
public NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(@NotNull JetFile file,
@NotNull JetScope outerScope,
@NotNull RedeclarationHandler handler) {
JetNamespaceHeader namespaceHeader = file.getNamespaceHeader(); JetNamespaceHeader namespaceHeader = file.getNamespaceHeader();
if (moduleDescriptor.getRootNs() == null) { if (moduleDescriptor.getRootNs() == null) {
createNamespaceDescriptorIfNeeded(null, moduleDescriptor, "<root>", true, null); createRootNamespaceDescriptorIfNeeded(null, moduleDescriptor, null, handler);
} }
NamespaceDescriptorParent currentOwner = moduleDescriptor.getRootNs(); NamespaceDescriptorImpl currentOwner = moduleDescriptor.getRootNs();
if (currentOwner == null) { if (currentOwner == null) {
throw new IllegalStateException("must be initialized 5 lines above"); throw new IllegalStateException("must be initialized 5 lines above");
} }
@@ -77,7 +81,7 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
String namespaceName = JetPsiUtil.safeName(nameExpression.getReferencedName()); String namespaceName = JetPsiUtil.safeName(nameExpression.getReferencedName());
NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorIfNeeded( NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorIfNeeded(
null, currentOwner, namespaceName, false, nameExpression); null, currentOwner, namespaceName, nameExpression, handler);
trace.record(BindingContext.NAMESPACE_IS_SRC, namespaceDescriptor, true); trace.record(BindingContext.NAMESPACE_IS_SRC, namespaceDescriptor, true);
trace.record(RESOLUTION_SCOPE, nameExpression, outerScope); trace.record(RESOLUTION_SCOPE, nameExpression, outerScope);
@@ -89,13 +93,14 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
NamespaceDescriptorImpl namespaceDescriptor; NamespaceDescriptorImpl namespaceDescriptor;
String name; String name;
if (namespaceHeader.isRoot()) { if (namespaceHeader.isRoot()) {
// again to register file in trace // previous call to createRootNamespaceDescriptorIfNeeded couldn't store occurrence for current file.
namespaceDescriptor = createNamespaceDescriptorIfNeeded(file, moduleDescriptor, "<root>", true, null); namespaceDescriptor = moduleDescriptor.getRootNs();
storeBindingForFileAndExpression(file, null, namespaceDescriptor);
} }
else { else {
name = namespaceHeader.getName(); name = namespaceHeader.getName();
namespaceDescriptor = createNamespaceDescriptorIfNeeded(file, currentOwner, name, namespaceHeader.isRoot(), namespaceDescriptor = createNamespaceDescriptorIfNeeded(
namespaceHeader.getLastPartExpression()); file, currentOwner, name, namespaceHeader.getLastPartExpression(), handler);
trace.record(BindingContext.NAMESPACE_IS_SRC, namespaceDescriptor, true); trace.record(BindingContext.NAMESPACE_IS_SRC, namespaceDescriptor, true);
trace.record(RESOLUTION_SCOPE, namespaceHeader, outerScope); trace.record(RESOLUTION_SCOPE, namespaceHeader, outerScope);
@@ -107,49 +112,95 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
@Override @Override
@NotNull @NotNull
public NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(@NotNull FqName fqName) { public NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(@NotNull FqName fqName) {
NamespaceDescriptorParent owner = moduleDescriptor; NamespaceDescriptorImpl owner = null;
for (FqName pathElement : fqName.path()) { for (FqName pathElement : fqName.path()) {
owner = createNamespaceDescriptorIfNeeded(null, if (pathElement.isRoot()) {
owner, pathElement.isRoot() ? "<root>" : pathElement.shortName(), pathElement.isRoot(), null); owner = createRootNamespaceDescriptorIfNeeded(null,
moduleDescriptor,
null,
RedeclarationHandler.DO_NOTHING);
}
else {
assert owner != null : "Should never be null as first element in the path must be root";
owner = createNamespaceDescriptorIfNeeded(null,
owner,
pathElement.shortName(),
null,
RedeclarationHandler.DO_NOTHING);
}
} }
return (NamespaceDescriptorImpl) owner;
assert owner != null : "Should never be null as first element in the path must be root";
return owner;
}
private NamespaceDescriptorImpl createRootNamespaceDescriptorIfNeeded(@Nullable JetFile file,
@NotNull ModuleDescriptor owner,
@Nullable JetReferenceExpression expression,
@NotNull RedeclarationHandler handler) {
FqName fqName = FqName.ROOT;
NamespaceDescriptorImpl namespaceDescriptor = owner.getRootNs();
if (namespaceDescriptor == null) {
namespaceDescriptor = createNewNamespaceDescriptor(owner, FqNameUnsafe.ROOT_NAME, expression, handler, fqName);
}
storeBindingForFileAndExpression(file, expression, namespaceDescriptor);
return namespaceDescriptor;
} }
@NotNull @NotNull
public NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file, private NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file,
@NotNull NamespaceDescriptorParent owner, @NotNull String name, boolean root, @Nullable JetReferenceExpression expression) { @NotNull NamespaceDescriptorImpl owner,
FqName fqName; @NotNull String name,
NamespaceDescriptorImpl namespaceDescriptor; @Nullable JetReferenceExpression expression,
if (root) { @NotNull RedeclarationHandler handler) {
if (!(owner instanceof ModuleDescriptor)) { FqName ownerFqName = DescriptorUtils.getFQName(owner).toSafe();
throw new IllegalStateException(); FqName fqName = ownerFqName.child(name);
} // !!!
fqName = FqName.ROOT; NamespaceDescriptorImpl namespaceDescriptor = (NamespaceDescriptorImpl) owner.getMemberScope().getDeclaredNamespace(name);
namespaceDescriptor = ((ModuleDescriptor) owner).getRootNs();
}
else {
FqName ownerFqName = DescriptorUtils.getFQName(owner).toSafe();
fqName = ownerFqName.child(name);
namespaceDescriptor = ((NamespaceDescriptorImpl) owner).getNamespace(name);
}
if (namespaceDescriptor == null) { if (namespaceDescriptor == null) {
namespaceDescriptor = new NamespaceDescriptorImpl( namespaceDescriptor = createNewNamespaceDescriptor(owner, name, expression, handler, fqName);
owner,
Collections.<AnnotationDescriptor>emptyList(), // TODO: annotations
name
);
trace.record(FQNAME_TO_NAMESPACE_DESCRIPTOR, fqName, namespaceDescriptor);
WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, RedeclarationHandler.DO_NOTHING).setDebugName("Namespace member scope");
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
namespaceDescriptor.initialize(scope);
configuration.extendNamespaceScope(trace, namespaceDescriptor, scope);
owner.addNamespace(namespaceDescriptor);
if (expression != null) {
trace.record(BindingContext.NAMESPACE, expression, namespaceDescriptor);
}
} }
storeBindingForFileAndExpression(file, expression, namespaceDescriptor);
return namespaceDescriptor;
}
private NamespaceDescriptorImpl createNewNamespaceDescriptor(NamespaceDescriptorParent owner,
String name,
PsiElement expression,
RedeclarationHandler handler,
FqName fqName) {
NamespaceDescriptorImpl namespaceDescriptor;
namespaceDescriptor = new NamespaceDescriptorImpl(
owner,
Collections.<AnnotationDescriptor>emptyList(), // TODO: annotations
name
);
trace.record(FQNAME_TO_NAMESPACE_DESCRIPTOR, fqName, namespaceDescriptor);
WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, handler).setDebugName("Namespace member scope");
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
namespaceDescriptor.initialize(scope);
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
//
configuration.extendNamespaceScope(trace, namespaceDescriptor, scope);
owner.addNamespace(namespaceDescriptor);
if (expression != null) {
trace.record(BindingContext.NAMESPACE, expression, namespaceDescriptor);
}
return namespaceDescriptor;
}
private void storeBindingForFileAndExpression(@Nullable JetFile file,
@Nullable JetReferenceExpression expression,
@NotNull NamespaceDescriptor namespaceDescriptor) {
if (expression != null) { if (expression != null) {
trace.record(REFERENCE_TARGET, expression, namespaceDescriptor); trace.record(REFERENCE_TARGET, expression, namespaceDescriptor);
} }
@@ -166,9 +217,5 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
files.add(file); files.add(file);
trace.record(BindingContext.NAMESPACE_TO_FILES, namespaceDescriptor, files); trace.record(BindingContext.NAMESPACE_TO_FILES, namespaceDescriptor, files);
} }
return namespaceDescriptor;
} }
} }
@@ -138,10 +138,10 @@ public class OverrideResolver {
@Override @Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) { public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
if (fakeOverride instanceof PropertyDescriptor) { if (fakeOverride instanceof PropertyDescriptor) {
classDescriptor.addPropertyDescriptor((PropertyDescriptor) fakeOverride); classDescriptor.getBuilder().addPropertyDescriptor((PropertyDescriptor) fakeOverride);
} }
else if (fakeOverride instanceof SimpleFunctionDescriptor) { else if (fakeOverride instanceof SimpleFunctionDescriptor) {
classDescriptor.addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride); classDescriptor.getBuilder().addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
} }
else { else {
throw new IllegalStateException(fakeOverride.getClass().getName()); throw new IllegalStateException(fakeOverride.getClass().getName());
@@ -16,7 +16,6 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.LinkedHashMultimap;
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 com.intellij.psi.PsiElement;
@@ -30,7 +29,6 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import javax.inject.Inject; import javax.inject.Inject;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* @author abreslav * @author abreslav
@@ -39,7 +37,6 @@ public class TopDownAnalysisContext {
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap(); private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap(); private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
protected final Map<JetFile, WritableScope> namespaceScopes = Maps.newHashMap();
private JetScope rootScope; private JetScope rootScope;
protected final Map<JetFile, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap(); protected final Map<JetFile, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
@@ -50,6 +47,13 @@ public class TopDownAnalysisContext {
private final Map<JetParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap(); private final Map<JetParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap();
private Map<JetDeclaration, CallableMemberDescriptor> members = null; private Map<JetDeclaration, CallableMemberDescriptor> members = null;
// File scopes - package scope extended with imports
protected final Map<JetFile, WritableScope> namespaceScopes = Maps.newHashMap();
public final Map<JetDeclarationContainer, WithDeferredResolve> forDeferredResolver = Maps.newHashMap();
public final Map<JetDeclarationContainer, JetScope> normalScope = Maps.newHashMap();
private StringBuilder debugOutput; private StringBuilder debugOutput;
@@ -199,7 +199,7 @@ public class TopDownAnalyzer {
} }
// context.getDeclaringScopes().put(file, outerScope); // context.getDeclaringScopes().put(file, outerScope);
doProcess(outerScope, standardLibraryNamespace, toAnalyze); doProcess(outerScope, standardLibraryNamespace.getBuilder(), toAnalyze);
} }
public static void processObject( public static void processObject(
@@ -207,8 +207,8 @@ public class TopDownAnalyzer {
@NotNull final BindingTrace trace, @NotNull final BindingTrace trace,
@NotNull JetScope outerScope, @NotNull JetScope outerScope,
@NotNull final DeclarationDescriptor containingDeclaration, @NotNull final DeclarationDescriptor containingDeclaration,
@NotNull JetObjectDeclaration object) { @NotNull JetObjectDeclaration object
) {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("<dummy for object>"); ModuleDescriptor moduleDescriptor = new ModuleDescriptor("<dummy for object>");
TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters topDownAnalysisParameters =
@@ -27,9 +27,13 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope; import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.SubstitutionUtils;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
@@ -82,11 +86,42 @@ public class TypeHierarchyResolver {
this.trace = trace; this.trace = trace;
} }
public void process(@NotNull JetScope outerScope, @NotNull NamespaceLikeBuilder owner,
@NotNull Collection<? extends PsiElement> declarations) {
public void process(@NotNull JetScope outerScope, @NotNull NamespaceLikeBuilder owner, @NotNull Collection<? extends PsiElement> declarations) {
context.setRootScope(outerScope); context.setRootScope(outerScope);
collectNamespacesAndClassifiers(outerScope, outerScope, owner, declarations); // namespaceScopes, classes
{
// TODO: Very temp code - main goal is to remove recursion from collectNamespacesAndClassifiers
Queue<JetDeclarationContainer> forDeferredResolve = new LinkedList<JetDeclarationContainer>();
forDeferredResolve.addAll(collectNamespacesAndClassifiers(outerScope, owner, declarations));
while (!forDeferredResolve.isEmpty()) {
JetDeclarationContainer declarationContainer = forDeferredResolve.poll();
assert declarationContainer != null;
WithDeferredResolve descriptorForDeferredResolve = context.forDeferredResolver.get(declarationContainer);
JetScope scope = context.normalScope.get(declarationContainer);
// Even more temp code
if (descriptorForDeferredResolve instanceof MutableClassDescriptorLite) {
forDeferredResolve.addAll(
collectNamespacesAndClassifiers(
scope,
((MutableClassDescriptorLite) descriptorForDeferredResolve).getBuilder(),
declarationContainer.getDeclarations()));
}
else if (descriptorForDeferredResolve instanceof NamespaceDescriptorImpl) {
forDeferredResolve.addAll(
collectNamespacesAndClassifiers(
scope,
((NamespaceDescriptorImpl) descriptorForDeferredResolve).getBuilder(),
declarationContainer.getDeclarations()));
}
else {
assert false;
}
}
}
importsResolver.processTypeImports(); importsResolver.processTypeImports();
@@ -106,105 +141,111 @@ public class TypeHierarchyResolver {
checkTypesInClassHeaders(); // Check bounds in the types used in generic bounds and supertype lists checkTypesInClassHeaders(); // Check bounds in the types used in generic bounds and supertype lists
} }
private void collectNamespacesAndClassifiers( /**
* Use nearest class object scope or namespace scope
*
* @param declarationElement
* @param owner
* @return
*/
@NotNull
private JetScope getStaticScope(PsiElement declarationElement, @NotNull NamespaceLikeBuilder owner) {
DeclarationDescriptor ownerDescriptor = owner.getOwnerForChildren();
if (ownerDescriptor instanceof NamespaceDescriptorImpl) {
return context.getNamespaceScopes().get(declarationElement.getContainingFile());
}
if (ownerDescriptor instanceof MutableClassDescriptor) {
MutableClassDescriptor classDescriptor = (MutableClassDescriptor) ownerDescriptor;
if (classDescriptor.getKind() == ClassKind.OBJECT) {
return classDescriptor.getScopeForMemberResolution();
}
DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration();
if (declaration instanceof NamespaceDescriptorImpl) {
return getStaticScope(declarationElement, ((NamespaceDescriptorImpl)declaration).getBuilder());
}
if (declaration instanceof MutableClassDescriptorLite) {
return getStaticScope(declarationElement, ((MutableClassDescriptorLite)declaration).getBuilder());
}
}
return null;
}
@Nullable
private Collection<JetDeclarationContainer> collectNamespacesAndClassifiers(
@NotNull final JetScope outerScope, @NotNull final JetScope outerScope,
@NotNull final JetScope outerScopeForStatic,
@NotNull final NamespaceLikeBuilder owner, @NotNull final NamespaceLikeBuilder owner,
@NotNull Collection<? extends PsiElement> declarations) { @NotNull Iterable<? extends PsiElement> declarations
) {
final Collection<JetDeclarationContainer> forDeferredResolve = new ArrayList<JetDeclarationContainer>();
for (PsiElement declaration : declarations) { for (PsiElement declaration : declarations) {
declaration.accept(new JetVisitorVoid() { declaration.accept(new JetVisitorVoid() {
@Override @Override
public void visitJetFile(JetFile file) { public void visitJetFile(JetFile file) {
NamespaceDescriptorImpl namespaceDescriptor = namespaceFactory.createNamespaceDescriptorPathIfNeeded(file, outerScope); NamespaceDescriptorImpl namespaceDescriptor = namespaceFactory.createNamespaceDescriptorPathIfNeeded(
file, outerScope, RedeclarationHandler.DO_NOTHING);
context.getNamespaceDescriptors().put(file, namespaceDescriptor); context.getNamespaceDescriptors().put(file, namespaceDescriptor);
WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), new TraceBasedRedeclarationHandler(trace)); WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(),
new TraceBasedRedeclarationHandler(trace));
namespaceScope.changeLockLevel(WritableScope.LockLevel.BOTH); namespaceScope.changeLockLevel(WritableScope.LockLevel.BOTH);
context.getNamespaceScopes().put(file, namespaceScope); context.getNamespaceScopes().put(file, namespaceScope);
collectNamespacesAndClassifiers(namespaceScope, namespaceScope, namespaceDescriptor, file.getDeclarations()); prepareForDeferredCall(namespaceScope, namespaceDescriptor, file);
} }
@Override @Override
public void visitClass(JetClass klass) { public void visitClass(JetClass klass) {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner.getOwnerForChildren(), outerScope, getClassKind(klass)); MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(
owner.getOwnerForChildren(), outerScope, getClassKind(klass), JetPsiUtil.safeName(klass.getName()));
context.getClasses().put(klass, mutableClassDescriptor);
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(klass), mutableClassDescriptor); trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(klass), mutableClassDescriptor);
if (klass.hasModifier(JetTokens.ENUM_KEYWORD)) { createClassObjectForEnumClass(klass, mutableClassDescriptor);
MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor(trace, mutableClassDescriptor, outerScope, ClassKind.OBJECT);
classObjectDescriptor.setName("class-object-for-" + klass.getName());
classObjectDescriptor.setModality(Modality.FINAL);
classObjectDescriptor.setVisibility(DescriptorResolver.resolveVisibilityFromModifiers(klass.getModifierList()));
classObjectDescriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0));
classObjectDescriptor.createTypeConstructor();
createPrimaryConstructorForObject(null, classObjectDescriptor);
mutableClassDescriptor.setClassObjectDescriptor(classObjectDescriptor);
}
visitClassOrObject(klass, (Map) context.getClasses(), mutableClassDescriptor); JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
prepareForDeferredCall(classScope, mutableClassDescriptor, klass);
owner.addClassifierDescriptor(mutableClassDescriptor); owner.addClassifierDescriptor(mutableClassDescriptor);
} }
@Override @Override
public void visitObjectDeclaration(JetObjectDeclaration declaration) { public void visitObjectDeclaration(JetObjectDeclaration declaration) {
final MutableClassDescriptor objectDescriptor = createClassDescriptorForObject(declaration, owner, outerScope, ClassKind.OBJECT); final MutableClassDescriptor objectDescriptor = createClassDescriptorForObject(declaration, owner, outerScope);
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(declaration), objectDescriptor); trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(declaration), objectDescriptor);
} }
@Override @Override
public void visitEnumEntry(JetEnumEntry enumEntry) { public void visitEnumEntry(JetEnumEntry enumEntry) {
MutableClassDescriptorLite classObjectDescriptor = ((MutableClassDescriptor) owner).getClassObjectDescriptor(); // TODO: Bad casting
MutableClassDescriptorLite ownerClassDescriptor = (MutableClassDescriptorLite) owner.getOwnerForChildren();
MutableClassDescriptorLite classObjectDescriptor = ownerClassDescriptor.getClassObjectDescriptor();
assert classObjectDescriptor != null : enumEntry.getParent().getText(); assert classObjectDescriptor != null : enumEntry.getParent().getText();
if (enumEntry.getPrimaryConstructorParameterList() == null) { if (enumEntry.getPrimaryConstructorParameterList() == null) {
createClassDescriptorForObject(enumEntry, classObjectDescriptor, outerScopeForStatic, ClassKind.ENUM_ENTRY); // Simple enum entry
return;
createClassDescriptorForEnumEntry(enumEntry, classObjectDescriptor.getBuilder());
} }
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, classObjectDescriptor, outerScope, ClassKind.ENUM_ENTRY); else {
visitClassOrObject( // Advanced enum entry like "Cons<out T>(val head : T, val tail : List<T>) : List<T>(tail.size + 1)"
enumEntry, MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(
(Map) context.getClasses(), classObjectDescriptor, outerScope, ClassKind.ENUM_ENTRY, JetPsiUtil.safeName(enumEntry.getName()));
mutableClassDescriptor context.getClasses().put(enumEntry, mutableClassDescriptor);
);
classObjectDescriptor.addObjectDescriptor(mutableClassDescriptor);
}
private MutableClassDescriptor createClassDescriptorForObject(@NotNull JetClassOrObject declaration, @NotNull NamespaceLikeBuilder owner, JetScope scope, ClassKind classKind) { JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner.getOwnerForChildren(), scope, classKind) {
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) {
return ClassObjectStatus.NOT_ALLOWED;
}
};
Map<JetClassOrObject, MutableClassDescriptor> map = classKind == ClassKind.OBJECT ? (Map) context.getObjects() : (Map) context.getClasses();
visitClassOrObject(declaration, map, mutableClassDescriptor);
createPrimaryConstructorForObject((JetDeclaration) declaration, mutableClassDescriptor);
owner.addObjectDescriptor(mutableClassDescriptor);
trace.record(BindingContext.CLASS, declaration, mutableClassDescriptor);
return mutableClassDescriptor;
}
private void createPrimaryConstructorForObject(@Nullable JetDeclaration object, MutableClassDescriptor mutableClassDescriptor) { prepareForDeferredCall(classScope, mutableClassDescriptor, enumEntry);
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(mutableClassDescriptor, Collections.<AnnotationDescriptor>emptyList(), true);
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(), classObjectDescriptor.getBuilder().addObjectDescriptor(mutableClassDescriptor);
Visibilities.INTERNAL);//TODO check set mutableClassDescriptor.getVisibility()
// TODO : make the constructor private?
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor, trace);
if (object != null) {
trace.record(CONSTRUCTOR, object, constructorDescriptor);
} }
} }
private void visitClassOrObject(@NotNull JetClassOrObject declaration, Map<JetClassOrObject, MutableClassDescriptor> map, MutableClassDescriptor mutableClassDescriptor) {
mutableClassDescriptor.setName(JetPsiUtil.safeName(declaration.getName()));
map.put(declaration, mutableClassDescriptor);
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
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) {
trace.report(UNSUPPORTED.on(typedef, "TypeHierarchyResolver")); trace.report(UNSUPPORTED.on(typedef, "TypeHierarchyResolver"));
@@ -214,7 +255,8 @@ public class TypeHierarchyResolver {
public void visitClassObject(JetClassObject classObject) { public void visitClassObject(JetClassObject classObject) {
JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration(); JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
if (objectDeclaration != null) { if (objectDeclaration != null) {
NamespaceLikeBuilder.ClassObjectStatus status = owner.setClassObjectDescriptor(createClassDescriptorForObject(objectDeclaration, owner, outerScopeForStatic, ClassKind.OBJECT)); MutableClassDescriptor classObjectDescriptor = createClassDescriptorForObject(objectDeclaration, owner, getStaticScope(classObject, owner));
NamespaceLikeBuilder.ClassObjectStatus status = owner.setClassObjectDescriptor(classObjectDescriptor);
switch (status) { switch (status) {
case DUPLICATE: case DUPLICATE:
trace.report(MANY_CLASS_OBJECTS.on(classObject)); trace.report(MANY_CLASS_OBJECTS.on(classObject));
@@ -222,15 +264,87 @@ public class TypeHierarchyResolver {
case NOT_ALLOWED: case NOT_ALLOWED:
trace.report(CLASS_OBJECT_NOT_ALLOWED.on(classObject)); trace.report(CLASS_OBJECT_NOT_ALLOWED.on(classObject));
break; break;
case OK:
// Everything is OK so no errors to trace.
break;
} }
} }
} }
private void createClassObjectForEnumClass(JetClass klass, MutableClassDescriptor mutableClassDescriptor) {
if (klass.hasModifier(JetTokens.ENUM_KEYWORD)) {
MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor(
mutableClassDescriptor, outerScope, ClassKind.OBJECT, "class-object-for-" + klass.getName());
classObjectDescriptor.setModality(Modality.FINAL);
classObjectDescriptor.setVisibility(DescriptorResolver.resolveVisibilityFromModifiers(klass.getModifierList()));
classObjectDescriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0));
classObjectDescriptor.createTypeConstructor();
createPrimaryConstructorForObject(null, classObjectDescriptor);
mutableClassDescriptor.getBuilder().setClassObjectDescriptor(classObjectDescriptor);
}
}
private MutableClassDescriptor createClassDescriptorForObject(
@NotNull JetObjectDeclaration declaration, @NotNull NamespaceLikeBuilder owner, JetScope scope) {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(
owner.getOwnerForChildren(), scope, ClassKind.OBJECT, JetPsiUtil.safeName(declaration.getName()));
context.getObjects().put(declaration, mutableClassDescriptor);
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
prepareForDeferredCall(classScope, mutableClassDescriptor, declaration);
createPrimaryConstructorForObject(declaration, mutableClassDescriptor);
owner.addObjectDescriptor(mutableClassDescriptor);
trace.record(BindingContext.CLASS, declaration, mutableClassDescriptor);
return mutableClassDescriptor;
}
private MutableClassDescriptor createClassDescriptorForEnumEntry(@NotNull JetEnumEntry declaration, @NotNull NamespaceLikeBuilder owner) {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(
owner.getOwnerForChildren(), getStaticScope(declaration, owner), ClassKind.ENUM_ENTRY, JetPsiUtil.safeName(declaration.getName()));
context.getClasses().put(declaration, mutableClassDescriptor);
prepareForDeferredCall(mutableClassDescriptor.getScopeForMemberResolution(), mutableClassDescriptor, declaration);
// ??? - is enum entry object?
createPrimaryConstructorForObject(declaration, mutableClassDescriptor);
owner.addObjectDescriptor(mutableClassDescriptor);
trace.record(BindingContext.CLASS, declaration, mutableClassDescriptor);
return mutableClassDescriptor;
}
private void createPrimaryConstructorForObject(@Nullable PsiElement object, MutableClassDescriptor mutableClassDescriptor) {
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(mutableClassDescriptor, Collections.<AnnotationDescriptor>emptyList(), true);
// TODO check set mutableClassDescriptor.getVisibility()
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(),
Collections.<ValueParameterDescriptor>emptyList(), Visibilities.INTERNAL);
// TODO : make the constructor private?
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor, trace);
if (object != null) {
trace.record(CONSTRUCTOR, object, constructorDescriptor);
}
}
private void prepareForDeferredCall(@NotNull JetScope outerScope,
@NotNull WithDeferredResolve withDeferredResolve,
@NotNull JetDeclarationContainer container) {
forDeferredResolve.add(container);
context.normalScope.put(container, outerScope);
context.forDeferredResolver.put(container, withDeferredResolve);
}
}); });
} }
return forDeferredResolve;
} }
@NotNull @NotNull
private ClassKind getClassKind(@NotNull JetClass jetClass) { private static ClassKind getClassKind(@NotNull JetClass jetClass) {
if (jetClass.isTrait()) return ClassKind.TRAIT; if (jetClass.isTrait()) return ClassKind.TRAIT;
if (jetClass.hasModifier(JetTokens.ANNOTATION_KEYWORD)) return ClassKind.ANNOTATION_CLASS; if (jetClass.hasModifier(JetTokens.ANNOTATION_KEYWORD)) return ClassKind.ANNOTATION_CLASS;
if (jetClass.hasModifier(JetTokens.ENUM_KEYWORD)) return ClassKind.ENUM_CLASS; if (jetClass.hasModifier(JetTokens.ENUM_KEYWORD)) return ClassKind.ENUM_CLASS;
@@ -258,7 +372,8 @@ public class TypeHierarchyResolver {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey(); JetClass jetClass = entry.getKey();
MutableClassDescriptor descriptor = entry.getValue(); MutableClassDescriptor descriptor = entry.getValue();
descriptorResolver.resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(), descriptor.getTypeConstructor().getParameters(), trace); descriptorResolver.resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(),
descriptor.getTypeConstructor().getParameters(), trace);
descriptorResolver.resolveSupertypes(jetClass, descriptor, trace); descriptorResolver.resolveSupertypes(jetClass, descriptor, trace);
} }
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) { for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
@@ -292,7 +407,9 @@ public class TypeHierarchyResolver {
} }
} }
private static void topologicallySort(MutableClassDescriptor mutableClassDescriptor, Set<ClassDescriptor> visited, LinkedList<MutableClassDescriptor> topologicalOrder) { private static void topologicallySort(MutableClassDescriptor mutableClassDescriptor,
Set<ClassDescriptor> visited,
LinkedList<MutableClassDescriptor> topologicalOrder) {
if (!visited.add(mutableClassDescriptor)) { if (!visited.add(mutableClassDescriptor)) {
return; return;
} }
@@ -306,7 +423,10 @@ public class TypeHierarchyResolver {
topologicalOrder.addFirst(mutableClassDescriptor); topologicalOrder.addFirst(mutableClassDescriptor);
} }
private void traverseTypeHierarchy(MutableClassDescriptor currentClass, Set<ClassDescriptor> visited, Set<ClassDescriptor> beingProcessed, List<ClassDescriptor> currentPath) { private void traverseTypeHierarchy(MutableClassDescriptor currentClass,
Set<ClassDescriptor> visited,
Set<ClassDescriptor> beingProcessed,
List<ClassDescriptor> currentPath) {
if (!visited.add(currentClass)) { if (!visited.add(currentClass)) {
if (beingProcessed.contains(currentClass)) { if (beingProcessed.contains(currentClass)) {
markCycleErrors(currentPath, currentClass); markCycleErrors(currentPath, currentClass);
@@ -314,7 +434,8 @@ public class TypeHierarchyResolver {
ClassDescriptor subclassOfCurrent = currentPath.get(currentPath.size() - 1); ClassDescriptor subclassOfCurrent = currentPath.get(currentPath.size() - 1);
assert subclassOfCurrent instanceof MutableClassDescriptor; assert subclassOfCurrent instanceof MutableClassDescriptor;
// Disconnect the loop // Disconnect the loop
for (Iterator<JetType> iterator = ((MutableClassDescriptor) subclassOfCurrent).getSupertypes().iterator(); iterator.hasNext(); ) { for (Iterator<JetType> iterator = ((MutableClassDescriptor) subclassOfCurrent).getSupertypes().iterator();
iterator.hasNext(); ) {
JetType type = iterator.next(); JetType type = iterator.next();
if (type.getConstructor() == currentClass.getTypeConstructor()) { if (type.getConstructor() == currentClass.getTypeConstructor()) {
iterator.remove(); iterator.remove();
@@ -340,11 +461,8 @@ public class TypeHierarchyResolver {
private void markCycleErrors(List<ClassDescriptor> currentPath, @NotNull ClassDescriptor current) { private void markCycleErrors(List<ClassDescriptor> currentPath, @NotNull ClassDescriptor current) {
int size = currentPath.size(); int size = currentPath.size();
boolean found = false; for (int i = size - 1; i >= 0; i--) {
for (int i = 0; i < size; i++) {
ClassDescriptor classDescriptor = currentPath.get(i); ClassDescriptor classDescriptor = currentPath.get(i);
if (classDescriptor == current) found = true;
if (!found) continue;
ClassDescriptor superclass = (i < size - 1) ? currentPath.get(i + 1) : current; ClassDescriptor superclass = (i < size - 1) ? currentPath.get(i + 1) : current;
PsiElement psiElement = BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor); PsiElement psiElement = BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
@@ -371,6 +489,11 @@ public class TypeHierarchyResolver {
if (elementToMark != null) { if (elementToMark != null) {
trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark)); trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark));
} }
if (classDescriptor == current) {
// Beginning of cycle is found
break;
}
} }
} }
@@ -408,11 +531,14 @@ public class TypeHierarchyResolver {
if (conflictingTypes.size() > 1) { if (conflictingTypes.size() > 1) {
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
assert containingDeclaration instanceof ClassDescriptor : containingDeclaration; assert containingDeclaration instanceof ClassDescriptor : containingDeclaration;
JetClassOrObject psiElement = (JetClassOrObject) BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), mutableClassDescriptor); JetClassOrObject psiElement = (JetClassOrObject) BindingContextUtils
.classDescriptorToDeclaration(trace.getBindingContext(), mutableClassDescriptor);
JetDelegationSpecifierList delegationSpecifierList = psiElement.getDelegationSpecifierList(); JetDelegationSpecifierList delegationSpecifierList = psiElement.getDelegationSpecifierList();
assert delegationSpecifierList != null; assert delegationSpecifierList != null;
// trace.getErrorHandler().genericError(delegationSpecifierList.getNode(), "Type parameter " + typeParameterDescriptor.getName() + " of " + containingDeclaration.getName() + " has inconsistent values: " + conflictingTypes); // trace.getErrorHandler().genericError(delegationSpecifierList.getNode(), "Type parameter " + typeParameterDescriptor.getName() + " of " + containingDeclaration.getName() + " has inconsistent values: " + conflictingTypes);
trace.report(INCONSISTENT_TYPE_PARAMETER_VALUES.on(delegationSpecifierList, typeParameterDescriptor, (ClassDescriptor) containingDeclaration, conflictingTypes)); trace.report(INCONSISTENT_TYPE_PARAMETER_VALUES
.on(delegationSpecifierList, typeParameterDescriptor, (ClassDescriptor) containingDeclaration,
conflictingTypes));
} }
} }
} }
@@ -18,23 +18,17 @@ package org.jetbrains.jet.lang.types.lang;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.util.Pair;
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.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.scopes.*; import org.jetbrains.jet.lang.resolve.scopes.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.JetTypeImpl;
import org.jetbrains.jet.lang.types.NamespaceType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.Variance;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
@@ -52,13 +46,23 @@ public class JetStandardClasses {
public static final ModuleDescriptor FAKE_STANDARD_CLASSES_MODULE = new ModuleDescriptor("<builtin>"); public static final ModuleDescriptor FAKE_STANDARD_CLASSES_MODULE = new ModuleDescriptor("<builtin>");
private static final NamespaceDescriptorImpl STANDARD_CLASSES_FAKE_ROOT_NS = new NamespaceDescriptorImpl(FAKE_STANDARD_CLASSES_MODULE, Collections.<AnnotationDescriptor>emptyList(), "<root>"); private static final NamespaceDescriptorImpl STANDARD_CLASSES_FAKE_ROOT_NS = new NamespaceDescriptorImpl(
FAKE_STANDARD_CLASSES_MODULE, Collections.<AnnotationDescriptor>emptyList(), FqNameUnsafe.ROOT_NAME);
static { static {
FAKE_STANDARD_CLASSES_MODULE.setRootNs(STANDARD_CLASSES_FAKE_ROOT_NS); FAKE_STANDARD_CLASSES_MODULE.setRootNs(STANDARD_CLASSES_FAKE_ROOT_NS);
//WritableScopeImpl writableScope =
// new WritableScopeImpl(JetScope.EMPTY, FAKE_STANDARD_CLASSES_MODULE, RedeclarationHandler.DO_NOTHING);
//STANDARD_CLASSES_FAKE_ROOT_NS.initialize(writableScope);
//STANDARD_CLASSES_FAKE_ROOT_NS.getMemberScope().changeLockLevel(WritableScope.LockLevel.BOTH);
} }
public static NamespaceDescriptorImpl STANDARD_CLASSES_NAMESPACE = new NamespaceDescriptorImpl(STANDARD_CLASSES_FAKE_ROOT_NS, Collections.<AnnotationDescriptor>emptyList(), "jet"); public static NamespaceDescriptorImpl STANDARD_CLASSES_NAMESPACE = new NamespaceDescriptorImpl(
STANDARD_CLASSES_FAKE_ROOT_NS, Collections.<AnnotationDescriptor>emptyList(), "jet");
//
//static {
// STANDARD_CLASSES_FAKE_ROOT_NS.getMemberScope().addNamespace(STANDARD_CLASSES_NAMESPACE);
//}
public static final FqName STANDARD_CLASSES_FQNAME = DescriptorUtils.getFQName(STANDARD_CLASSES_NAMESPACE).toSafe(); public static final FqName STANDARD_CLASSES_FQNAME = DescriptorUtils.getFQName(STANDARD_CLASSES_NAMESPACE).toSafe();
@@ -76,7 +76,7 @@ public class JetDefaultModalityModifiersTest extends JetLiteFixture {
} }
private MutableClassDescriptor createClassDescriptor(ClassKind kind, JetClass aClass) { private MutableClassDescriptor createClassDescriptor(ClassKind kind, JetClass aClass) {
MutableClassDescriptor classDescriptor = new MutableClassDescriptor(JetTestUtils.DUMMY_TRACE, root, scope, kind); MutableClassDescriptor classDescriptor = new MutableClassDescriptor(root, scope, kind, aClass.getName());
descriptorResolver.resolveMutableClassDescriptor(aClass, classDescriptor, JetTestUtils.DUMMY_TRACE); descriptorResolver.resolveMutableClassDescriptor(aClass, classDescriptor, JetTestUtils.DUMMY_TRACE);
return classDescriptor; return classDescriptor;
} }