From efa4bf1d74a14b34a4e56bc2289d6096a6147a34 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Tue, 17 Nov 2015 15:09:01 +0300 Subject: [PATCH] Script refactoring, frontend: Treat scripts as classes (as opposed to function bodies) ScriptDescriptor implements ClassDescriptor Scripts are accessible in IDE via stub index Replace special treatment of scripts with generic mechanism in several cases Scripts to longer generate 'rv' property for storing result value (changes in repl required) --- .../kotlin/cfg/JetControlFlowProcessor.java | 13 +- .../kotlin/resolve/BindingContext.java | 2 +- .../kotlin/resolve/BodiesResolveContext.java | 8 +- .../kotlin/resolve/BodyResolver.java | 9 +- .../kotlin/resolve/ControlFlowAnalyzer.java | 3 + .../kotlin/resolve/LazyTopDownAnalyzer.kt | 39 +++--- .../kotlin/resolve/ScriptBodyResolver.java | 71 ---------- .../resolve/TopDownAnalysisContext.java | 17 +-- .../lazy/DeclarationScopeProviderImpl.java | 6 + .../resolve/lazy/LazyDeclarationResolver.java | 37 +++-- .../kotlin/resolve/lazy/ResolveSession.java | 52 ++----- .../lazy/TopLevelDescriptorProvider.kt | 8 -- .../lazy/data/JetClassOrObjectInfo.java | 1 + .../kotlin/resolve/lazy/data/JetScriptInfo.kt | 11 +- .../descriptors/AbstractLazyMemberScope.kt | 9 +- .../LazyScriptClassDescriptor.java | 66 --------- .../descriptors/LazyScriptClassMemberScope.kt | 132 +++++++----------- .../lazy/descriptors/LazyScriptDescriptor.kt | 109 +++++---------- .../scopes/receivers/ScriptReceiver.java | 48 ------- .../expressions/ExpressionTypingServices.java | 7 - .../util/RecursiveDescriptorProcessor.java | 2 +- .../kotlin/descriptors/ScriptDescriptor.java | 19 +-- ...clarationDescriptorVisitorEmptyBodies.java | 2 +- .../impl/ScriptCodeDescriptor.java | 75 ---------- .../kotlin/renderer/DescriptorRendererImpl.kt | 8 +- .../idea/project/ResolveElementCache.kt | 6 +- ...ubBasedPackageMemberDeclarationProvider.kt | 18 +-- 27 files changed, 198 insertions(+), 580 deletions(-) delete mode 100644 compiler/frontend/src/org/jetbrains/kotlin/resolve/ScriptBodyResolver.java delete mode 100644 compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassDescriptor.java delete mode 100644 compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/ScriptReceiver.java delete mode 100644 core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ScriptCodeDescriptor.java diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/kotlin/cfg/JetControlFlowProcessor.java index 858ad9252bc..c846dd13a8c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/JetControlFlowProcessor.java @@ -1318,7 +1318,7 @@ public class JetControlFlowProcessor { @Override public void visitObjectDeclaration(@NotNull KtObjectDeclaration objectDeclaration) { generateHeaderDelegationSpecifiers(objectDeclaration); - generateClassOrObjectInitializers(objectDeclaration); + generateInitializersForScriptClassOrObject(objectDeclaration); generateDeclarationForLocalClassOrObjectIfNeeded(objectDeclaration); } @@ -1353,7 +1353,7 @@ public class JetControlFlowProcessor { } } - private void generateClassOrObjectInitializers(@NotNull KtClassOrObject classOrObject) { + private void generateInitializersForScriptClassOrObject(@NotNull KtDeclarationContainer classOrObject) { for (KtDeclaration declaration : classOrObject.getDeclarations()) { if (declaration instanceof KtProperty || declaration instanceof KtClassInitializer) { generateInstructions(declaration); @@ -1368,12 +1368,17 @@ public class JetControlFlowProcessor { // delegation specifiers of primary constructor, anonymous class and property initializers generateHeaderDelegationSpecifiers(klass); - generateClassOrObjectInitializers(klass); + generateInitializersForScriptClassOrObject(klass); } generateDeclarationForLocalClassOrObjectIfNeeded(klass); } + @Override + public void visitScript(@NotNull KtScript script) { + generateInitializersForScriptClassOrObject(script); + } + private void generateDeclarationForLocalClassOrObjectIfNeeded(@NotNull KtClassOrObject classOrObject) { if (classOrObject.isLocal()) { for (KtDeclaration declaration : classOrObject.getDeclarations()) { @@ -1402,7 +1407,7 @@ public class JetControlFlowProcessor { generateCallOrMarkUnresolved(constructor.getDelegationCall()); if (!constructor.getDelegationCall().isCallToThis()) { - generateClassOrObjectInitializers(classOrObject); + generateInitializersForScriptClassOrObject(classOrObject); } generateInstructions(constructor.getBodyExpression()); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index aaeb5c83e4e..db7b5e80741 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -213,7 +213,7 @@ public interface BindingContext { WritableSlice[] DECLARATIONS_TO_DESCRIPTORS = new WritableSlice[] { CLASS, TYPE_PARAMETER, FUNCTION, CONSTRUCTOR, VARIABLE, VALUE_PARAMETER, PROPERTY_ACCESSOR, - PRIMARY_CONSTRUCTOR_PARAMETER + PRIMARY_CONSTRUCTOR_PARAMETER, SCRIPT }; @SuppressWarnings("unchecked") diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodiesResolveContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodiesResolveContext.java index 3559a895dba..b34d954c45f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodiesResolveContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodiesResolveContext.java @@ -20,9 +20,13 @@ import org.jetbrains.annotations.Mutable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.ReadOnly; -import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes; +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor; +import org.jetbrains.kotlin.descriptors.PropertyDescriptor; +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; +import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor; import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import java.util.Collection; @@ -39,7 +43,7 @@ public interface BodiesResolveContext { @Mutable Map getSecondaryConstructors(); @Mutable - Map getScripts(); + Map getScripts(); @Mutable Map getProperties(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index d11828d0556..86ff9a6c0b6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -60,7 +60,6 @@ import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE; public class BodyResolver { - @NotNull private final ScriptBodyResolver scriptBodyResolverResolver; @NotNull private final AnnotationChecker annotationChecker; @NotNull private final ExpressionTypingServices expressionTypingServices; @NotNull private final CallResolver callResolver; @@ -82,7 +81,6 @@ public class BodyResolver { @NotNull DelegatedPropertyResolver delegatedPropertyResolver, @NotNull ExpressionTypingServices expressionTypingServices, @NotNull FunctionAnalyzerExtension functionAnalyzerExtension, - @NotNull ScriptBodyResolver scriptBodyResolverResolver, @NotNull BindingTrace trace, @NotNull ValueParameterResolver valueParameterResolver, @NotNull AnnotationChecker annotationChecker @@ -95,7 +93,6 @@ public class BodyResolver { this.delegatedPropertyResolver = delegatedPropertyResolver; this.expressionTypingServices = expressionTypingServices; this.functionAnalyzerExtension = functionAnalyzerExtension; - this.scriptBodyResolverResolver = scriptBodyResolverResolver; this.annotationChecker = annotationChecker; this.trace = new ObservableBindingTrace(trace); this.valueParameterResolver = valueParameterResolver; @@ -112,8 +109,6 @@ public class BodyResolver { resolveFunctionBodies(c); - scriptBodyResolverResolver.resolveScriptBodies(c); - if (!c.getTopDownAnalysisMode().isLocalDeclarations()) { computeDeferredTypes(); } @@ -523,7 +518,9 @@ public class BodyResolver { if (body != null) { PreliminaryDeclarationVisitor.Companion.createForDeclaration( (KtDeclaration) anonymousInitializer.getParent().getParent(), trace); - expressionTypingServices.getType(scopeForInitializers, body, NO_EXPECTED_TYPE, outerDataFlowInfo, trace); + expressionTypingServices.getTypeInfo( + scopeForInitializers, body, NO_EXPECTED_TYPE, outerDataFlowInfo, trace, /*isStatement = */true + ); } processModifiersOnInitializer(anonymousInitializer, scopeForInitializers); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ControlFlowAnalyzer.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ControlFlowAnalyzer.java index 492b5ae9a33..528f8af0be1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ControlFlowAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ControlFlowAnalyzer.java @@ -46,6 +46,9 @@ public class ControlFlowAnalyzer { for (KtClassOrObject aClass : c.getDeclaredClasses().keySet()) { checkDeclarationContainer(c, aClass); } + for (KtScript script : c.getScripts().keySet()) { + checkDeclarationContainer(c, script); + } for (KtSecondaryConstructor constructor : c.getSecondaryConstructors().keySet()) { checkSecondaryConstructor(constructor); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt index 0d6876e4cd7..799ff909568 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.lazy.* import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor +import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor import org.jetbrains.kotlin.resolve.varianceChecker.VarianceChecker import java.util.* @@ -69,26 +70,22 @@ public class LazyTopDownAnalyzer( throw IllegalArgumentException("Unsupported declaration: " + dcl + " " + dcl.getText()) } + override fun visitScript(script: KtScript) { + c.getScripts().put( + script, + lazyDeclarationResolver.getScriptDescriptor(script, KotlinLookupLocation(script)) as LazyScriptDescriptor + ) + registerDeclarations(script.declarations) + } + override fun visitKtFile(file: KtFile) { - if (file.isScript()) { - val script = file.getScript() ?: throw AssertionError("getScript() is null for file: $file") - - DescriptorResolver.registerFileInPackage(trace, file) - c.getScripts().put(script, topLevelDescriptorProvider.getScriptDescriptor(script)) - } - else { - val packageDirective = file.getPackageDirective() - assert(packageDirective != null) { "No package in a non-script file: " + file } - - c.addFile(file) - - packageDirective!!.accept(this) - DescriptorResolver.registerFileInPackage(trace, file) - - registerDeclarations(file.getDeclarations()) - - topLevelFqNames.put(file.getPackageFqName(), packageDirective) - } + DescriptorResolver.registerFileInPackage(trace, file) + registerDeclarations(file.declarations) + val packageDirective = file.packageDirective + assert(file.isScript || packageDirective != null) { "No package in a non-script file: " + file } + packageDirective?.accept(this) + c.addFile(file) + topLevelFqNames.put(file.packageFqName, packageDirective) } override fun visitPackageDirective(directive: KtPackageDirective) { @@ -158,8 +155,8 @@ public class LazyTopDownAnalyzer( } override fun visitAnonymousInitializer(initializer: KtClassInitializer) { - val classOrObject = PsiTreeUtil.getParentOfType(initializer, javaClass())!! - c.getAnonymousInitializers().put(initializer, lazyDeclarationResolver.resolveToDescriptor(classOrObject) as ClassDescriptorWithResolutionScopes) + val containerDescriptor = lazyDeclarationResolver.resolveToDescriptor(initializer.containingDeclaration) as ClassDescriptorWithResolutionScopes + c.getAnonymousInitializers().put(initializer, containerDescriptor) } override fun visitTypedef(typedef: KtTypedef) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ScriptBodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ScriptBodyResolver.java deleted file mode 100644 index b6cc5d4308d..00000000000 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ScriptBodyResolver.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.resolve; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.descriptors.ScriptDescriptor; -import org.jetbrains.kotlin.psi.KtScript; -import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; -import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil; -import org.jetbrains.kotlin.resolve.scopes.LexicalScope; -import org.jetbrains.kotlin.types.ErrorUtils; -import org.jetbrains.kotlin.types.KotlinType; -import org.jetbrains.kotlin.types.expressions.CoercionStrategy; -import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext; -import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices; -import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor; - -import java.util.Map; - -import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE; - -public class ScriptBodyResolver { - private final ExpressionTypingServices expressionTypingServices; - - public ScriptBodyResolver( - @NotNull ExpressionTypingServices expressionTypingServices - ) { - this.expressionTypingServices = expressionTypingServices; - } - - public void resolveScriptBodies(@NotNull BodiesResolveContext c) { - for (Map.Entry e : c.getScripts().entrySet()) { - ScriptDescriptor descriptor = e.getValue(); - ForceResolveUtil.forceResolveAllContents(descriptor); - } - } - - @NotNull - public KotlinType resolveScriptReturnType( - @NotNull KtScript script, - @NotNull LexicalScope scopeForBodyResolution, - @NotNull BindingTrace trace - ) { - // Resolve all contents of the script - ExpressionTypingContext context = ExpressionTypingContext.newContext( - trace, scopeForBodyResolution, DataFlowInfo.EMPTY, NO_EXPECTED_TYPE - ); - PreliminaryDeclarationVisitor.Companion.createForDeclaration(script, trace); - KotlinType returnType = expressionTypingServices.getBlockReturnedType( - script.getBlockExpression(), CoercionStrategy.NO_COERCION, context - ).getType(); - if (returnType == null) { - returnType = ErrorUtils.createErrorType("getBlockReturnedType returned null"); - } - return returnType; - } -} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TopDownAnalysisContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TopDownAnalysisContext.java index 16c84b25b39..258ed6c216a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TopDownAnalysisContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TopDownAnalysisContext.java @@ -18,13 +18,13 @@ package org.jetbrains.kotlin.resolve; import com.google.common.collect.Maps; import kotlin.CollectionsKt; -import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; import org.jetbrains.kotlin.resolve.lazy.DeclarationScopeProvider; +import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor; import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import java.io.PrintStream; @@ -47,7 +47,7 @@ public class TopDownAnalysisContext implements BodiesResolveContext { private final Map primaryConstructorParameterProperties = Maps.newHashMap(); private Map members = null; - private final Map scripts = Maps.newLinkedHashMap(); + private final Map scripts = Maps.newLinkedHashMap(); private final TopDownAnalysisMode topDownAnalysisMode; private final DeclarationScopeProvider declarationScopeProvider; @@ -115,7 +115,7 @@ public class TopDownAnalysisContext implements BodiesResolveContext { @Override @NotNull - public Map getScripts() { + public Map getScripts() { return scripts; } @@ -158,15 +158,6 @@ public class TopDownAnalysisContext implements BodiesResolveContext { @NotNull public Collection getAllClasses() { - Collection scriptClasses = CollectionsKt.map( - getScripts().values(), - new Function1() { - @Override - public ClassDescriptorWithResolutionScopes invoke(ScriptDescriptor scriptDescriptor) { - return (ClassDescriptorWithResolutionScopes) scriptDescriptor.getClassDescriptor(); - } - } - ); - return CollectionsKt.plus(getDeclaredClasses().values(), scriptClasses); + return CollectionsKt.plus(getDeclaredClasses().values(), getScripts().values()); } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/DeclarationScopeProviderImpl.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/DeclarationScopeProviderImpl.java index 0bedc9fb426..743148377d0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/DeclarationScopeProviderImpl.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/DeclarationScopeProviderImpl.java @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor; +import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor; import org.jetbrains.kotlin.resolve.scopes.LexicalScope; public class DeclarationScopeProviderImpl implements DeclarationScopeProvider { @@ -71,6 +72,11 @@ public class DeclarationScopeProviderImpl implements DeclarationScopeProvider { return classDescriptor.getScopeForMemberDeclarationResolution(); } + //TODO: this is not how it works for classes and for exact parity we can try to use the code above + if (parentDeclaration instanceof KtScript) { + LazyScriptDescriptor scriptDescriptor = (LazyScriptDescriptor) lazyDeclarationResolver.resolveToDescriptor(parentDeclaration); + return scriptDescriptor.getScopeForInitializerResolution(); + } throw new IllegalStateException("Don't call this method for local declarations: " + ktDeclaration + "\n" + PsiUtilsKt.getElementTextWithContext(ktDeclaration)); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java index 602e23da30a..24c23be248d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java @@ -66,22 +66,35 @@ public class LazyDeclarationResolver { @NotNull public ClassDescriptor getClassDescriptor(@NotNull KtClassOrObject classOrObject, @NotNull LookupLocation location) { - MemberScope scope = getMemberScopeDeclaredIn(classOrObject, location); + return findClassDescriptor(classOrObject, location); + } + + @NotNull + public ScriptDescriptor getScriptDescriptor(@NotNull KtScript script, @NotNull LookupLocation location) { + return (ScriptDescriptor) findClassDescriptor(script, location); + } + + @NotNull + private ClassDescriptor findClassDescriptor( + @NotNull KtNamedDeclaration classObjectOrScript, + @NotNull LookupLocation location + ) { + MemberScope scope = getMemberScopeDeclaredIn(classObjectOrScript, location); // Why not use the result here. Because it may be that there is a redeclaration: // class A {} class A { fun foo(): A} // and if we find the class by name only, we may b-not get the right one. // This call is only needed to make sure the classes are written to trace - ClassifierDescriptor scopeDescriptor = scope.getContributedClassifier(classOrObject.getNameAsSafeName(), location); - DeclarationDescriptor descriptor = getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, classOrObject); + ClassifierDescriptor scopeDescriptor = scope.getContributedClassifier(classObjectOrScript.getNameAsSafeName(), location); + DeclarationDescriptor descriptor = getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, classObjectOrScript); if (descriptor == null) { throw new IllegalArgumentException( - String.format("Could not find a classifier for %s.\n" + - "Found descriptor: %s (%s).\n", - PsiUtilsKt.getElementTextWithContext(classOrObject), - scopeDescriptor != null ? DescriptorRenderer.DEBUG_TEXT.render(scopeDescriptor) : "null", - scopeDescriptor != null ? (scopeDescriptor.getContainingDeclaration().getClass()) : null)); + String.format("Could not find a classifier for %s.\n" + + "Found descriptor: %s (%s).\n", + PsiUtilsKt.getElementTextWithContext(classObjectOrScript), + scopeDescriptor != null ? DescriptorRenderer.DEBUG_TEXT.render(scopeDescriptor) : "null", + scopeDescriptor != null ? (scopeDescriptor.getContainingDeclaration().getClass()) : null)); } return (ClassDescriptor) descriptor; @@ -210,7 +223,7 @@ public class LazyDeclarationResolver { @Override public DeclarationDescriptor visitScript(@NotNull KtScript script, Void data) { - return topLevelDescriptorProvider.getScriptDescriptor(script); + return getScriptDescriptor(script, lookupLocationFor(script, true)); } @Override @@ -238,7 +251,11 @@ public class LazyDeclarationResolver { else { if (parentDeclaration instanceof KtClassOrObject) { return getClassDescriptor((KtClassOrObject) parentDeclaration, location).getUnsubstitutedMemberScope(); - } else { + } + else if (parentDeclaration instanceof KtScript) { + return getScriptDescriptor((KtScript) parentDeclaration, location).getUnsubstitutedMemberScope(); + } + else { throw new IllegalStateException("Don't call this method for local declarations: " + declaration + "\n" + PsiUtilsKt.getElementTextWithContext(declaration)); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java index b54c07844be..928df7c3143 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/ResolveSession.java @@ -35,13 +35,13 @@ import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.*; import org.jetbrains.kotlin.resolve.lazy.data.JetClassLikeInfo; +import org.jetbrains.kotlin.resolve.lazy.data.JetClassOrObjectInfo; import org.jetbrains.kotlin.resolve.lazy.data.JetScriptInfo; import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory; import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider; import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotations; import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationsContextImpl; import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor; -import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import org.jetbrains.kotlin.storage.*; @@ -63,8 +63,6 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { private final MemoizedFunctionToNullable packages; private final PackageFragmentProvider packageFragmentProvider; - private final MemoizedFunctionToNotNull scriptDescriptors; - private final MemoizedFunctionToNotNull fileAnnotations; private final MemoizedFunctionToNotNull danglingAnnotations; @@ -73,7 +71,6 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { private DescriptorResolver descriptorResolver; private FunctionDescriptorResolver functionDescriptorResolver; private TypeResolver typeResolver; - private ScriptBodyResolver scriptBodyResolver; private LazyDeclarationResolver lazyDeclarationResolver; private FileScopeProvider fileScopeProvider; private DeclarationScopeProvider declarationScopeProvider; @@ -106,11 +103,6 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { this.typeResolver = typeResolver; } - @Inject - public void setScriptBodyResolver(ScriptBodyResolver scriptBodyResolver) { - this.scriptBodyResolver = scriptBodyResolver; - } - @Inject public void setLazyDeclarationResolver(LazyDeclarationResolver lazyDeclarationResolver) { this.lazyDeclarationResolver = lazyDeclarationResolver; @@ -179,20 +171,6 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { } }; - this.scriptDescriptors = storageManager.createMemoizedFunction( - new Function1() { - @Override - public LazyScriptDescriptor invoke(KtScript script) { - return new LazyScriptDescriptor( - ResolveSession.this, - scriptBodyResolver, - script, - ScriptPriorities.getScriptPriority(script) - ); - } - } - ); - fileAnnotations = storageManager.createMemoizedFunction(new Function1() { @Override public LazyAnnotations invoke(KtFile file) { @@ -267,12 +245,18 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { new Function() { @Override public ClassDescriptor fun(JetClassLikeInfo classLikeInfo) { - if (classLikeInfo instanceof JetScriptInfo) { - return getClassDescriptorForScript(((JetScriptInfo) classLikeInfo).getScript()); + if (classLikeInfo instanceof JetClassOrObjectInfo) { + //noinspection RedundantCast + return getClassDescriptor(((JetClassOrObjectInfo) classLikeInfo).getCorrespondingClassOrObject(), location); + } + else if (classLikeInfo instanceof JetScriptInfo) { + return getScriptDescriptor(((JetScriptInfo) classLikeInfo).getScript()); + } + else { + throw new IllegalStateException( + "Unexpected " + classLikeInfo + " of type " + classLikeInfo.getClass().getName() + ); } - KtClassOrObject classOrObject = classLikeInfo.getCorrespondingClassOrObject(); - if (classOrObject == null) return null; - return getClassDescriptor(classOrObject, location); } } ); @@ -284,19 +268,9 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { return lazyDeclarationResolver.getClassDescriptor(classOrObject, location); } - @NotNull - public ClassDescriptor getClassDescriptorForScript(@NotNull KtScript script) { - MemberScope memberScope = lazyDeclarationResolver.getMemberScopeDeclaredIn(script, NoLookupLocation.FOR_SCRIPT); - FqName fqName = ScriptNameUtil.classNameForScript(script); - ClassifierDescriptor classifier = memberScope.getContributedClassifier(fqName.shortName(), NoLookupLocation.FOR_SCRIPT); - assert classifier != null : "No descriptor for " + fqName + " in file " + script.getContainingFile(); - return (ClassDescriptor) classifier; - } - - @Override @NotNull public ScriptDescriptor getScriptDescriptor(@NotNull KtScript script) { - return scriptDescriptors.invoke(script); + return lazyDeclarationResolver.getScriptDescriptor(script, NoLookupLocation.FOR_SCRIPT); } @Override diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/TopLevelDescriptorProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/TopLevelDescriptorProvider.kt index 19bae1e1977..39a152520c1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/TopLevelDescriptorProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/TopLevelDescriptorProvider.kt @@ -17,17 +17,13 @@ package org.jetbrains.kotlin.resolve.lazy import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ScriptDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtScript import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor public interface TopLevelDescriptorProvider { fun getPackageFragment(fqName: FqName): LazyPackageDescriptor? - fun getScriptDescriptor(script: KtScript): ScriptDescriptor - fun getTopLevelClassDescriptors(fqName: FqName, location: LookupLocation): Collection } @@ -38,10 +34,6 @@ public object NoTopLevelDescriptorProvider : TopLevelDescriptorProvider { shouldNotBeCalled() } - override fun getScriptDescriptor(script: KtScript): ScriptDescriptor { - shouldNotBeCalled() - } - override fun getTopLevelClassDescriptors(fqName: FqName, location: LookupLocation): Collection { shouldNotBeCalled() } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/data/JetClassOrObjectInfo.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/data/JetClassOrObjectInfo.java index c19ab632485..fced90bcd81 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/data/JetClassOrObjectInfo.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/data/JetClassOrObjectInfo.java @@ -40,6 +40,7 @@ public abstract class JetClassOrObjectInfo implements } @Override + @NotNull public KtClassOrObject getCorrespondingClassOrObject() { return element; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/data/JetScriptInfo.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/data/JetScriptInfo.kt index feb509df431..970e5ca119a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/data/JetScriptInfo.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/data/JetScriptInfo.kt @@ -34,14 +34,5 @@ public class JetScriptInfo( override fun getPrimaryConstructorParameters() = listOf() override fun getClassKind() = ClassKind.CLASS override fun getDeclarations() = script.getDeclarations() - .filter(::shouldBeScriptClassMember) override fun getDanglingAnnotations() = listOf() -} - -public fun shouldBeScriptClassMember(declaration: KtDeclaration): Boolean { - // To avoid the necessity to always analyze the whole body of a script even if just its class descriptor is needed - // we only add those vals, vars and funs that have explicitly specified return types - // (or implicit Unit for function with block body) - return declaration is KtCallableDeclaration && declaration.getTypeReference() != null - || declaration is KtNamedFunction && declaration.hasBlockBody() -} +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt index 8b5b14cc99a..14e8d77f625 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt @@ -17,7 +17,10 @@ package org.jetbrains.kotlin.resolve.lazy.descriptors import com.google.common.collect.Sets -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.record import org.jetbrains.kotlin.name.Name @@ -29,8 +32,8 @@ import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.data.JetScriptInfo import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProvider import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter -import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl import org.jetbrains.kotlin.resolve.scopes.LexicalScope +import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.utils.Printer @@ -53,7 +56,7 @@ protected constructor( private fun resolveClassDescriptor(name: Name): List { return declarationProvider.getClassOrObjectDeclarations(name).map { if (it is JetScriptInfo) - LazyScriptClassDescriptor(c as ResolveSession, thisDescriptor, name, it) + LazyScriptDescriptor(c as ResolveSession, thisDescriptor, name, it) else LazyClassDescriptor(c, thisDescriptor, name, it) }.toReadOnlyList() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassDescriptor.java deleted file mode 100644 index 996e919fd50..00000000000 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassDescriptor.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.resolve.lazy.descriptors; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.resolve.lazy.LazyClassContext; -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; -import org.jetbrains.kotlin.descriptors.Visibilities; -import org.jetbrains.kotlin.descriptors.Visibility; -import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.resolve.TemporaryBindingTrace; -import org.jetbrains.kotlin.resolve.lazy.ResolveSession; -import org.jetbrains.kotlin.resolve.lazy.data.JetScriptInfo; -import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider; - -public class LazyScriptClassDescriptor extends LazyClassDescriptor { - public LazyScriptClassDescriptor( - @NotNull ResolveSession resolveSession, - @NotNull DeclarationDescriptor containingDeclaration, - @NotNull Name name, - @NotNull JetScriptInfo scriptInfo - ) { - super(resolveSession, containingDeclaration, name, scriptInfo); - } - - @NotNull - @Override - protected LazyScriptClassMemberScope createMemberScope( - @NotNull LazyClassContext c, - @NotNull ClassMemberDeclarationProvider declarationProvider - ) { - return new LazyScriptClassMemberScope( - // Must be a ResolveSession for scripts - (ResolveSession) c, - declarationProvider, - this, - TemporaryBindingTrace.create(c.getTrace(), "A trace for script class, needed to avoid rewrites on members") - ); - } - - @NotNull - @Override - public LazyScriptClassMemberScope getUnsubstitutedMemberScope() { - return (LazyScriptClassMemberScope) super.getUnsubstitutedMemberScope(); - } - - @NotNull - @Override - public Visibility getVisibility() { - return Visibilities.PUBLIC; - } -} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassMemberScope.kt index 803aaad3b71..954a38fa9e2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptClassMemberScope.kt @@ -20,112 +20,76 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.parsing.KotlinScriptDefinitionProvider import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.lazy.ResolveSession -import org.jetbrains.kotlin.resolve.lazy.data.JetScriptInfo import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider -import org.jetbrains.kotlin.storage.NotNullLazyValue import org.jetbrains.kotlin.utils.toReadOnlyList -public class LazyScriptClassMemberScope protected constructor( +public class LazyScriptClassMemberScope( private val resolveSession: ResolveSession, declarationProvider: ClassMemberDeclarationProvider, - thisClass: LazyClassDescriptor, + private val scriptDescriptor: LazyScriptDescriptor, trace: BindingTrace) -: LazyClassMemberScope(resolveSession, declarationProvider, thisClass, trace) { - - private val scriptResultProperty: NotNullLazyValue = resolveSession.storageManager.createLazyValue { - val scriptInfo = declarationProvider.getOwnerInfo() as JetScriptInfo - createScriptResultProperty(resolveSession.getScriptDescriptor(scriptInfo.script)) - } - - override fun computeExtraDescriptors(location: LookupLocation): Collection { - return (super.computeExtraDescriptors(location) - + getContributedVariables(Name.identifier(ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME), location) - + getPropertiesForScriptParameters()).toReadOnlyList() - } - - private fun getPropertiesForScriptParameters() = getPrimaryConstructor()!!.valueParameters.flatMap { getContributedVariables(it.name, NoLookupLocation.FOR_SCRIPT) } - - override fun getNonDeclaredProperties(name: Name, result: MutableSet) { - super.getNonDeclaredProperties(name, result) - - if (name.asString() == ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME) { - result.add(scriptResultProperty()) - } - } - - public fun getScriptResultProperty(): PropertyDescriptor = scriptResultProperty() - - override fun createPropertiesFromPrimaryConstructorParameters(name: Name, result: MutableSet) { - val scriptInfo = declarationProvider.getOwnerInfo() as JetScriptInfo - - // From primary constructor parameters - val primaryConstructor = getPrimaryConstructor() - if (primaryConstructor == null) return - - for (valueParameterDescriptor in primaryConstructor.getValueParameters()) { - if (name == valueParameterDescriptor.getName()) { - result.add(createPropertyFromScriptParameter(resolveSession.getScriptDescriptor(scriptInfo.script), valueParameterDescriptor)) - } - } - } +: LazyClassMemberScope(resolveSession, declarationProvider, scriptDescriptor, trace) { override fun resolvePrimaryConstructor(): ConstructorDescriptor? { - val scriptInfo = declarationProvider.getOwnerInfo() as JetScriptInfo - val scriptDescriptor = resolveSession.getScriptDescriptor(scriptInfo.script) - val constructor = createConstructor(scriptDescriptor, scriptDescriptor.getScriptCodeDescriptor().getValueParameters()) + val constructor = ConstructorDescriptorImpl.create( + scriptDescriptor, + Annotations.EMPTY, + true, + SourceElement.NO_SOURCE + ) + constructor.initialize( + createScriptParameters(constructor), + Visibilities.PUBLIC + ) setDeferredReturnType(constructor) return constructor } - private fun createScriptResultProperty(scriptDescriptor: ScriptDescriptor): PropertyDescriptor { - val propertyDescriptor = PropertyDescriptorImpl.create( - scriptDescriptor.getClassDescriptor(), - Annotations.EMPTY, - Modality.FINAL, - Visibilities.PUBLIC, - false, - Name.identifier(ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME), - CallableMemberDescriptor.Kind.DECLARATION, - SourceElement.NO_SOURCE, - /* lateInit = */ false, - /* isConst = */ false - ) - - val returnType = scriptDescriptor.getScriptCodeDescriptor().getReturnType() - assert(returnType != null) { "Return type not initialized for " + scriptDescriptor } - returnType!! - - propertyDescriptor.setType( - returnType, - listOf(), - scriptDescriptor.getThisAsReceiverParameter(), - null as ReceiverParameterDescriptor? - ) - propertyDescriptor.initialize(null, null) - - return propertyDescriptor + private fun createScriptParameters(constructor: ConstructorDescriptorImpl): List { + val file = scriptDescriptor.scriptInfo.script.getContainingKtFile() + val scriptDefinition = KotlinScriptDefinitionProvider.getInstance(file.project).findScriptDefinition(file) + return scriptDefinition.scriptParameters.mapIndexed { index, scriptParameter -> + ValueParameterDescriptorImpl( + constructor, null, index, Annotations.EMPTY, scriptParameter.getName(), scriptParameter.getType(), + /* declaresDefaultValue = */ false, + /* isCrossinline = */ false, + /* isNoinline = */ false, + null, SourceElement.NO_SOURCE + ) + } } - private fun createConstructor(scriptDescriptor: ScriptDescriptor, valueParameters: List): ConstructorDescriptorImpl { - return ConstructorDescriptorImpl.create( - scriptDescriptor.getClassDescriptor(), - Annotations.EMPTY, - true, - SourceElement.NO_SOURCE - ).initialize( - valueParameters, - Visibilities.PUBLIC - ) + override fun computeExtraDescriptors(location: LookupLocation): Collection { + return (super.computeExtraDescriptors(location) + + getPropertiesForScriptParameters()).toReadOnlyList() } - private fun createPropertyFromScriptParameter(scriptDescriptor: ScriptDescriptor, parameter: ValueParameterDescriptor): PropertyDescriptor { + private fun getPropertiesForScriptParameters() = getPrimaryConstructor()!!.valueParameters.flatMap { + getContributedVariables(it.name, NoLookupLocation.FOR_SCRIPT) + } + + override fun createPropertiesFromPrimaryConstructorParameters(name: Name, result: MutableSet) { + val primaryConstructor = getPrimaryConstructor()!! + for (valueParameterDescriptor in primaryConstructor.valueParameters) { + if (name == valueParameterDescriptor.getName()) { + result.add(createPropertyFromScriptParameter(scriptDescriptor, valueParameterDescriptor)) + } + } + } + + private fun createPropertyFromScriptParameter( + scriptDescriptor: ScriptDescriptor, + parameter: ValueParameterDescriptor + ): PropertyDescriptor { val propertyDescriptor = PropertyDescriptorImpl.create( - scriptDescriptor.getClassDescriptor(), + scriptDescriptor, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt index cc4db5a9692..0c4db85599b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyScriptDescriptor.kt @@ -16,100 +16,57 @@ package org.jetbrains.kotlin.resolve.lazy.descriptors -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorVisitor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.descriptors.ScriptDescriptor -import org.jetbrains.kotlin.descriptors.SourceElement -import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorNonRootImpl -import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl -import org.jetbrains.kotlin.descriptors.impl.ScriptCodeDescriptor -import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl -import org.jetbrains.kotlin.parsing.KotlinScriptDefinitionProvider -import org.jetbrains.kotlin.psi.KtScript +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.ScriptBodyResolver -import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil -import org.jetbrains.kotlin.resolve.lazy.LazyEntity +import org.jetbrains.kotlin.resolve.ScriptPriorities +import org.jetbrains.kotlin.resolve.lazy.LazyClassContext import org.jetbrains.kotlin.resolve.lazy.ResolveSession -import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl -import org.jetbrains.kotlin.resolve.scopes.receivers.ScriptReceiver +import org.jetbrains.kotlin.resolve.lazy.data.JetScriptInfo +import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider import org.jetbrains.kotlin.resolve.source.toSourceElement -import org.jetbrains.kotlin.types.DeferredType import org.jetbrains.kotlin.types.TypeSubstitutor -import org.jetbrains.kotlin.utils.sure public class LazyScriptDescriptor( private val resolveSession: ResolveSession, - scriptBodyResolver: ScriptBodyResolver, - private val jetScript: KtScript, - private val priority: Int -) : ScriptDescriptor, LazyEntity, DeclarationDescriptorNonRootImpl( - jetScript.getContainingKtFile().getPackageFqName().let { - fqName -> - resolveSession.getPackageFragment(fqName).sure { "Package not found $fqName" } - }, - Annotations.EMPTY, - ScriptDescriptor.NAME, - jetScript.toSourceElement() + containingDeclaration: DeclarationDescriptor, + name: Name, + internal val scriptInfo: JetScriptInfo +) : ScriptDescriptor, LazyClassDescriptor( + resolveSession, + containingDeclaration, + name, + scriptInfo ) { init { - resolveSession.trace.record(BindingContext.SCRIPT, jetScript, this) + resolveSession.trace.record(BindingContext.SCRIPT, scriptInfo.script, this) } - private val implicitReceiver = ReceiverParameterDescriptorImpl(this, ScriptReceiver(this)) + private val sourceElement = scriptInfo.script.toSourceElement() - override fun getThisAsReceiverParameter() = implicitReceiver + override fun getSource() = sourceElement + + private val priority: Int = ScriptPriorities.getScriptPriority(scriptInfo.script) override fun getPriority() = priority - override fun getClassDescriptor() = resolveSession.getClassDescriptorForScript(jetScript) as LazyScriptClassDescriptor - - override fun getScriptResultProperty(): PropertyDescriptor = getClassDescriptor().getUnsubstitutedMemberScope().getScriptResultProperty() - - private val scriptCodeDescriptor = resolveSession.storageManager.createLazyValue { - val result = ScriptCodeDescriptor(this) - - val file = jetScript.getContainingKtFile() - val scriptDefinition = KotlinScriptDefinitionProvider.getInstance(file.getProject()).findScriptDefinition(file) - - result.initialize( - implicitReceiver, - scriptDefinition.getScriptParameters().mapIndexed { index, scriptParameter -> - ValueParameterDescriptorImpl( - result, null, index, Annotations.EMPTY, scriptParameter.getName(), scriptParameter.getType(), - /* declaresDefaultValue = */ false, - /* isCrossinline = */ false, - /* isNoinline = */ false, - null, SourceElement.NO_SOURCE - ) - }, - DeferredType.create(resolveSession.storageManager, resolveSession.trace) { - val scope = LexicalScopeImpl( - resolveSession.fileScopeProvider.getFileResolutionScope(jetScript.getContainingKtFile()), - this, false, implicitReceiver, "Scope for body resolution for $this" - ) { - for (valueParameterDescriptor in result.valueParameters) { - addVariableDescriptor(valueParameterDescriptor) - } - } - - scriptBodyResolver.resolveScriptReturnType(jetScript, scope, resolveSession.trace) - } - ) - result - } - - override fun getScriptCodeDescriptor(): ScriptCodeDescriptor = scriptCodeDescriptor() - - override fun forceResolveAllContents() { - ForceResolveUtil.forceResolveAllContents(getClassDescriptor()) - ForceResolveUtil.forceResolveAllContents(getScriptCodeDescriptor()) - } - override fun substitute(substitutor: TypeSubstitutor) = this override fun accept(visitor: DeclarationDescriptorVisitor, data: D): R { return visitor.visitScriptDescriptor(this, data) } + + protected override fun createMemberScope( + c: LazyClassContext, + declarationProvider: ClassMemberDeclarationProvider): LazyScriptClassMemberScope { + return LazyScriptClassMemberScope( + // Must be a ResolveSession for scripts + c as ResolveSession, + declarationProvider, + this, + c.trace + ) + } + + override fun getUnsubstitutedPrimaryConstructor() = super.getUnsubstitutedPrimaryConstructor()!! } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/ScriptReceiver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/ScriptReceiver.java deleted file mode 100644 index 1bb662b37a3..00000000000 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/ScriptReceiver.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.resolve.scopes.receivers; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.descriptors.ScriptDescriptor; -import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; -import org.jetbrains.kotlin.types.KotlinType; - -public class ScriptReceiver implements ImplicitReceiver { - private final ScriptDescriptor scriptDescriptor; - - public ScriptReceiver(@NotNull ScriptDescriptor scriptDescriptor) { - this.scriptDescriptor = scriptDescriptor; - } - - @NotNull - @Override - public ScriptDescriptor getDeclarationDescriptor() { - return scriptDescriptor; - } - - @NotNull - @Override - public KotlinType getType() { - // not sure - return DescriptorUtilsKt.getBuiltIns(scriptDescriptor).getAnyType(); - } - - @Override - public boolean exists() { - return true; - } -} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java index aa1d00329f2..7217393f57b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingServices.java @@ -159,13 +159,6 @@ public class ExpressionTypingServices { List block = StatementFilterKt.filterStatements(statementFilter, expression); DeclarationDescriptor containingDescriptor = context.scope.getOwnerDescriptor(); - if (containingDescriptor instanceof ScriptDescriptor) { - if (!(expression.getParent() instanceof KtScript)) { - // top level script declarations should have ScriptDescriptor parent - // and lower level script declarations should be ScriptCodeDescriptor parent - containingDescriptor = ((ScriptDescriptor) containingDescriptor).getScriptCodeDescriptor(); - } - } LexicalWritableScope scope = new LexicalWritableScope(context.scope, containingDescriptor, false, null, new TraceBasedRedeclarationHandler(context.trace), "getBlockReturnedType"); scope.changeLockLevel(LexicalWritableScope.LockLevel.BOTH); diff --git a/compiler/tests/org/jetbrains/kotlin/test/util/RecursiveDescriptorProcessor.java b/compiler/tests/org/jetbrains/kotlin/test/util/RecursiveDescriptorProcessor.java index aec11576daf..f4f760bcc37 100644 --- a/compiler/tests/org/jetbrains/kotlin/test/util/RecursiveDescriptorProcessor.java +++ b/compiler/tests/org/jetbrains/kotlin/test/util/RecursiveDescriptorProcessor.java @@ -122,7 +122,7 @@ public class RecursiveDescriptorProcessor { @Override public Boolean visitScriptDescriptor(ScriptDescriptor scriptDescriptor, D data) { - return visitClassDescriptor(scriptDescriptor.getClassDescriptor(), data); + return visitClassDescriptor(scriptDescriptor, data); } @Override diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ScriptDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ScriptDescriptor.java index 7a9c37ebc79..97827157e68 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/ScriptDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/ScriptDescriptor.java @@ -17,24 +17,11 @@ package org.jetbrains.kotlin.descriptors; import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.descriptors.impl.ScriptCodeDescriptor; -import org.jetbrains.kotlin.name.Name; - -public interface ScriptDescriptor extends DeclarationDescriptorNonRoot { - String LAST_EXPRESSION_VALUE_FIELD_NAME = "rv"; - Name NAME = Name.special("