diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java index 893a528dd82..ad386182e74 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java @@ -18,14 +18,19 @@ package org.jetbrains.jet.di; import com.intellij.openapi.project.Project; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; +import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.resolve.TypeResolver; +import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider; import org.jetbrains.jet.lang.resolve.AnnotationResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver; import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; import com.intellij.openapi.project.Project; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; +import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.annotations.NotNull; import javax.annotation.PreDestroy; @@ -33,21 +38,29 @@ import javax.annotation.PreDestroy; public class InjectorForLazyResolve { private final Project project; + private final ResolveSession resolveSession; + private final BindingTrace bindingTrace; private DescriptorResolver descriptorResolver; private ExpressionTypingServices expressionTypingServices; private TypeResolver typeResolver; + private ScopeProvider scopeProvider; private AnnotationResolver annotationResolver; private CallResolver callResolver; private OverloadingConflictResolver overloadingConflictResolver; private QualifiedExpressionResolver qualifiedExpressionResolver; public InjectorForLazyResolve( - @NotNull Project project + @NotNull Project project, + @NotNull ResolveSession resolveSession, + @NotNull BindingTrace bindingTrace ) { this.project = project; + this.resolveSession = resolveSession; + this.bindingTrace = bindingTrace; this.descriptorResolver = new DescriptorResolver(); this.expressionTypingServices = new ExpressionTypingServices(); this.typeResolver = new TypeResolver(); + this.scopeProvider = new ScopeProvider(resolveSession); this.annotationResolver = new AnnotationResolver(); this.callResolver = new CallResolver(); this.overloadingConflictResolver = new OverloadingConflictResolver(); @@ -92,4 +105,8 @@ public class InjectorForLazyResolve { return this.typeResolver; } + public ScopeProvider getScopeProvider() { + return this.scopeProvider; + } + } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java index eee08283aed..23367be19d2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java @@ -99,8 +99,9 @@ public abstract class AbstractLazyMemberScope declarations = declarationProvider.getFunctionDeclarations(name); for (JetNamedFunction functionDeclaration : declarations) { JetScope resolutionScope = getScopeForMemberDeclarationResolution(functionDeclaration); - result.add(resolveSession.getDescriptorResolver().resolveFunctionDescriptor(thisDescriptor, resolutionScope, - functionDeclaration, resolveSession.getTrace())); + result.add(resolveSession.getInjector().getDescriptorResolver().resolveFunctionDescriptor(thisDescriptor, resolutionScope, + functionDeclaration, + resolveSession.getTrace())); } getNonDeclaredFunctions(name, result); @@ -130,8 +131,9 @@ public abstract class AbstractLazyMemberScope declarations = declarationProvider.getPropertyDeclarations(name); for (JetProperty propertyDeclaration : declarations) { JetScope resolutionScope = getScopeForMemberDeclarationResolution(propertyDeclaration); - result.add(resolveSession.getDescriptorResolver().resolvePropertyDescriptor(thisDescriptor, resolutionScope, - propertyDeclaration, resolveSession.getTrace())); + result.add(resolveSession.getInjector().getDescriptorResolver().resolvePropertyDescriptor(thisDescriptor, resolutionScope, + propertyDeclaration, + resolveSession.getTrace())); } getNonDeclaredProperties(name, result); 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 691ddcd436f..3ea27e13de1 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 @@ -247,10 +247,10 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes public Collection getSupertypes() { if (supertypes == null) { JetClassOrObject declaration = declarationProvider.getOwnerClassOrObject(); - this.supertypes = resolveSession.getDescriptorResolver() + this.supertypes = resolveSession.getInjector().getDescriptorResolver() .resolveSupertypes(getScopeForClassHeaderResolution(), - declaration, - resolveSession.getTrace()); + declaration, + resolveSession.getTrace()); } return supertypes; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java index cdc8e4eb42e..807aee4bac0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java @@ -16,15 +16,21 @@ package org.jetbrains.jet.lang.resolve.lazy; +import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.JetDeclaration; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.types.JetType; +import java.util.Collection; import java.util.Set; /** @@ -47,10 +53,33 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope result) { - JetClassOrObject owner = declarationProvider.getOwnerClassOrObject(); - //throw new UnsupportedOperationException(); // TODO - System.err.println("getNonDeclaredFunctions() should generate fake overrides for a class"); + protected void getNonDeclaredFunctions(@NotNull Name name, @NotNull final Set result) { + Collection fromSupertypes = Lists.newArrayList(); + for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) { + fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name)); + } + OverrideResolver.generateOverridesInFunctionGroup( + name, + fromSupertypes, + Lists.newArrayList(result), + thisDescriptor, + new OverrideResolver.DescriptorSink() { + @Override + public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) { + assert fakeOverride instanceof FunctionDescriptor : "A non-function overrides a function"; + result.add((FunctionDescriptor) fakeOverride); + } + + @Override + public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) { + BindingTrace trace = resolveSession.getTrace(); + JetDeclaration declaration = (JetDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), + fromCurrent); + assert declaration != null : "fromCurrent can not be a fake override"; + trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().getName())); + } + } + ); } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyPackageMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyPackageMemberScope.java index 0efbd11badb..b3c32c3eef8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyPackageMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyPackageMemberScope.java @@ -65,7 +65,8 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope() { + @Override + public boolean apply(@Nullable PsiFile file) { + throw new UnsupportedOperationException("This shouldn't be called from within lazy resolve"); + } + }, false, false, Collections.emptyList()); + + this.injector = new InjectorForLazyResolve(project, this, mockParameters, trace); this.module = rootDescriptor; DeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(FqName.ROOT); assert provider != null : "No declaration provider for root package in " + rootDescriptor; this.rootPackage = new LazyPackageDescriptor(rootDescriptor, JetPsiUtil.ROOT_NAMESPACE_NAME, this, provider); rootDescriptor.setRootNs(rootPackage); - this.scopeProvider = new ScopeProvider(this); this.declarationProviderFactory = declarationProviderFactory; } @NotNull - public DescriptorResolver getDescriptorResolver() { - return injector.getDescriptorResolver(); - } - - public TypeResolver getTypeResolver() { - return injector.getTypeResolver(); + public InjectorForLazyResolve getInjector() { + return injector; } @Nullable @@ -108,11 +108,6 @@ public class ResolveSession { throw new UnsupportedOperationException(); // TODO } - @NotNull - public ScopeProvider getScopeProvider() { - return scopeProvider; - } - public Collection getDescriptorsForDeclarations(Collection declarationsOrFiles) { final List descriptors = Lists.newArrayList(); for (PsiElement declarationOrFile : declarationsOrFiles) { @@ -135,7 +130,7 @@ public class ResolveSession { @Override public void visitDeclaration(JetDeclaration dcl) { - JetScope scope = scopeProvider.getResolutionScopeForDeclaration(dcl); + JetScope scope = injector.getScopeProvider().getResolutionScopeForDeclaration(dcl); collectDescriptors(scope, dcl); } @@ -185,7 +180,7 @@ public class ResolveSession { PsiElement parent = element.getParent(); if (parent instanceof JetFile) { JetFile file = (JetFile) parent; - return getScopeProvider().getFileScopeForDeclarationResolution(file); + return getInjector().getScopeProvider().getFileScopeForDeclarationResolution(file); } if (parent instanceof JetClassBody) { diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/BasicLazyResolveTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/BasicLazyResolveTest.java index f50271456c3..aaef0dbdbe0 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/BasicLazyResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/BasicLazyResolveTest.java @@ -14,7 +14,7 @@ package org.jetbrains.jet.lang.resolve.lazy;/* * limitations under the License. */ -import com.google.common.base.Predicates; +import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.intellij.openapi.Disposable; @@ -66,8 +66,8 @@ public class BasicLazyResolveTest { Project project = jetCoreEnvironment.getProject(); final JetClass jetClass = JetPsiFactory.createClass(project, "package p; class C {fun f() {}}"); - final JetClass genericJetClass = JetPsiFactory.createClass(project, "package p; open class G {fun f(): T {}}"); - final JetClass genericJetClass2 = JetPsiFactory.createClass(project, "package p; class G2 : G {}"); + final JetClass genericJetClass = JetPsiFactory.createClass(project, "package p; open class G {open fun f(): T {} fun a() {}}"); + final JetClass genericJetClass2 = JetPsiFactory.createClass(project, "package p; class G2 : G { fun g() : E {} override fun f() : T {}}"); final JetNamedFunction fooFunction1 = JetPsiFactory.createFunction(project, "package p; fun foo() {}"); final JetNamedFunction fooFunction2 = JetPsiFactory.createFunction(project, "package p; fun foo(a: C) {}"); @@ -155,21 +155,26 @@ public class BasicLazyResolveTest { return jetClass.getDeclarations(); } - private List filter(List list, Class t) { + private List filter(List list, final Class t, final Name name) { //noinspection unchecked - return (List) Lists.newArrayList(Collections2.filter(list, Predicates.instanceOf(t))); + return (List) Lists.newArrayList(Collections2.filter(list, new Predicate() { + @Override + public boolean apply(D d) { + return t.isInstance(d) && ((JetNamed) d).getNameAsName().equals(name); + } + })); } @NotNull @Override - public List getFunctionDeclarations(@NotNull Name name) { - return filter(jetClass.getDeclarations(), JetNamedFunction.class); + public List getFunctionDeclarations(@NotNull final Name name) { + return filter(jetClass.getDeclarations(), JetNamedFunction.class, name); } @NotNull @Override public List getPropertyDeclarations(@NotNull Name name) { - return filter(jetClass.getDeclarations(), JetProperty.class); + return filter(jetClass.getDeclarations(), JetProperty.class, name); } @Override @@ -215,18 +220,23 @@ public class BasicLazyResolveTest { assertEquals(classDescriptor, foo2.getValueParameters().get(0).getType().getConstructor().getDeclarationDescriptor()); assertEquals(packageDescriptor, foo2.getContainingDeclaration()); - ClassifierDescriptor genericClassifier2 = packageDescriptor.getMemberScope().getClassifier(Name.identifier("G2")); - assertNotNull(genericClassifier2); - assertEquals(1, genericClassifier2.getTypeConstructor().getSupertypes().size()); - assertEquals("G", genericClassifier2.getTypeConstructor().getSupertypes().iterator().next().toString()); - ClassifierDescriptor genericClassifier = packageDescriptor.getMemberScope().getClassifier(Name.identifier("G")); assertNotNull(genericClassifier); + ClassDescriptor genericClass = (ClassDescriptor) genericClassifier; + assertEquals(Modality.OPEN, genericClass.getModality()); assertEquals(1, genericClassifier.getTypeConstructor().getParameters().size()); TypeParameterDescriptor typeParameterDescriptor_T = genericClassifier.getTypeConstructor().getParameters().get(0); assertEquals(JetStandardClasses.getNullableAnyType(), typeParameterDescriptor_T.getUpperBoundsAsType()); assertEquals("G", genericClassifier.getDefaultType().toString()); assertEquals(typeParameterDescriptor_T.getDefaultType(), genericClassifier.getDefaultType().getMemberScope().getFunctions(Name.identifier("f")).iterator().next().getReturnType()); + + ClassifierDescriptor genericClassifier2 = packageDescriptor.getMemberScope().getClassifier(Name.identifier("G2")); + assertNotNull(genericClassifier2); + assertEquals(1, genericClassifier2.getTypeConstructor().getSupertypes().size()); + assertEquals("G", genericClassifier2.getTypeConstructor().getSupertypes().iterator().next().toString()); + assertEquals(1, genericClassifier2.getDefaultType().getMemberScope().getFunctions(Name.identifier("g")).size()); + assertEquals(1, genericClassifier2.getDefaultType().getMemberScope().getFunctions(Name.identifier("a")).size()); + assertEquals(1, genericClassifier2.getDefaultType().getMemberScope().getFunctions(Name.identifier("f")).iterator().next().getOverriddenDescriptors().size()); } } \ No newline at end of file diff --git a/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java b/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java index bfc0a601f44..142a31d5e12 100644 --- a/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java +++ b/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java @@ -25,6 +25,8 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.java.*; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; +import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider; import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolverDummyImpl; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; @@ -53,9 +55,12 @@ public class AllInjectorsGenerator { private static void generateInjectorForLazyResolve() throws IOException { DependencyInjectorGenerator generator = new DependencyInjectorGenerator(false); generator.addParameter(Project.class); + generator.addParameter(ResolveSession.class); + generator.addParameter(BindingTrace.class); generator.addPublicField(DescriptorResolver.class); generator.addPublicField(ExpressionTypingServices.class); generator.addPublicField(TypeResolver.class); + generator.addPublicField(ScopeProvider.class); generator.generate("compiler/frontend/src", "org.jetbrains.jet.di", "InjectorForLazyResolve"); }