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)
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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<KtSecondaryConstructor, ConstructorDescriptor> getSecondaryConstructors();
|
||||
@Mutable
|
||||
Map<KtScript, ScriptDescriptor> getScripts();
|
||||
Map<KtScript, LazyScriptDescriptor> getScripts();
|
||||
|
||||
@Mutable
|
||||
Map<KtProperty, PropertyDescriptor> getProperties();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<KtClassOrObject>(initializer, javaClass<KtClassOrObject>())!!
|
||||
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) {
|
||||
|
||||
@@ -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<KtScript, ScriptDescriptor> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<KtParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap();
|
||||
private Map<KtCallableDeclaration, CallableMemberDescriptor> members = null;
|
||||
|
||||
private final Map<KtScript, ScriptDescriptor> scripts = Maps.newLinkedHashMap();
|
||||
private final Map<KtScript, LazyScriptDescriptor> scripts = Maps.newLinkedHashMap();
|
||||
|
||||
private final TopDownAnalysisMode topDownAnalysisMode;
|
||||
private final DeclarationScopeProvider declarationScopeProvider;
|
||||
@@ -115,7 +115,7 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Map<KtScript, ScriptDescriptor> getScripts() {
|
||||
public Map<KtScript, LazyScriptDescriptor> getScripts() {
|
||||
return scripts;
|
||||
}
|
||||
|
||||
@@ -158,15 +158,6 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
|
||||
|
||||
@NotNull
|
||||
public Collection<ClassDescriptorWithResolutionScopes> getAllClasses() {
|
||||
Collection<ClassDescriptorWithResolutionScopes> scriptClasses = CollectionsKt.map(
|
||||
getScripts().values(),
|
||||
new Function1<ScriptDescriptor, ClassDescriptorWithResolutionScopes>() {
|
||||
@Override
|
||||
public ClassDescriptorWithResolutionScopes invoke(ScriptDescriptor scriptDescriptor) {
|
||||
return (ClassDescriptorWithResolutionScopes) scriptDescriptor.getClassDescriptor();
|
||||
}
|
||||
}
|
||||
);
|
||||
return CollectionsKt.plus(getDeclaredClasses().values(), scriptClasses);
|
||||
return CollectionsKt.plus(getDeclaredClasses().values(), getScripts().values());
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -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));
|
||||
|
||||
+27
-10
@@ -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<completion here>}
|
||||
// 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));
|
||||
}
|
||||
|
||||
@@ -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<FqName, LazyPackageDescriptor> packages;
|
||||
private final PackageFragmentProvider packageFragmentProvider;
|
||||
|
||||
private final MemoizedFunctionToNotNull<KtScript, LazyScriptDescriptor> scriptDescriptors;
|
||||
|
||||
private final MemoizedFunctionToNotNull<KtFile, LazyAnnotations> fileAnnotations;
|
||||
private final MemoizedFunctionToNotNull<KtFile, LazyAnnotations> 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<KtScript, LazyScriptDescriptor>() {
|
||||
@Override
|
||||
public LazyScriptDescriptor invoke(KtScript script) {
|
||||
return new LazyScriptDescriptor(
|
||||
ResolveSession.this,
|
||||
scriptBodyResolver,
|
||||
script,
|
||||
ScriptPriorities.getScriptPriority(script)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
fileAnnotations = storageManager.createMemoizedFunction(new Function1<KtFile, LazyAnnotations>() {
|
||||
@Override
|
||||
public LazyAnnotations invoke(KtFile file) {
|
||||
@@ -267,12 +245,18 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
|
||||
new Function<JetClassLikeInfo, ClassDescriptor>() {
|
||||
@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
|
||||
|
||||
@@ -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<ClassDescriptor>
|
||||
}
|
||||
|
||||
@@ -38,10 +34,6 @@ public object NoTopLevelDescriptorProvider : TopLevelDescriptorProvider {
|
||||
shouldNotBeCalled()
|
||||
}
|
||||
|
||||
override fun getScriptDescriptor(script: KtScript): ScriptDescriptor {
|
||||
shouldNotBeCalled()
|
||||
}
|
||||
|
||||
override fun getTopLevelClassDescriptors(fqName: FqName, location: LookupLocation): Collection<ClassDescriptor> {
|
||||
shouldNotBeCalled()
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ public abstract class JetClassOrObjectInfo<E extends KtClassOrObject> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public KtClassOrObject getCorrespondingClassOrObject() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@@ -34,14 +34,5 @@ public class JetScriptInfo(
|
||||
override fun getPrimaryConstructorParameters() = listOf<KtParameter>()
|
||||
override fun getClassKind() = ClassKind.CLASS
|
||||
override fun getDeclarations() = script.getDeclarations()
|
||||
.filter(::shouldBeScriptClassMember)
|
||||
override fun getDanglingAnnotations() = listOf<KtAnnotationEntry>()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -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<ClassDescriptor> {
|
||||
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()
|
||||
|
||||
-66
@@ -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;
|
||||
}
|
||||
}
|
||||
+48
-84
@@ -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<PropertyDescriptor> = resolveSession.storageManager.createLazyValue {
|
||||
val scriptInfo = declarationProvider.getOwnerInfo() as JetScriptInfo
|
||||
createScriptResultProperty(resolveSession.getScriptDescriptor(scriptInfo.script))
|
||||
}
|
||||
|
||||
override fun computeExtraDescriptors(location: LookupLocation): Collection<DeclarationDescriptor> {
|
||||
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<PropertyDescriptor>) {
|
||||
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<PropertyDescriptor>) {
|
||||
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<TypeParameterDescriptor>(),
|
||||
scriptDescriptor.getThisAsReceiverParameter(),
|
||||
null as ReceiverParameterDescriptor?
|
||||
)
|
||||
propertyDescriptor.initialize(null, null)
|
||||
|
||||
return propertyDescriptor
|
||||
private fun createScriptParameters(constructor: ConstructorDescriptorImpl): List<ValueParameterDescriptor> {
|
||||
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<ValueParameterDescriptor>): ConstructorDescriptorImpl {
|
||||
return ConstructorDescriptorImpl.create(
|
||||
scriptDescriptor.getClassDescriptor(),
|
||||
Annotations.EMPTY,
|
||||
true,
|
||||
SourceElement.NO_SOURCE
|
||||
).initialize(
|
||||
valueParameters,
|
||||
Visibilities.PUBLIC
|
||||
)
|
||||
override fun computeExtraDescriptors(location: LookupLocation): Collection<DeclarationDescriptor> {
|
||||
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<PropertyDescriptor>) {
|
||||
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,
|
||||
|
||||
+33
-76
@@ -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 <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, 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()!!
|
||||
}
|
||||
|
||||
-48
@@ -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;
|
||||
}
|
||||
}
|
||||
-7
@@ -159,13 +159,6 @@ public class ExpressionTypingServices {
|
||||
List<KtExpression> 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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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("<script>");
|
||||
|
||||
public interface ScriptDescriptor extends ClassDescriptor {
|
||||
int getPriority();
|
||||
|
||||
@NotNull
|
||||
ScriptCodeDescriptor getScriptCodeDescriptor();
|
||||
|
||||
@NotNull
|
||||
ReceiverParameterDescriptor getThisAsReceiverParameter();
|
||||
|
||||
@NotNull
|
||||
ClassDescriptor getClassDescriptor();
|
||||
|
||||
@NotNull
|
||||
PropertyDescriptor getScriptResultProperty();
|
||||
@Override
|
||||
ConstructorDescriptor getUnsubstitutedPrimaryConstructor();
|
||||
}
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ public class DeclarationDescriptorVisitorEmptyBodies<R, D> implements Declaratio
|
||||
|
||||
@Override
|
||||
public R visitScriptDescriptor(ScriptDescriptor scriptDescriptor, D data) {
|
||||
return visitDeclarationDescriptor(scriptDescriptor, data);
|
||||
return visitClassDescriptor(scriptDescriptor, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,75 +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.descriptors.impl;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ScriptCodeDescriptor extends FunctionDescriptorImpl {
|
||||
|
||||
public ScriptCodeDescriptor(@NotNull ScriptDescriptor containingDeclaration) {
|
||||
super(containingDeclaration, null, Annotations.Companion.getEMPTY(), Name.special("<script-code>"), Kind.DECLARATION, SourceElement.NO_SOURCE);
|
||||
}
|
||||
|
||||
public void initialize(
|
||||
@NotNull ReceiverParameterDescriptor dispatchReceiverParameter,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters,
|
||||
@NotNull KotlinType returnType) {
|
||||
super.initialize(null, dispatchReceiverParameter, Collections.<TypeParameterDescriptor>emptyList(), valueParameters, returnType,
|
||||
Modality.FINAL, Visibilities.INTERNAL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected FunctionDescriptorImpl createSubstitutedCopy(
|
||||
@NotNull DeclarationDescriptor newOwner,
|
||||
@Nullable FunctionDescriptor original,
|
||||
@NotNull Kind kind,
|
||||
@Nullable Name newName,
|
||||
boolean preserveSource
|
||||
) {
|
||||
throw new IllegalStateException("no need to copy script code descriptor");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides) {
|
||||
throw new IllegalStateException("no need to copy script code descriptor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExternal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInline() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTailrec() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -872,10 +872,6 @@ internal class DescriptorRendererImpl(
|
||||
|
||||
|
||||
/* OTHER */
|
||||
private fun renderModuleOrScript(moduleOrScript: DeclarationDescriptor, builder: StringBuilder) {
|
||||
renderName(moduleOrScript, builder)
|
||||
}
|
||||
|
||||
private fun renderPackageView(packageView: PackageViewDescriptor, builder: StringBuilder) {
|
||||
builder.append(renderKeyword("package")).append(" ")
|
||||
builder.append(renderFqName(packageView.fqName.toUnsafe()))
|
||||
@@ -962,11 +958,11 @@ internal class DescriptorRendererImpl(
|
||||
}
|
||||
|
||||
override fun visitModuleDeclaration(descriptor: ModuleDescriptor, builder: StringBuilder) {
|
||||
renderModuleOrScript(descriptor, builder)
|
||||
renderName(descriptor, builder)
|
||||
}
|
||||
|
||||
override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor, builder: StringBuilder) {
|
||||
renderModuleOrScript(scriptDescriptor, builder)
|
||||
visitClassDescriptor(scriptDescriptor, builder)
|
||||
}
|
||||
|
||||
override fun visitClassDescriptor(descriptor: ClassDescriptor, builder: StringBuilder) {
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.resolve.*
|
||||
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.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
@@ -491,8 +492,7 @@ public class ResolveElementCache(
|
||||
private fun initializerAdditionalResolve(resolveSession: ResolveSession, classInitializer: KtClassInitializer, file: KtFile, statementFilter: StatementFilter): BindingTrace {
|
||||
val trace = createDelegatingTrace(classInitializer)
|
||||
|
||||
val classOrObject = classInitializer.getParentOfType<KtClassOrObject>(true)!!
|
||||
val classOrObjectDescriptor = resolveSession.resolveToDescriptor(classOrObject) as LazyClassDescriptor
|
||||
val classOrObjectDescriptor = resolveSession.resolveToDescriptor(classInitializer.containingDeclaration) as LazyClassDescriptor
|
||||
|
||||
val bodyResolver = createBodyResolver(resolveSession, trace, file, statementFilter)
|
||||
bodyResolver.resolveAnonymousInitializer(DataFlowInfo.EMPTY, classInitializer, classOrObjectDescriptor)
|
||||
@@ -550,7 +550,7 @@ public class ResolveElementCache(
|
||||
|
||||
override fun getDeclaringScope(declaration: KtDeclaration): LexicalScope? = declaringScopes(declaration)
|
||||
|
||||
override fun getScripts(): MutableMap<KtScript, ScriptDescriptor> = hashMapOf()
|
||||
override fun getScripts(): MutableMap<KtScript, LazyScriptDescriptor> = hashMapOf()
|
||||
|
||||
override fun getOuterDataFlowInfo(): DataFlowInfo = DataFlowInfo.EMPTY
|
||||
|
||||
|
||||
+9
-9
@@ -22,19 +22,14 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.JetClassLikeInfo
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.JetClassInfoUtil
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionByPackageIndex
|
||||
import com.intellij.psi.stubs.StringStubIndexExtension
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelPropertyByPackageIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelPropertyFqnNameIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelClassByPackageIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.JetScriptInfo
|
||||
|
||||
public class StubBasedPackageMemberDeclarationProvider(
|
||||
private val fqName: FqName,
|
||||
@@ -65,8 +60,13 @@ public class StubBasedPackageMemberDeclarationProvider(
|
||||
}
|
||||
|
||||
override fun getClassOrObjectDeclarations(name: Name): Collection<JetClassLikeInfo> {
|
||||
return KotlinFullClassNameIndex.getInstance().get(childName(name), project, searchScope)
|
||||
.map { JetClassInfoUtil.createClassLikeInfo(it) }
|
||||
val result = ArrayList<JetClassLikeInfo>()
|
||||
KotlinFullClassNameIndex.getInstance().get(childName(name), project, searchScope)
|
||||
.mapTo(result) { JetClassInfoUtil.createClassLikeInfo(it) }
|
||||
|
||||
KotlinScriptFqnIndex.instance.get(childName(name), project, searchScope)
|
||||
.mapTo(result) { JetScriptInfo(it) }
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getFunctionDeclarations(name: Name): Collection<KtNamedFunction> {
|
||||
|
||||
Reference in New Issue
Block a user