Thread-safe lazy values introduced into LazyClassDescriptor
This commit is contained in:
+158
-100
@@ -16,17 +16,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.lazy;
|
package org.jetbrains.jet.lang.resolve.lazy;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.intellij.openapi.util.Computable;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.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.*;
|
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.data.FilteringClassLikeInfo;
|
import org.jetbrains.jet.lang.resolve.lazy.data.FilteringClassLikeInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil;
|
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo;
|
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo;
|
||||||
@@ -64,17 +69,16 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
private final ClassKind kind;
|
private final ClassKind kind;
|
||||||
private final boolean isInner;
|
private final boolean isInner;
|
||||||
|
|
||||||
private ReceiverParameterDescriptor thisAsReceiverParameter;
|
private final LazyValue<ReceiverParameterDescriptor> thisAsReceiverParameter;
|
||||||
private List<AnnotationDescriptor> annotations;
|
private final LazyValue<List<AnnotationDescriptor>> annotations;
|
||||||
private ClassDescriptor classObjectDescriptor;
|
private final LazyValue<Optional<ClassDescriptor>> classObjectDescriptor;
|
||||||
private boolean classObjectDescriptorResolved = false;
|
|
||||||
|
|
||||||
private final LazyClassMemberScope unsubstitutedMemberScope;
|
private final LazyClassMemberScope unsubstitutedMemberScope;
|
||||||
private final JetScope unsubstitutedInnerClassesScope;
|
private final JetScope unsubstitutedInnerClassesScope;
|
||||||
|
|
||||||
private JetScope scopeForClassHeaderResolution;
|
private final LazyValue<JetScope> scopeForClassHeaderResolution;
|
||||||
private JetScope scopeForMemberDeclarationResolution;
|
private final LazyValue<JetScope> scopeForMemberDeclarationResolution;
|
||||||
private JetScope scopeForPropertyInitializerResolution;
|
private final LazyValue<JetScope> scopeForPropertyInitializerResolution;
|
||||||
|
|
||||||
|
|
||||||
public LazyClassDescriptor(
|
public LazyClassDescriptor(
|
||||||
@@ -111,6 +115,44 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
}
|
}
|
||||||
this.visibility = resolveVisibilityFromModifiers(modifierList, getDefaultClassVisibility(this));
|
this.visibility = resolveVisibilityFromModifiers(modifierList, getDefaultClassVisibility(this));
|
||||||
this.isInner = isInnerClass(modifierList);
|
this.isInner = isInnerClass(modifierList);
|
||||||
|
|
||||||
|
StorageManager storageManager = resolveSession.getStorageManager();
|
||||||
|
this.thisAsReceiverParameter = storageManager.createLazyValue(new Computable<ReceiverParameterDescriptor>() {
|
||||||
|
@Override
|
||||||
|
public ReceiverParameterDescriptor compute() {
|
||||||
|
return DescriptorResolver.createLazyReceiverParameterDescriptor(LazyClassDescriptor.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.annotations = storageManager.createLazyValue(new Computable<List<AnnotationDescriptor>>() {
|
||||||
|
@Override
|
||||||
|
public List<AnnotationDescriptor> compute() {
|
||||||
|
return resolveAnnotations();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.classObjectDescriptor = storageManager.createLazyValue(new Computable<Optional<ClassDescriptor>>() {
|
||||||
|
@Override
|
||||||
|
public Optional<ClassDescriptor> compute() {
|
||||||
|
return Optional.fromNullable(computeClassObjectDescriptor());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.scopeForClassHeaderResolution = storageManager.createLazyValue(new Computable<JetScope>() {
|
||||||
|
@Override
|
||||||
|
public JetScope compute() {
|
||||||
|
return computeScopeForClassHeaderResolution();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.scopeForMemberDeclarationResolution = storageManager.createLazyValue(new Computable<JetScope>() {
|
||||||
|
@Override
|
||||||
|
public JetScope compute() {
|
||||||
|
return computeScopeForMemberDeclarationResolution();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.scopeForPropertyInitializerResolution = storageManager.createLazyValue(new Computable<JetScope>() {
|
||||||
|
@Override
|
||||||
|
public JetScope compute() {
|
||||||
|
return computeScopeForPropertyInitializerResolution();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -126,59 +168,67 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetScope getScopeForClassHeaderResolution() {
|
public JetScope getScopeForClassHeaderResolution() {
|
||||||
if (scopeForClassHeaderResolution == null) {
|
return scopeForClassHeaderResolution.get();
|
||||||
WritableScopeImpl scope = new WritableScopeImpl(
|
|
||||||
JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Class Header Resolution");
|
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
|
|
||||||
scope.addClassifierDescriptor(typeParameterDescriptor);
|
|
||||||
}
|
|
||||||
scope.changeLockLevel(WritableScope.LockLevel.READING);
|
|
||||||
|
|
||||||
PsiElement scopeAnchor = declarationProvider.getOwnerInfo().getScopeAnchor();
|
|
||||||
scopeForClassHeaderResolution = new ChainedScope(
|
|
||||||
this,
|
|
||||||
"ScopeForClassHeaderResolution: " + getName(),
|
|
||||||
scope, getScopeProvider().getResolutionScopeForDeclaration(scopeAnchor));
|
|
||||||
}
|
|
||||||
return scopeForClassHeaderResolution;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JetScope computeScopeForClassHeaderResolution() {
|
||||||
|
WritableScopeImpl scope = new WritableScopeImpl(
|
||||||
|
JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Class Header Resolution");
|
||||||
|
for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
|
||||||
|
scope.addClassifierDescriptor(typeParameterDescriptor);
|
||||||
|
}
|
||||||
|
scope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||||
|
|
||||||
|
PsiElement scopeAnchor = declarationProvider.getOwnerInfo().getScopeAnchor();
|
||||||
|
return new ChainedScope(
|
||||||
|
this,
|
||||||
|
"ScopeForClassHeaderResolution: " + getName(),
|
||||||
|
scope, getScopeProvider().getResolutionScopeForDeclaration(scopeAnchor));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public JetScope getScopeForMemberDeclarationResolution() {
|
public JetScope getScopeForMemberDeclarationResolution() {
|
||||||
if (scopeForMemberDeclarationResolution == null) {
|
return scopeForMemberDeclarationResolution.get();
|
||||||
WritableScopeImpl scope = new WritableScopeImpl(
|
|
||||||
JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Member Declaration Resolution");
|
|
||||||
scope.addLabeledDeclaration(this);
|
|
||||||
scope.changeLockLevel(WritableScope.LockLevel.READING);
|
|
||||||
|
|
||||||
scopeForMemberDeclarationResolution = new ChainedScope(
|
|
||||||
this,
|
|
||||||
"ScopeForMemberDeclarationResolution: " + getName(),
|
|
||||||
scope, getScopeForMemberLookup(), getScopeForClassHeaderResolution());
|
|
||||||
}
|
|
||||||
return scopeForMemberDeclarationResolution;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JetScope computeScopeForMemberDeclarationResolution() {
|
||||||
|
WritableScopeImpl scope = new WritableScopeImpl(
|
||||||
|
JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Member Declaration Resolution");
|
||||||
|
scope.addLabeledDeclaration(this);
|
||||||
|
scope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||||
|
|
||||||
|
return new ChainedScope(
|
||||||
|
this,
|
||||||
|
"ScopeForMemberDeclarationResolution: " + getName(),
|
||||||
|
scope, getScopeForMemberLookup(), getScopeForClassHeaderResolution());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public JetScope getScopeForPropertyInitializerResolution() {
|
public JetScope getScopeForPropertyInitializerResolution() {
|
||||||
|
return scopeForPropertyInitializerResolution.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JetScope computeScopeForPropertyInitializerResolution() {
|
||||||
ConstructorDescriptor primaryConstructor = getUnsubstitutedPrimaryConstructor();
|
ConstructorDescriptor primaryConstructor = getUnsubstitutedPrimaryConstructor();
|
||||||
if (primaryConstructor == null) return getScopeForMemberDeclarationResolution();
|
if (primaryConstructor == null) return getScopeForMemberDeclarationResolution();
|
||||||
|
|
||||||
if (scopeForPropertyInitializerResolution == null) {
|
WritableScopeImpl scope = new WritableScopeImpl(
|
||||||
WritableScopeImpl scope = new WritableScopeImpl(
|
JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Property Initializer Resolution");
|
||||||
JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Property Initializer Resolution");
|
|
||||||
|
|
||||||
List<ValueParameterDescriptor> parameters = primaryConstructor.getValueParameters();
|
List<ValueParameterDescriptor> parameters = primaryConstructor.getValueParameters();
|
||||||
for (ValueParameterDescriptor valueParameterDescriptor : parameters) {
|
for (ValueParameterDescriptor valueParameterDescriptor : parameters) {
|
||||||
scope.addVariableDescriptor(valueParameterDescriptor);
|
scope.addVariableDescriptor(valueParameterDescriptor);
|
||||||
}
|
|
||||||
|
|
||||||
scope.changeLockLevel(WritableScope.LockLevel.READING);
|
|
||||||
|
|
||||||
scopeForPropertyInitializerResolution = new ChainedScope(
|
|
||||||
this,
|
|
||||||
"ScopeForPropertyInitializerResolution: " + getName(),
|
|
||||||
scope, getScopeForMemberDeclarationResolution());
|
|
||||||
}
|
}
|
||||||
return scopeForPropertyInitializerResolution;
|
|
||||||
|
scope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||||
|
|
||||||
|
return new ChainedScope(
|
||||||
|
this,
|
||||||
|
"ScopeForPropertyInitializerResolution: " + getName(),
|
||||||
|
scope, getScopeForMemberDeclarationResolution());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -223,16 +273,18 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClassObjectDescriptor() {
|
public ClassDescriptor getClassObjectDescriptor() {
|
||||||
if (!classObjectDescriptorResolved) {
|
return classObjectDescriptor.get().orNull();
|
||||||
JetClassObject classObject = declarationProvider.getOwnerInfo().getClassObject();
|
}
|
||||||
|
|
||||||
JetClassLikeInfo classObjectInfo = getClassObjectInfo(classObject);
|
@Nullable
|
||||||
if (classObjectInfo != null) {
|
private ClassDescriptor computeClassObjectDescriptor() {
|
||||||
classObjectDescriptor = new LazyClassDescriptor(resolveSession, this, getClassObjectName(getName()), classObjectInfo);
|
JetClassObject classObject = declarationProvider.getOwnerInfo().getClassObject();
|
||||||
}
|
|
||||||
classObjectDescriptorResolved = true;
|
JetClassLikeInfo classObjectInfo = getClassObjectInfo(classObject);
|
||||||
|
if (classObjectInfo != null) {
|
||||||
|
return new LazyClassDescriptor(resolveSession, this, getClassObjectName(getName()), classObjectInfo);
|
||||||
}
|
}
|
||||||
return classObjectDescriptor;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -281,27 +333,26 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ReceiverParameterDescriptor getThisAsReceiverParameter() {
|
public ReceiverParameterDescriptor getThisAsReceiverParameter() {
|
||||||
if (thisAsReceiverParameter == null) {
|
return thisAsReceiverParameter.get();
|
||||||
thisAsReceiverParameter = DescriptorResolver.createLazyReceiverParameterDescriptor(this);
|
|
||||||
}
|
|
||||||
return thisAsReceiverParameter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AnnotationDescriptor> getAnnotations() {
|
public List<AnnotationDescriptor> getAnnotations() {
|
||||||
if (annotations == null) {
|
return annotations.get();
|
||||||
JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
|
}
|
||||||
JetModifierList modifierList = classInfo.getModifierList();
|
|
||||||
if (modifierList != null) {
|
@NotNull
|
||||||
AnnotationResolver annotationResolver = resolveSession.getInjector().getAnnotationResolver();
|
private List<AnnotationDescriptor> resolveAnnotations() {
|
||||||
JetScope scopeForDeclaration = getScopeProvider().getResolutionScopeForDeclaration(classInfo.getScopeAnchor());
|
JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
|
||||||
annotations = annotationResolver.resolveAnnotations(scopeForDeclaration, modifierList, resolveSession.getTrace());
|
JetModifierList modifierList = classInfo.getModifierList();
|
||||||
}
|
if (modifierList != null) {
|
||||||
else {
|
AnnotationResolver annotationResolver = resolveSession.getInjector().getAnnotationResolver();
|
||||||
annotations = Collections.emptyList();
|
JetScope scopeForDeclaration = getScopeProvider().getResolutionScopeForDeclaration(classInfo.getScopeAnchor());
|
||||||
}
|
return annotationResolver.resolveAnnotations(scopeForDeclaration, modifierList, resolveSession.getTrace());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return annotations;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -339,35 +390,16 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class LazyClassTypeConstructor implements LazyDescriptor, TypeConstructor {
|
private class LazyClassTypeConstructor implements LazyDescriptor, TypeConstructor {
|
||||||
private Collection<JetType> supertypes = null;
|
private final LazyValue<Collection<JetType>> supertypes = resolveSession.getStorageManager().createLazyValue(new Computable<Collection<JetType>>() {
|
||||||
private List<TypeParameterDescriptor> parameters = null;
|
@Override
|
||||||
|
public Collection<JetType> compute() {
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<TypeParameterDescriptor> getParameters() {
|
|
||||||
if (parameters == null) {
|
|
||||||
JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
|
|
||||||
List<JetTypeParameter> typeParameters = classInfo.getTypeParameters();
|
|
||||||
parameters = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
|
|
||||||
|
|
||||||
for (int i = 0; i < typeParameters.size(); i++) {
|
|
||||||
parameters.add(new LazyTypeParameterDescriptor(resolveSession, LazyClassDescriptor.this, typeParameters.get(i), i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Collection<JetType> getSupertypes() {
|
|
||||||
if (supertypes == null) {
|
|
||||||
if (resolveSession.isClassSpecial(DescriptorUtils.getFQName(LazyClassDescriptor.this))) {
|
if (resolveSession.isClassSpecial(DescriptorUtils.getFQName(LazyClassDescriptor.this))) {
|
||||||
this.supertypes = Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetClassOrObject classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject();
|
JetClassOrObject classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject();
|
||||||
if (classOrObject == null) {
|
if (classOrObject == null) {
|
||||||
this.supertypes = Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
List<JetType> allSupertypes = resolveSession.getInjector().getDescriptorResolver()
|
List<JetType> allSupertypes = resolveSession.getInjector().getDescriptorResolver()
|
||||||
@@ -375,12 +407,38 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc
|
|||||||
LazyClassDescriptor.this, classOrObject,
|
LazyClassDescriptor.this, classOrObject,
|
||||||
resolveSession.getTrace());
|
resolveSession.getTrace());
|
||||||
List<JetType> validSupertypes = Lists.newArrayList(Collections2.filter(allSupertypes, VALID_SUPERTYPE));
|
List<JetType> validSupertypes = Lists.newArrayList(Collections2.filter(allSupertypes, VALID_SUPERTYPE));
|
||||||
this.supertypes = validSupertypes;
|
|
||||||
findAndDisconnectLoopsInTypeHierarchy(validSupertypes);
|
findAndDisconnectLoopsInTypeHierarchy(validSupertypes);
|
||||||
|
return validSupertypes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return supertypes;
|
});
|
||||||
|
private final LazyValue<List<TypeParameterDescriptor>> parameters = resolveSession.getStorageManager().createLazyValue(new Computable<List<TypeParameterDescriptor>>() {
|
||||||
|
@Override
|
||||||
|
public List<TypeParameterDescriptor> compute() {
|
||||||
|
JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
|
||||||
|
List<JetTypeParameter> typeParameters = classInfo.getTypeParameters();
|
||||||
|
|
||||||
|
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
|
||||||
|
for (int i = 0; i < typeParameters.size(); i++) {
|
||||||
|
parameters.add(new LazyTypeParameterDescriptor(resolveSession, LazyClassDescriptor.this, typeParameters.get(i), i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<TypeParameterDescriptor> getParameters() {
|
||||||
|
return parameters.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<JetType> getSupertypes() {
|
||||||
|
return supertypes.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findAndDisconnectLoopsInTypeHierarchy(List<JetType> supertypes) {
|
private void findAndDisconnectLoopsInTypeHierarchy(List<JetType> supertypes) {
|
||||||
|
|||||||
Reference in New Issue
Block a user