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.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiAnnotation;
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 com.intellij.psi.*;
import jet.typeinfo.TypeInfoVariance;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
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.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
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.*;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
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 javax.inject.Inject;
import java.util.ArrayList;
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;
import java.util.*;
/**
* @author abreslav
@@ -541,7 +474,7 @@ public class JavaDescriptorResolver {
MutableClassDescriptorLite classObject = createClassObjectDescriptor(classData.classDescriptor, psiClass);
if (classObject != null) {
classData.classDescriptor.setClassObjectDescriptor(classObject);
classData.classDescriptor.getBuilder().setClassObjectDescriptor(classObject);
}
trace.record(BindingContext.CLASS, psiClass, classData.classDescriptor);
@@ -605,7 +538,8 @@ public class JavaDescriptorResolver {
checkPsiClassIsNotJet(psiClass);
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);
@@ -994,7 +928,7 @@ public class JavaDescriptorResolver {
JavaNamespaceDescriptor ns = new JavaNamespaceDescriptor(
parentNs,
Collections.<AnnotationDescriptor>emptyList(), // TODO
qualifiedName.isRoot() ? "<root>" : qualifiedName.shortName(),
qualifiedName.isRoot() ? FqNameUnsafe.ROOT_NAME : qualifiedName.shortName(),
qualifiedName
);
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
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.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.FqName;
@@ -49,6 +48,8 @@ public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl {
return memberScope;
}
@NotNull
@Override
public FqName getQualifiedName() {
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 WritableScope scopeForInitializers = null; //contains members + primary constructor value parameters + map for backing fields
public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetScope outerScope, ClassKind kind) {
public MutableClassDescriptor(@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetScope outerScope, ClassKind kind, String name) {
super(containingDeclaration, kind);
RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING;
@@ -64,38 +64,13 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
if (getKind() == ClassKind.TRAIT) {
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
public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, @NotNull BindingTrace 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
public Set<SimpleFunctionDescriptor> getFunctions() {
return functions;
@@ -154,11 +107,6 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
}
@Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
super.addClassifierDescriptor(classDescriptor);
scopeForMemberResolution.addClassifierDescriptor(classDescriptor);
}
public void setTypeParameterDescriptors(List<TypeParameterDescriptor> typeParameters) {
super.setTypeParameterDescriptors(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);
}
@Override
public void lockScopes() {
super.lockScopes();
scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING);
@@ -214,4 +163,81 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite {
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
*/
public class MutableClassDescriptorLite extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLikeBuilder {
public class MutableClassDescriptorLite extends MutableDeclarationDescriptor
implements ClassDescriptor, WithDeferredResolve {
private ConstructorDescriptor primaryConstructor;
private final Set<ConstructorDescriptor> constructors = Sets.newLinkedHashSet();
@@ -60,11 +61,21 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
private ClassReceiver implicitReceiver;
public MutableClassDescriptorLite(@NotNull DeclarationDescriptor containingDeclaration, ClassKind kind) {
public MutableClassDescriptorLite(@NotNull DeclarationDescriptor containingDeclaration,
@NotNull ClassKind kind) {
super(containingDeclaration);
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) {
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
@Override
public TypeConstructor getTypeConstructor() {
@@ -258,20 +246,7 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
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
@Override
@@ -279,11 +254,6 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
return innerClassesScope;
}
@Override
public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) {
getScopeForMemberLookupAsWritableScope().addObjectDescriptor(objectDescriptor);
}
public void addSupertype(@NotNull JetType supertype) {
if (!ErrorUtils.isErrorType(supertype)) {
if (TypeUtils.getClassDescriptor(supertype) != null) {
@@ -341,4 +311,59 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
public void setAnnotations(List<AnnotationDescriptor> 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
*/
public interface NamespaceDescriptor extends Annotated, Named, ClassOrNamespaceDescriptor, NamespaceDescriptorParent {
public interface NamespaceDescriptor extends Annotated, Named, FqNamed, ClassOrNamespaceDescriptor, NamespaceDescriptorParent {
@NotNull
JetScope getMemberScope();
@@ -17,7 +17,10 @@
package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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 java.util.List;
@@ -25,7 +28,7 @@ import java.util.List;
/**
* @author abreslav
*/
public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl implements NamespaceLikeBuilder {
public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl implements WithDeferredResolve {
private WritableScope memberScope;
@@ -36,13 +39,11 @@ public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl imp
}
public void initialize(@NotNull WritableScope memberScope) {
this.memberScope = memberScope;
}
if (this.memberScope != null) {
throw new IllegalStateException("Namespace member scope reinitialize");
}
@NotNull
@Override
public DeclarationDescriptor getOwnerForChildren() {
return this;
this.memberScope = memberScope;
}
@Override
@@ -51,37 +52,64 @@ public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl imp
return memberScope;
}
public NamespaceDescriptorImpl getNamespace(String name) {
return (NamespaceDescriptorImpl) memberScope.getDeclaredNamespace(name);
}
@Override
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
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
memberScope.addClassifierDescriptor(classDescriptor);
public void forceResolve() {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) {
memberScope.addObjectDescriptor(objectDescriptor);
}
@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");
public boolean isAlreadyResolved() {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
}
@@ -34,9 +34,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.lang.diagnostics.Errors.CONSTRUCTOR_IN_TRAIT;
import static org.jetbrains.jet.lang.diagnostics.Errors.REDECLARATION;
import static org.jetbrains.jet.lang.diagnostics.Errors.SECONDARY_CONSTRUCTORS_ARE_NOT_SUPPORTED;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
/**
* @author abreslav
@@ -127,7 +125,7 @@ public class DeclarationResolver {
for (Map.Entry<JetFile, WritableScope> entry : context.getNamespaceScopes().entrySet()) {
JetFile namespace = entry.getKey();
WritableScope namespaceScope = entry.getValue();
NamespaceLikeBuilder namespaceDescriptor = context.getNamespaceDescriptors().get(namespace);
NamespaceLikeBuilder namespaceDescriptor = context.getNamespaceDescriptors().get(namespace).getBuilder();
resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceScope, namespaceScope, namespaceDescriptor);
}
@@ -135,13 +133,14 @@ public class DeclarationResolver {
JetClass jetClass = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
resolveFunctionAndPropertyHeaders(jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(),
resolveFunctionAndPropertyHeaders(
jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(),
classDescriptor.getScopeForInitializers(), classDescriptor.getScopeForMemberResolution(),
classDescriptor);
// processPrimaryConstructor(classDescriptor, jetClass);
// for (JetSecondaryConstructor jetConstructor : jetClass.getSecondaryConstructors()) {
// processSecondaryConstructor(classDescriptor, jetConstructor);
// }
classDescriptor.getBuilder());
// processPrimaryConstructor(classDescriptor, jetClass);
// for (JetSecondaryConstructor jetConstructor : jetClass.getSecondaryConstructors()) {
// processSecondaryConstructor(classDescriptor, jetConstructor);
// }
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
JetObjectDeclaration object = entry.getKey();
@@ -149,7 +148,7 @@ public class DeclarationResolver {
resolveFunctionAndPropertyHeaders(object.getDeclarations(), classDescriptor.getScopeForMemberResolution(),
classDescriptor.getScopeForInitializers(), classDescriptor.getScopeForMemberResolution(),
classDescriptor);
classDescriptor.getBuilder());
}
// TODO : Extensions
@@ -186,17 +185,22 @@ public class DeclarationResolver {
@Override
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);
}
@Override
public void visitEnumEntry(JetEnumEntry enumEntry) {
if (enumEntry.getPrimaryConstructorParameterList() == null) {
MutableClassDescriptorLite classObjectDescriptor = ((MutableClassDescriptor) namespaceLike).getClassObjectDescriptor();
// FIX: Bad cast
MutableClassDescriptorLite classObjectDescriptor =
((MutableClassDescriptorLite)namespaceLike.getOwnerForChildren()).getClassObjectDescriptor();
assert classObjectDescriptor != null;
PropertyDescriptor propertyDescriptor = descriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(classObjectDescriptor, enumEntry, context.getClasses().get(enumEntry), trace);
classObjectDescriptor.addPropertyDescriptor(propertyDescriptor);
PropertyDescriptor propertyDescriptor = descriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(
classObjectDescriptor, enumEntry, context.getClasses().get(enumEntry), trace);
classObjectDescriptor.getBuilder().addPropertyDescriptor(propertyDescriptor);
}
}
});
@@ -222,7 +226,7 @@ public class DeclarationResolver {
memberScope,
parameter, trace
);
classDescriptor.addPropertyDescriptor(propertyDescriptor);
classDescriptor.getBuilder().addPropertyDescriptor(propertyDescriptor);
context.getPrimaryConstructorParameterProperties().put(parameter, propertyDescriptor);
}
}
@@ -72,7 +72,7 @@ public class DelegationResolver {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) declarationDescriptor;
if (propertyDescriptor.getModality().isOverridable()) {
PropertyDescriptor copy = propertyDescriptor.copy(classDescriptor, true, CallableMemberDescriptor.Kind.DELEGATION, true);
classDescriptor.addPropertyDescriptor(copy);
classDescriptor.getBuilder().addPropertyDescriptor(copy);
trace.record(DELEGATED, copy);
}
}
@@ -80,7 +80,7 @@ public class DelegationResolver {
SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) declarationDescriptor;
if (functionDescriptor.getModality().isOverridable()) {
SimpleFunctionDescriptor copy = functionDescriptor.copy(classDescriptor, true, CallableMemberDescriptor.Kind.DELEGATION, true);
classDescriptor.addFunctionDescriptor(copy);
classDescriptor.getBuilder().addFunctionDescriptor(copy);
trace.record(DELEGATED, copy);
}
}
@@ -29,6 +29,8 @@ import java.util.List;
*/
public class FqNameUnsafe {
public static final String ROOT_NAME = "<root>";
@NotNull
private final String fqName;
@@ -246,7 +248,7 @@ public class FqNameUnsafe {
@Override
public String toString() {
return isRoot() ? "<root>" : fqName;
return isRoot() ? ROOT_NAME : fqName;
}
@Override
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.ModuleConfiguration;
@@ -61,14 +62,17 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
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();
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) {
throw new IllegalStateException("must be initialized 5 lines above");
}
@@ -77,7 +81,7 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
String namespaceName = JetPsiUtil.safeName(nameExpression.getReferencedName());
NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorIfNeeded(
null, currentOwner, namespaceName, false, nameExpression);
null, currentOwner, namespaceName, nameExpression, handler);
trace.record(BindingContext.NAMESPACE_IS_SRC, namespaceDescriptor, true);
trace.record(RESOLUTION_SCOPE, nameExpression, outerScope);
@@ -89,13 +93,14 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
NamespaceDescriptorImpl namespaceDescriptor;
String name;
if (namespaceHeader.isRoot()) {
// again to register file in trace
namespaceDescriptor = createNamespaceDescriptorIfNeeded(file, moduleDescriptor, "<root>", true, null);
// previous call to createRootNamespaceDescriptorIfNeeded couldn't store occurrence for current file.
namespaceDescriptor = moduleDescriptor.getRootNs();
storeBindingForFileAndExpression(file, null, namespaceDescriptor);
}
else {
name = namespaceHeader.getName();
namespaceDescriptor = createNamespaceDescriptorIfNeeded(file, currentOwner, name, namespaceHeader.isRoot(),
namespaceHeader.getLastPartExpression());
namespaceDescriptor = createNamespaceDescriptorIfNeeded(
file, currentOwner, name, namespaceHeader.getLastPartExpression(), handler);
trace.record(BindingContext.NAMESPACE_IS_SRC, namespaceDescriptor, true);
trace.record(RESOLUTION_SCOPE, namespaceHeader, outerScope);
@@ -107,49 +112,95 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
@Override
@NotNull
public NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(@NotNull FqName fqName) {
NamespaceDescriptorParent owner = moduleDescriptor;
NamespaceDescriptorImpl owner = null;
for (FqName pathElement : fqName.path()) {
owner = createNamespaceDescriptorIfNeeded(null,
owner, pathElement.isRoot() ? "<root>" : pathElement.shortName(), pathElement.isRoot(), null);
if (pathElement.isRoot()) {
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
public NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file,
@NotNull NamespaceDescriptorParent owner, @NotNull String name, boolean root, @Nullable JetReferenceExpression expression) {
FqName fqName;
NamespaceDescriptorImpl namespaceDescriptor;
if (root) {
if (!(owner instanceof ModuleDescriptor)) {
throw new IllegalStateException();
}
fqName = FqName.ROOT;
namespaceDescriptor = ((ModuleDescriptor) owner).getRootNs();
}
else {
FqName ownerFqName = DescriptorUtils.getFQName(owner).toSafe();
fqName = ownerFqName.child(name);
namespaceDescriptor = ((NamespaceDescriptorImpl) owner).getNamespace(name);
}
private NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file,
@NotNull NamespaceDescriptorImpl owner,
@NotNull String name,
@Nullable JetReferenceExpression expression,
@NotNull RedeclarationHandler handler) {
FqName ownerFqName = DescriptorUtils.getFQName(owner).toSafe();
FqName fqName = ownerFqName.child(name);
// !!!
NamespaceDescriptorImpl namespaceDescriptor = (NamespaceDescriptorImpl) owner.getMemberScope().getDeclaredNamespace(name);
if (namespaceDescriptor == null) {
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, 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);
}
namespaceDescriptor = createNewNamespaceDescriptor(owner, name, expression, handler, fqName);
}
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) {
trace.record(REFERENCE_TARGET, expression, namespaceDescriptor);
}
@@ -166,9 +217,5 @@ public class NamespaceFactoryImpl implements NamespaceFactory {
files.add(file);
trace.record(BindingContext.NAMESPACE_TO_FILES, namespaceDescriptor, files);
}
return namespaceDescriptor;
}
}
@@ -138,10 +138,10 @@ public class OverrideResolver {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
if (fakeOverride instanceof PropertyDescriptor) {
classDescriptor.addPropertyDescriptor((PropertyDescriptor) fakeOverride);
classDescriptor.getBuilder().addPropertyDescriptor((PropertyDescriptor) fakeOverride);
}
else if (fakeOverride instanceof SimpleFunctionDescriptor) {
classDescriptor.addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
classDescriptor.getBuilder().addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
}
else {
throw new IllegalStateException(fakeOverride.getClass().getName());
@@ -16,7 +16,6 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
@@ -30,7 +29,6 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import javax.inject.Inject;
import java.io.PrintStream;
import java.util.Map;
import java.util.Set;
/**
* @author abreslav
@@ -39,7 +37,6 @@ public class TopDownAnalysisContext {
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
protected final Map<JetFile, WritableScope> namespaceScopes = Maps.newHashMap();
private JetScope rootScope;
protected final Map<JetFile, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
@@ -50,6 +47,13 @@ public class TopDownAnalysisContext {
private final Map<JetParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap();
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;
@@ -68,7 +72,7 @@ public class TopDownAnalysisContext {
debugOutput.append(message).append("\n");
}
}
/*package*/ void enableDebugOutput() {
if (debugOutput == null) {
debugOutput = new StringBuilder();
@@ -199,7 +199,7 @@ public class TopDownAnalyzer {
}
// context.getDeclaringScopes().put(file, outerScope);
doProcess(outerScope, standardLibraryNamespace, toAnalyze);
doProcess(outerScope, standardLibraryNamespace.getBuilder(), toAnalyze);
}
public static void processObject(
@@ -207,8 +207,8 @@ public class TopDownAnalyzer {
@NotNull final BindingTrace trace,
@NotNull JetScope outerScope,
@NotNull final DeclarationDescriptor containingDeclaration,
@NotNull JetObjectDeclaration object) {
@NotNull JetObjectDeclaration object
) {
ModuleDescriptor moduleDescriptor = new ModuleDescriptor("<dummy for object>");
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.psi.*;
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.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.lexer.JetTokens;
@@ -82,11 +86,42 @@ public class TypeHierarchyResolver {
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);
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();
@@ -106,105 +141,111 @@ public class TypeHierarchyResolver {
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 outerScopeForStatic,
@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) {
declaration.accept(new JetVisitorVoid() {
@Override
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);
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);
context.getNamespaceScopes().put(file, namespaceScope);
collectNamespacesAndClassifiers(namespaceScope, namespaceScope, namespaceDescriptor, file.getDeclarations());
prepareForDeferredCall(namespaceScope, namespaceDescriptor, file);
}
@Override
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);
if (klass.hasModifier(JetTokens.ENUM_KEYWORD)) {
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);
}
createClassObjectForEnumClass(klass, mutableClassDescriptor);
visitClassOrObject(klass, (Map) context.getClasses(), mutableClassDescriptor);
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
prepareForDeferredCall(classScope, mutableClassDescriptor, klass);
owner.addClassifierDescriptor(mutableClassDescriptor);
}
@Override
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);
}
@Override
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();
if (enumEntry.getPrimaryConstructorParameterList() == null) {
createClassDescriptorForObject(enumEntry, classObjectDescriptor, outerScopeForStatic, ClassKind.ENUM_ENTRY);
return;
// Simple enum entry
createClassDescriptorForEnumEntry(enumEntry, classObjectDescriptor.getBuilder());
}
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, classObjectDescriptor, outerScope, ClassKind.ENUM_ENTRY);
visitClassOrObject(
enumEntry,
(Map) context.getClasses(),
mutableClassDescriptor
);
classObjectDescriptor.addObjectDescriptor(mutableClassDescriptor);
}
else {
// Advanced enum entry like "Cons<out T>(val head : T, val tail : List<T>) : List<T>(tail.size + 1)"
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(
classObjectDescriptor, outerScope, ClassKind.ENUM_ENTRY, JetPsiUtil.safeName(enumEntry.getName()));
context.getClasses().put(enumEntry, mutableClassDescriptor);
private MutableClassDescriptor createClassDescriptorForObject(@NotNull JetClassOrObject declaration, @NotNull NamespaceLikeBuilder owner, JetScope scope, ClassKind classKind) {
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;
}
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
private void createPrimaryConstructorForObject(@Nullable JetDeclaration object, MutableClassDescriptor mutableClassDescriptor) {
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(mutableClassDescriptor, Collections.<AnnotationDescriptor>emptyList(), true);
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
Visibilities.INTERNAL);//TODO check set mutableClassDescriptor.getVisibility()
// TODO : make the constructor private?
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor, trace);
if (object != null) {
trace.record(CONSTRUCTOR, object, constructorDescriptor);
prepareForDeferredCall(classScope, mutableClassDescriptor, enumEntry);
classObjectDescriptor.getBuilder().addObjectDescriptor(mutableClassDescriptor);
}
}
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
public void visitTypedef(JetTypedef typedef) {
trace.report(UNSUPPORTED.on(typedef, "TypeHierarchyResolver"));
@@ -214,7 +255,8 @@ public class TypeHierarchyResolver {
public void visitClassObject(JetClassObject classObject) {
JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
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) {
case DUPLICATE:
trace.report(MANY_CLASS_OBJECTS.on(classObject));
@@ -222,15 +264,87 @@ public class TypeHierarchyResolver {
case NOT_ALLOWED:
trace.report(CLASS_OBJECT_NOT_ALLOWED.on(classObject));
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
private ClassKind getClassKind(@NotNull JetClass jetClass) {
private static ClassKind getClassKind(@NotNull JetClass jetClass) {
if (jetClass.isTrait()) return ClassKind.TRAIT;
if (jetClass.hasModifier(JetTokens.ANNOTATION_KEYWORD)) return ClassKind.ANNOTATION_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()) {
JetClass jetClass = entry.getKey();
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);
}
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)) {
return;
}
@@ -306,7 +423,10 @@ public class TypeHierarchyResolver {
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 (beingProcessed.contains(currentClass)) {
markCycleErrors(currentPath, currentClass);
@@ -314,7 +434,8 @@ public class TypeHierarchyResolver {
ClassDescriptor subclassOfCurrent = currentPath.get(currentPath.size() - 1);
assert subclassOfCurrent instanceof MutableClassDescriptor;
// 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();
if (type.getConstructor() == currentClass.getTypeConstructor()) {
iterator.remove();
@@ -340,11 +461,8 @@ public class TypeHierarchyResolver {
private void markCycleErrors(List<ClassDescriptor> currentPath, @NotNull ClassDescriptor current) {
int size = currentPath.size();
boolean found = false;
for (int i = 0; i < size; i++) {
for (int i = size - 1; i >= 0; i--) {
ClassDescriptor classDescriptor = currentPath.get(i);
if (classDescriptor == current) found = true;
if (!found) continue;
ClassDescriptor superclass = (i < size - 1) ? currentPath.get(i + 1) : current;
PsiElement psiElement = BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
@@ -371,6 +489,11 @@ public class TypeHierarchyResolver {
if (elementToMark != null) {
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) {
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
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();
assert delegationSpecifierList != null;
// 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.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));
}
}
}
@@ -484,4 +610,4 @@ public class TypeHierarchyResolver {
}
}
}
}
}
@@ -18,23 +18,17 @@ package org.jetbrains.jet.lang.types.lang;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
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.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.scopes.*;
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.types.JetType;
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 org.jetbrains.jet.lang.types.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -52,13 +46,23 @@ public class JetStandardClasses {
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 {
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();
@@ -76,7 +76,7 @@ public class JetDefaultModalityModifiersTest extends JetLiteFixture {
}
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);
return classDescriptor;
}