diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java new file mode 100644 index 00000000000..5fbe1e78c5d --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java @@ -0,0 +1,46 @@ +/* + * 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.resolve.lazy; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.types.TypeConstructor; + +public class ForceResolveUtil { + private ForceResolveUtil() {} + + public static void forceResolveAllContents(@NotNull DeclarationDescriptor descriptor) { + if (descriptor instanceof LazyDescriptor) { + LazyDescriptor lazyDescriptor = (LazyDescriptor) descriptor; + lazyDescriptor.forceResolveAllContents(); + } + } + + public static void forceResolveAllContents(@NotNull JetScope scope) { + for (DeclarationDescriptor descriptor : scope.getAllDescriptors()) { + forceResolveAllContents(descriptor); + } + } + + public static void forceResolveAllContents(@NotNull TypeConstructor typeConstructor) { + if (typeConstructor instanceof LazyDescriptor) { + LazyDescriptor lazyConstructor = (LazyDescriptor) typeConstructor; + lazyConstructor.forceResolveAllContents(); + } + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java index 4486fc45424..3900ec1afde 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java @@ -49,7 +49,7 @@ import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName; /** * @author abreslav */ -public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDescriptorFromSource { +public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDescriptor, ClassDescriptorFromSource { private static final Predicate ONLY_ENUM_ENTRIES = Predicates.instanceOf(JetEnumEntry.class); private static final Predicate VALID_SUPERTYPE = new Predicate() { @@ -65,7 +65,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes private final Name name; private final DeclarationDescriptor containingDeclaration; - private final TypeConstructor typeConstructor; + private final LazyClassTypeConstructor typeConstructor; private final Modality modality; private final Visibility visibility; private final ClassKind kind; @@ -308,7 +308,30 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes return "lazy class " + getName().toString(); } - private class LazyClassTypeConstructor implements TypeConstructor { + @Override + public void forceResolveAllContents() { + getAnnotations(); + getClassObjectDescriptor(); + getClassObjectType(); + getConstructors(); + getContainingDeclaration(); + getImplicitReceiver(); + getKind(); + getModality(); + getName(); + getOriginal(); + getScopeForClassHeaderResolution(); + getScopeForMemberDeclarationResolution(); + ForceResolveUtil.forceResolveAllContents(getScopeForMemberLookup()); + getScopeForPropertyInitializerResolution(); + getUnsubstitutedInnerClassesScope(); + ForceResolveUtil.forceResolveAllContents(getTypeConstructor()); + getUnsubstitutedPrimaryConstructor(); + getVisibility(); + isClassObjectAValue(); + } + + private class LazyClassTypeConstructor implements LazyDescriptor, TypeConstructor { private Collection supertypes = null; private List parameters = null; @@ -395,6 +418,13 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes public String toString() { return LazyClassDescriptor.this.getName().toString(); } + + @Override + public void forceResolveAllContents() { + getAnnotations(); + getSupertypes(); + getParameters(); + } } private static JetClassLikeInfo noEnumEntries(JetClassLikeInfo classLikeInfo) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyDescriptor.java new file mode 100644 index 00000000000..9698c0a949d --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyDescriptor.java @@ -0,0 +1,21 @@ +/* + * 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.resolve.lazy; + +public interface LazyDescriptor { + void forceResolveAllContents(); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyPackageDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyPackageDescriptor.java index d8e44f28cd4..5882613558d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyPackageDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyPackageDescriptor.java @@ -31,8 +31,9 @@ import java.util.Collections; /** * @author abreslav */ -public class LazyPackageDescriptor extends AbstractNamespaceDescriptorImpl implements NamespaceDescriptor { +public class LazyPackageDescriptor extends AbstractNamespaceDescriptorImpl implements LazyDescriptor, NamespaceDescriptor { private final JetScope memberScope; + private final JetScope lazyScope; public LazyPackageDescriptor( @NotNull NamespaceDescriptorParent containingDeclaration, @@ -46,9 +47,9 @@ public class LazyPackageDescriptor extends AbstractNamespaceDescriptorImpl imple resolveSession.getModuleConfiguration().extendNamespaceScope(resolveSession.getTrace(), this, scope); scope.changeLockLevel(WritableScope.LockLevel.READING); - LazyPackageMemberScope lazyPackageMemberScope = new LazyPackageMemberScope(resolveSession, declarationProvider, this); + this.lazyScope = new LazyPackageMemberScope(resolveSession, declarationProvider, this); - this.memberScope = new ChainedScope(containingDeclaration, lazyPackageMemberScope, scope); + this.memberScope = new ChainedScope(this, lazyScope, scope); } @NotNull @@ -67,4 +68,9 @@ public class LazyPackageDescriptor extends AbstractNamespaceDescriptorImpl imple public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { throw new UnsupportedOperationException(); // TODO } + + @Override + public void forceResolveAllContents() { + ForceResolveUtil.forceResolveAllContents(lazyScope); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyTypeParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyTypeParameterDescriptor.java index 02cd7a5e37d..1ac60fe0a68 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyTypeParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyTypeParameterDescriptor.java @@ -43,7 +43,7 @@ import java.util.Set; /** * @author abreslav */ -public class LazyTypeParameterDescriptor implements TypeParameterDescriptor { +public class LazyTypeParameterDescriptor implements TypeParameterDescriptor, LazyDescriptor { private final ResolveSession resolveSession; private final SmartPsiElementPointer jetTypeParameterSmartPsiElementPointer; @@ -286,4 +286,20 @@ public class LazyTypeParameterDescriptor implements TypeParameterDescriptor { public String toString() { return getName().toString(); } + + @Override + public void forceResolveAllContents() { + getAnnotations(); + getClassObjectType(); + getContainingDeclaration(); + getDefaultType(); + getIndex(); + getLowerBounds(); + getLowerBoundsAsType(); + getOriginal(); + getTypeConstructor(); + getUpperBounds(); + getUpperBoundsAsType(); + getVariance(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java index a37def4e990..ec6e6643227 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java @@ -278,4 +278,44 @@ public class ResolveSession { } return actualName; } + + /** + * Forces all descriptors to be resolved. + * + * Use this method when laziness plays against you, e.g. when lazy descriptors may be accessed in a multi-threaded setting + */ + public void forceResolveAll() { + rootPackage.acceptVoid(new DeclarationDescriptorVisitorEmptyBodies() { + + @Override + public Void visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, Void data) { + ForceResolveUtil.forceResolveAllContents(descriptor); + return null; + } + + @Override + public Void visitNamespaceDescriptor(NamespaceDescriptor descriptor, Void data) { + ForceResolveUtil.forceResolveAllContents(descriptor); + return null; + } + + @Override + public Void visitClassDescriptor(ClassDescriptor descriptor, Void data) { + ForceResolveUtil.forceResolveAllContents(descriptor); + return null; + } + + @Override + public Void visitModuleDeclaration(ModuleDescriptor descriptor, Void data) { + ForceResolveUtil.forceResolveAllContents(descriptor); + return null; + } + + @Override + public Void visitScriptDescriptor(ScriptDescriptor scriptDescriptor, Void data) { + ForceResolveUtil.forceResolveAllContents(scriptDescriptor); + return null; + } + }); + } }