Support destructuring declarations in scripts and REPL
#KT-5620 In Progress #KT-15810 In Progress
This commit is contained in:
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.cli.jvm.repl
|
||||
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
|
||||
@@ -34,6 +35,9 @@ open class DelegatePackageMemberDeclarationProvider(var delegate: PackageMemberD
|
||||
|
||||
override fun getPropertyDeclarations(name: Name) = delegate.getPropertyDeclarations(name)
|
||||
|
||||
override fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry> =
|
||||
delegate.getDestructuringDeclarationsEntries(name)
|
||||
|
||||
override fun getClassOrObjectDeclarations(name: Name) = delegate.getClassOrObjectDeclarations(name)
|
||||
|
||||
override fun getTypeAliasDeclarations(name: Name) = delegate.getTypeAliasDeclarations(name)
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -126,6 +126,7 @@ class SyntheticClassOrObjectDescriptor(
|
||||
override fun getDeclarations(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List<KtDeclaration> = emptyList()
|
||||
override fun getFunctionDeclarations(name: Name): Collection<KtNamedFunction> = emptyList()
|
||||
override fun getPropertyDeclarations(name: Name): Collection<KtProperty> = emptyList()
|
||||
override fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry> = emptyList()
|
||||
override fun getClassOrObjectDeclarations(name: Name): Collection<KtClassLikeInfo> = emptyList()
|
||||
override fun getTypeAliasDeclarations(name: Name): Collection<KtTypeAlias> = emptyList()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -48,6 +48,8 @@ public interface BodiesResolveContext {
|
||||
Map<KtNamedFunction, SimpleFunctionDescriptor> getFunctions();
|
||||
@Mutable
|
||||
Map<KtTypeAlias, TypeAliasDescriptor> getTypeAliases();
|
||||
@Mutable
|
||||
Map<KtDestructuringDeclarationEntry, PropertyDescriptor> getDestructuringDeclarationEntries();
|
||||
|
||||
@Nullable
|
||||
LexicalScope getDeclaringScope(@NotNull KtDeclaration declaration);
|
||||
|
||||
@@ -110,6 +110,16 @@ class DeclarationsChecker(
|
||||
identifierChecker.checkDeclaration(property, trace)
|
||||
}
|
||||
|
||||
val destructuringDeclarations = bodiesResolveContext.destructuringDeclarationEntries.entries
|
||||
.map { (entry, _) -> entry.parent }
|
||||
.filterIsInstance<KtDestructuringDeclaration>()
|
||||
.distinct()
|
||||
|
||||
for (multiDeclaration in destructuringDeclarations) {
|
||||
modifiersChecker.checkModifiersForDestructuringDeclaration(multiDeclaration)
|
||||
identifierChecker.checkDeclaration(multiDeclaration, trace)
|
||||
}
|
||||
|
||||
for ((declaration, constructorDescriptor) in bodiesResolveContext.secondaryConstructors.entries) {
|
||||
checkConstructorDeclaration(constructorDescriptor, declaration)
|
||||
exposedChecker.checkFunction(declaration, constructorDescriptor)
|
||||
|
||||
@@ -51,6 +51,7 @@ import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension;
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.scopes.*;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||
@@ -777,6 +778,50 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PropertyDescriptor resolveDestructuringDeclarationEntryAsProperty(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@NotNull LexicalScope scopeForDeclarationResolution,
|
||||
@NotNull LexicalScope scopeForInitializerResolution,
|
||||
@NotNull KtDestructuringDeclarationEntry entry,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull DataFlowInfo dataFlowInfo
|
||||
) {
|
||||
KtDestructuringDeclaration destructuringDeclaration = (KtDestructuringDeclaration) entry.getParent();
|
||||
KtExpression initializer = destructuringDeclaration.getInitializer();
|
||||
|
||||
ExpressionTypingContext context = ExpressionTypingContext.newContext(
|
||||
trace, scopeForDeclarationResolution, dataFlowInfo, TypeUtils.NO_EXPECTED_TYPE
|
||||
);
|
||||
|
||||
ExpressionReceiver receiver = createReceiverForDestructuringDeclaration(destructuringDeclaration, context);
|
||||
|
||||
int componentIndex = destructuringDeclaration.getEntries().indexOf(entry);
|
||||
KotlinType componentType = destructuringDeclarationResolver.resolveInitializer(entry, receiver, initializer, context, componentIndex);
|
||||
|
||||
return resolveAsPropertyDescriptor(
|
||||
containingDeclaration,
|
||||
scopeForDeclarationResolution,
|
||||
scopeForInitializerResolution,
|
||||
entry,
|
||||
trace,
|
||||
dataFlowInfo,
|
||||
VariableAsPropertyInfo.Companion.createFromDestructuringDeclarationEntry(componentType));
|
||||
}
|
||||
|
||||
private ExpressionReceiver createReceiverForDestructuringDeclaration(
|
||||
@NotNull KtDestructuringDeclaration destructuringDeclaration,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
KtExpression initializer = destructuringDeclaration.getInitializer();
|
||||
if (initializer == null) return null;
|
||||
|
||||
KotlinType initializerType = expressionTypingServices.getTypeInfo(initializer, context).getType();
|
||||
if (initializerType == null) return null;
|
||||
|
||||
return ExpressionReceiver.Companion.create(initializer, initializerType, context.trace.getBindingContext());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PropertyDescriptor resolvePropertyDescriptor(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@@ -786,16 +831,37 @@ public class DescriptorResolver {
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull DataFlowInfo dataFlowInfo
|
||||
) {
|
||||
KtModifierList modifierList = property.getModifierList();
|
||||
boolean isVar = property.isVar();
|
||||
return resolveAsPropertyDescriptor(
|
||||
containingDeclaration,
|
||||
scopeForDeclarationResolution,
|
||||
scopeForInitializerResolution,
|
||||
property,
|
||||
trace,
|
||||
dataFlowInfo,
|
||||
VariableAsPropertyInfo.Companion.createFromProperty(property));
|
||||
}
|
||||
|
||||
Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration));
|
||||
@NotNull
|
||||
private PropertyDescriptor resolveAsPropertyDescriptor(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@NotNull LexicalScope scopeForDeclarationResolution,
|
||||
@NotNull LexicalScope scopeForInitializerResolution,
|
||||
@NotNull KtVariableDeclaration variableDeclaration,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull VariableAsPropertyInfo propertyInfo
|
||||
) {
|
||||
KtModifierList modifierList = variableDeclaration.getModifierList();
|
||||
boolean isVar = variableDeclaration.isVar();
|
||||
|
||||
Visibility visibility = resolveVisibilityFromModifiers(variableDeclaration, getDefaultVisibility(variableDeclaration, containingDeclaration));
|
||||
Modality modality = containingDeclaration instanceof ClassDescriptor
|
||||
? resolveMemberModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, property.hasBody()),
|
||||
? resolveMemberModalityFromModifiers(variableDeclaration,
|
||||
getDefaultModality(containingDeclaration, visibility, propertyInfo.getHasBody()),
|
||||
trace.getBindingContext(), containingDeclaration)
|
||||
: Modality.FINAL;
|
||||
|
||||
AnnotationSplitter.PropertyWrapper wrapper = new AnnotationSplitter.PropertyWrapper(property);
|
||||
AnnotationSplitter.PropertyWrapper wrapper = new AnnotationSplitter.PropertyWrapper(variableDeclaration);
|
||||
|
||||
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scopeForDeclarationResolution, modifierList, trace);
|
||||
AnnotationSplitter annotationSplitter =
|
||||
@@ -812,16 +878,16 @@ public class DescriptorResolver {
|
||||
modality,
|
||||
visibility,
|
||||
isVar,
|
||||
KtPsiUtil.safeName(property.getName()),
|
||||
KtPsiUtil.safeName(variableDeclaration.getName()),
|
||||
CallableMemberDescriptor.Kind.DECLARATION,
|
||||
KotlinSourceElementKt.toSourceElement(property),
|
||||
KotlinSourceElementKt.toSourceElement(variableDeclaration),
|
||||
modifierList != null && modifierList.hasModifier(KtTokens.LATEINIT_KEYWORD),
|
||||
modifierList != null && modifierList.hasModifier(KtTokens.CONST_KEYWORD),
|
||||
modifierList != null && modifierList.hasModifier(KtTokens.HEADER_KEYWORD) ||
|
||||
containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).isHeader(),
|
||||
modifierList != null && modifierList.hasModifier(KtTokens.IMPL_KEYWORD),
|
||||
modifierList != null && modifierList.hasModifier(KtTokens.EXTERNAL_KEYWORD),
|
||||
property.hasDelegate()
|
||||
propertyInfo.getHasDelegate()
|
||||
);
|
||||
wrapper.setDescriptor(propertyDescriptor);
|
||||
|
||||
@@ -831,7 +897,7 @@ public class DescriptorResolver {
|
||||
KotlinType receiverType = null;
|
||||
|
||||
{
|
||||
List<KtTypeParameter> typeParameters = property.getTypeParameters();
|
||||
List<KtTypeParameter> typeParameters = variableDeclaration.getTypeParameters();
|
||||
if (typeParameters.isEmpty()) {
|
||||
scopeForDeclarationResolutionWithTypeParameters = scopeForDeclarationResolution;
|
||||
scopeForInitializerResolutionWithTypeParameters = scopeForInitializerResolution;
|
||||
@@ -853,12 +919,12 @@ public class DescriptorResolver {
|
||||
}
|
||||
writableScopeForDeclarationResolution.freeze();
|
||||
writableScopeForInitializerResolution.freeze();
|
||||
resolveGenericBounds(property, propertyDescriptor, writableScopeForDeclarationResolution, typeParameterDescriptors, trace);
|
||||
resolveGenericBounds(variableDeclaration, propertyDescriptor, writableScopeForDeclarationResolution, typeParameterDescriptors, trace);
|
||||
scopeForDeclarationResolutionWithTypeParameters = writableScopeForDeclarationResolution;
|
||||
scopeForInitializerResolutionWithTypeParameters = writableScopeForInitializerResolution;
|
||||
}
|
||||
|
||||
KtTypeReference receiverTypeRef = property.getReceiverTypeReference();
|
||||
KtTypeReference receiverTypeRef = variableDeclaration.getReceiverTypeReference();
|
||||
if (receiverTypeRef != null) {
|
||||
receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true);
|
||||
}
|
||||
@@ -868,31 +934,45 @@ public class DescriptorResolver {
|
||||
DescriptorFactory.createExtensionReceiverParameterForCallable(propertyDescriptor, receiverType);
|
||||
|
||||
LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor);
|
||||
KotlinType typeIfKnown = variableTypeAndInitializerResolver.resolveTypeNullable(
|
||||
KotlinType propertyType = propertyInfo.getVariableType();
|
||||
KotlinType typeIfKnown = propertyType != null ? propertyType : variableTypeAndInitializerResolver.resolveTypeNullable(
|
||||
propertyDescriptor, scopeForInitializer,
|
||||
property, dataFlowInfo, /* local = */ trace, false
|
||||
variableDeclaration, dataFlowInfo, /* local = */ trace, false
|
||||
);
|
||||
|
||||
PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(
|
||||
scopeForDeclarationResolutionWithTypeParameters, property, propertyDescriptor, annotationSplitter, trace, typeIfKnown);
|
||||
scopeForDeclarationResolutionWithTypeParameters,
|
||||
variableDeclaration,
|
||||
propertyDescriptor,
|
||||
annotationSplitter,
|
||||
trace,
|
||||
typeIfKnown,
|
||||
propertyInfo.getPropertyGetter(),
|
||||
propertyInfo.getHasDelegate());
|
||||
|
||||
KotlinType type = typeIfKnown != null ? typeIfKnown : getter.getReturnType();
|
||||
|
||||
assert type != null : "At least getter type must be initialized via resolvePropertyGetterDescriptor";
|
||||
|
||||
variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(
|
||||
propertyDescriptor, scopeForInitializer, property, dataFlowInfo, type, trace
|
||||
propertyDescriptor, scopeForInitializer, variableDeclaration, dataFlowInfo, type, trace
|
||||
);
|
||||
|
||||
propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(containingDeclaration),
|
||||
receiverDescriptor);
|
||||
|
||||
PropertySetterDescriptor setter = resolvePropertySetterDescriptor(
|
||||
scopeForDeclarationResolutionWithTypeParameters, property, propertyDescriptor, annotationSplitter, trace);
|
||||
scopeForDeclarationResolutionWithTypeParameters,
|
||||
variableDeclaration,
|
||||
propertyDescriptor,
|
||||
annotationSplitter,
|
||||
trace,
|
||||
propertyInfo.getPropertySetter(),
|
||||
propertyInfo.getHasDelegate());
|
||||
|
||||
propertyDescriptor.initialize(getter, setter);
|
||||
|
||||
trace.record(BindingContext.VARIABLE, property, propertyDescriptor);
|
||||
trace.record(BindingContext.VARIABLE, variableDeclaration, propertyDescriptor);
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
@@ -924,12 +1004,13 @@ public class DescriptorResolver {
|
||||
@Nullable
|
||||
private PropertySetterDescriptor resolvePropertySetterDescriptor(
|
||||
@NotNull LexicalScope scopeWithTypeParameters,
|
||||
@NotNull KtProperty property,
|
||||
@NotNull KtVariableDeclaration property,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull AnnotationSplitter annotationSplitter,
|
||||
@NotNull BindingTrace trace
|
||||
@NotNull BindingTrace trace,
|
||||
@Nullable KtPropertyAccessor setter,
|
||||
boolean hasDelegate
|
||||
) {
|
||||
KtPropertyAccessor setter = property.getSetter();
|
||||
PropertySetterDescriptorImpl setterDescriptor = null;
|
||||
if (setter != null) {
|
||||
Annotations annotations = new CompositeAnnotations(CollectionsKt.listOf(
|
||||
@@ -986,7 +1067,7 @@ public class DescriptorResolver {
|
||||
}
|
||||
else if (property.isVar()) {
|
||||
Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
|
||||
setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, setterAnnotations, !property.hasDelegate(),
|
||||
setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, setterAnnotations, !hasDelegate,
|
||||
/* isExternal = */ false, property.hasModifier(KtTokens.INLINE_KEYWORD),
|
||||
propertyDescriptor.getSource());
|
||||
}
|
||||
@@ -1003,14 +1084,15 @@ public class DescriptorResolver {
|
||||
@NotNull
|
||||
private PropertyGetterDescriptorImpl resolvePropertyGetterDescriptor(
|
||||
@NotNull LexicalScope scopeForDeclarationResolution,
|
||||
@NotNull KtProperty property,
|
||||
@NotNull KtVariableDeclaration property,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull AnnotationSplitter annotationSplitter,
|
||||
@NotNull BindingTrace trace,
|
||||
@Nullable KotlinType propertyTypeIfKnown
|
||||
@Nullable KotlinType propertyTypeIfKnown,
|
||||
@Nullable KtPropertyAccessor getter,
|
||||
boolean hasDelegate
|
||||
) {
|
||||
PropertyGetterDescriptorImpl getterDescriptor;
|
||||
KtPropertyAccessor getter = property.getGetter();
|
||||
KotlinType getterType;
|
||||
if (getter != null) {
|
||||
Annotations getterAnnotations = new CompositeAnnotations(CollectionsKt.listOf(
|
||||
@@ -1031,7 +1113,7 @@ public class DescriptorResolver {
|
||||
}
|
||||
else {
|
||||
Annotations getterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_GETTER);
|
||||
getterDescriptor = DescriptorFactory.createGetter(propertyDescriptor, getterAnnotations, !property.hasDelegate(),
|
||||
getterDescriptor = DescriptorFactory.createGetter(propertyDescriptor, getterAnnotations, !hasDelegate,
|
||||
/* isExternal = */ false, property.hasModifier(KtTokens.INLINE_KEYWORD));
|
||||
getterType = propertyTypeIfKnown;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -62,6 +62,7 @@ class LazyTopDownAnalyzer(
|
||||
val properties = ArrayList<KtProperty>()
|
||||
val functions = ArrayList<KtNamedFunction>()
|
||||
val typeAliases = ArrayList<KtTypeAlias>()
|
||||
val destructuringDeclarations = ArrayList<KtDestructuringDeclaration>()
|
||||
|
||||
// fill in the context
|
||||
for (declaration in declarations) {
|
||||
@@ -168,7 +169,9 @@ class LazyTopDownAnalyzer(
|
||||
}
|
||||
|
||||
override fun visitDestructuringDeclaration(destructuringDeclaration: KtDestructuringDeclaration) {
|
||||
// Ignore: multi-declarations are only allowed locally
|
||||
if (destructuringDeclaration.containingKtFile.isScript) {
|
||||
destructuringDeclarations.add(destructuringDeclaration)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitNamedFunction(function: KtNamedFunction) {
|
||||
@@ -191,6 +194,8 @@ class LazyTopDownAnalyzer(
|
||||
|
||||
createPropertyDescriptors(c, topLevelFqNames, properties)
|
||||
|
||||
createPropertiesFromDestructuringDeclarations(c, topLevelFqNames, destructuringDeclarations)
|
||||
|
||||
createTypeAliasDescriptors(c, topLevelFqNames, typeAliases)
|
||||
|
||||
resolveAllHeadersInClasses(c)
|
||||
@@ -258,6 +263,21 @@ class LazyTopDownAnalyzer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPropertiesFromDestructuringDeclarations(
|
||||
c: TopDownAnalysisContext,
|
||||
topLevelFqNames: Multimap<FqName, KtElement>,
|
||||
destructuringDeclarations: List<KtDestructuringDeclaration>) {
|
||||
for (destructuringDeclaration in destructuringDeclarations) {
|
||||
for (entry in destructuringDeclaration.entries) {
|
||||
val descriptor = lazyDeclarationResolver.resolveToDescriptor(entry) as PropertyDescriptor
|
||||
|
||||
c.destructuringDeclarationEntries[entry] = descriptor
|
||||
ForceResolveUtil.forceResolveAllContents(descriptor.annotations)
|
||||
registerTopLevelFqName(topLevelFqNames, entry, descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerTopLevelFqName(topLevelFqNames: Multimap<FqName, KtElement>, declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor) {
|
||||
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||
val fqName = declaration.fqName
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -46,6 +46,7 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
|
||||
private final Map<KtProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
|
||||
private final Map<KtParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap();
|
||||
private final Map<KtTypeAlias, TypeAliasDescriptor> typeAliases = Maps.newLinkedHashMap();
|
||||
private final Map<KtDestructuringDeclarationEntry, PropertyDescriptor> destructuringDeclarationEntries = Maps.newLinkedHashMap();
|
||||
private Map<KtCallableDeclaration, CallableMemberDescriptor> members = null;
|
||||
|
||||
private final Map<KtScript, LazyScriptDescriptor> scripts = Maps.newLinkedHashMap();
|
||||
@@ -145,6 +146,11 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
|
||||
return typeAliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<KtDestructuringDeclarationEntry, PropertyDescriptor> getDestructuringDeclarationEntries() {
|
||||
return destructuringDeclarationEntries;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<KtCallableDeclaration, CallableMemberDescriptor> getMembers() {
|
||||
if (members == null) {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class VariableAsPropertyInfo(
|
||||
val propertyGetter: KtPropertyAccessor?,
|
||||
val propertySetter: KtPropertyAccessor?,
|
||||
val variableType: KotlinType?,
|
||||
val hasBody: Boolean,
|
||||
val hasDelegate: Boolean
|
||||
) {
|
||||
companion object {
|
||||
fun createFromDestructuringDeclarationEntry(type: KotlinType): VariableAsPropertyInfo {
|
||||
return VariableAsPropertyInfo(null, null, type, false, false)
|
||||
}
|
||||
|
||||
fun createFromProperty(property: KtProperty): VariableAsPropertyInfo {
|
||||
return VariableAsPropertyInfo(property.getter, property.setter, null, property.hasBody(), property.hasDelegate())
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -224,6 +224,17 @@ public class LazyDeclarationResolver {
|
||||
return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor visitDestructuringDeclarationEntry(
|
||||
@NotNull KtDestructuringDeclarationEntry destructuringDeclarationEntry, Void data
|
||||
) {
|
||||
LookupLocation location = lookupLocationFor(destructuringDeclarationEntry, false);
|
||||
KtDestructuringDeclaration destructuringDeclaration = ((KtDestructuringDeclaration) destructuringDeclarationEntry.getParent());
|
||||
MemberScope scopeForDeclaration = getMemberScopeDeclaredIn(destructuringDeclaration, location);
|
||||
scopeForDeclaration.getContributedVariables(destructuringDeclarationEntry.getNameAsSafeName(), location);
|
||||
return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, destructuringDeclarationEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeclarationDescriptor visitTypeAlias(@NotNull KtTypeAlias typeAlias, Void data) {
|
||||
LookupLocation location = lookupLocationFor(typeAlias, typeAlias.isTopLevel());
|
||||
|
||||
+11
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -37,6 +37,7 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage
|
||||
val properties = ArrayListMultimap.create<Name, KtProperty>()
|
||||
val classesAndObjects = ArrayListMultimap.create<Name, KtClassLikeInfo>() // order matters here
|
||||
val typeAliases = ArrayListMultimap.create<Name, KtTypeAlias>()
|
||||
val destructuringDeclarationsEntries = ArrayListMultimap.create<Name, KtDestructuringDeclarationEntry>()
|
||||
|
||||
fun putToIndex(declaration: KtDeclaration) {
|
||||
if (declaration is KtAnonymousInitializer || declaration is KtSecondaryConstructor) return
|
||||
@@ -55,7 +56,12 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage
|
||||
val scriptInfo = KtScriptInfo(declaration)
|
||||
classesAndObjects.put(scriptInfo.script.nameAsName, scriptInfo)
|
||||
}
|
||||
is KtParameter, is KtDestructuringDeclaration -> {
|
||||
is KtDestructuringDeclaration -> {
|
||||
for (entry in declaration.entries) {
|
||||
destructuringDeclarationsEntries.put(safeNameForLazyResolve(entry.nameAsName), entry)
|
||||
}
|
||||
}
|
||||
is KtParameter -> {
|
||||
// Do nothing, just put it into allDeclarations is enough
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unknown declaration: " + declaration)
|
||||
@@ -80,6 +86,9 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage
|
||||
override fun getPropertyDeclarations(name: Name): List<KtProperty>
|
||||
= index().properties[ResolveSessionUtils.safeNameForLazyResolve(name)].toList()
|
||||
|
||||
override fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry>
|
||||
= index().destructuringDeclarationsEntries[ResolveSessionUtils.safeNameForLazyResolve(name)].toList()
|
||||
|
||||
override fun getClassOrObjectDeclarations(name: Name): Collection<KtClassLikeInfo>
|
||||
= index().classesAndObjects[ResolveSessionUtils.safeNameForLazyResolve(name)]
|
||||
|
||||
|
||||
+6
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve.lazy.declarations
|
||||
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
|
||||
class CombinedPackageMemberDeclarationProvider(val providers: Collection<PackageMemberDeclarationProvider>) : PackageMemberDeclarationProvider {
|
||||
@@ -31,6 +32,10 @@ class CombinedPackageMemberDeclarationProvider(val providers: Collection<Package
|
||||
|
||||
override fun getPropertyDeclarations(name: Name) = providers.flatMap { it.getPropertyDeclarations(name) }
|
||||
|
||||
override fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry> {
|
||||
return providers.flatMap { it.getDestructuringDeclarationsEntries(name) }
|
||||
}
|
||||
|
||||
override fun getClassOrObjectDeclarations(name: Name) = providers.flatMap { it.getClassOrObjectDeclarations(name) }
|
||||
|
||||
override fun getTypeAliasDeclarations(name: Name) = providers.flatMap { it.getTypeAliasDeclarations(name) }
|
||||
|
||||
+5
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -16,12 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.lazy.declarations
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtTypeAlias
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
|
||||
interface DeclarationProvider {
|
||||
@@ -31,6 +28,8 @@ interface DeclarationProvider {
|
||||
|
||||
fun getPropertyDeclarations(name: Name): Collection<KtProperty>
|
||||
|
||||
fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry>
|
||||
|
||||
fun getClassOrObjectDeclarations(name: Name): Collection<KtClassLikeInfo>
|
||||
|
||||
fun getTypeAliasDeclarations(name: Name): Collection<KtTypeAlias>
|
||||
|
||||
+12
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -128,6 +128,17 @@ protected constructor(
|
||||
result.add(propertyDescriptor)
|
||||
}
|
||||
|
||||
for (entry in declarationProvider.getDestructuringDeclarationsEntries(name)) {
|
||||
val propertyDescriptor = c.descriptorResolver.resolveDestructuringDeclarationEntryAsProperty(
|
||||
thisDescriptor,
|
||||
getScopeForMemberDeclarationResolution(entry),
|
||||
getScopeForInitializerResolution(entry),
|
||||
entry,
|
||||
trace,
|
||||
c.declarationScopeProvider.getOuterDataFlowInfoForDeclaration(entry))
|
||||
result.add(propertyDescriptor)
|
||||
}
|
||||
|
||||
getNonDeclaredProperties(name, result)
|
||||
|
||||
return result.toList()
|
||||
|
||||
+12
-3
@@ -49,9 +49,7 @@ class DestructuringDeclarationResolver(
|
||||
): List<VariableDescriptor> {
|
||||
val result = arrayListOf<VariableDescriptor>()
|
||||
for ((componentIndex, entry) in destructuringDeclaration.entries.withIndex()) {
|
||||
val componentName = DataClassDescriptorResolver.createComponentName(componentIndex + 1)
|
||||
|
||||
val componentType = resolveComponentFunctionAndGetType(componentName, context, entry, receiver, initializer)
|
||||
val componentType = resolveInitializer(entry, receiver, initializer, context, componentIndex)
|
||||
val variableDescriptor = localVariableResolver.resolveLocalVariableDescriptorWithType(scope, entry, componentType, context.trace)
|
||||
|
||||
result.add(variableDescriptor)
|
||||
@@ -73,6 +71,17 @@ class DestructuringDeclarationResolver(
|
||||
writableScope.addVariableDescriptor(it)
|
||||
}
|
||||
|
||||
fun resolveInitializer(
|
||||
entry: KtDestructuringDeclarationEntry,
|
||||
receiver: ReceiverValue?,
|
||||
initializer: KtExpression?,
|
||||
context: ExpressionTypingContext,
|
||||
componentIndex: Int
|
||||
): KotlinType {
|
||||
val componentName = DataClassDescriptorResolver.createComponentName(componentIndex + 1)
|
||||
return resolveComponentFunctionAndGetType(componentName, context, entry, receiver, initializer)
|
||||
}
|
||||
|
||||
private fun resolveComponentFunctionAndGetType(
|
||||
componentName: Name,
|
||||
context: ExpressionTypingContext,
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
val (a1, a2) = A()
|
||||
val (b1: Int, b2: Int) = <!COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH!>A()<!>
|
||||
val (c1) = <!UNRESOLVED_REFERENCE!>unresolved<!>
|
||||
|
||||
<!WRONG_MODIFIER_TARGET!>private<!> val (d1) = A()
|
||||
|
||||
val (e1, _) = A()
|
||||
|
||||
a1
|
||||
a2
|
||||
e1
|
||||
|
||||
class A {
|
||||
operator fun component1() = 1
|
||||
operator fun component2() = ""
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package
|
||||
|
||||
public final class DestructuringDeclarationsScript : kotlin.script.templates.standard.ScriptTemplateWithArgs {
|
||||
public constructor DestructuringDeclarationsScript(/*0*/ args: kotlin.Array<kotlin.String>)
|
||||
public final override /*1*/ /*fake_override*/ val args: kotlin.Array<kotlin.String>
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public final class A {
|
||||
public constructor A()
|
||||
public final operator fun component1(): kotlin.Int
|
||||
public final operator fun component2(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
val (a, b, c) = A(<!NO_VALUE_FOR_PARAMETER!>)<!>
|
||||
|
||||
class A(val a: Int) {
|
||||
operator fun component1() {}
|
||||
operator fun component2() {}
|
||||
operator fun component3() {}
|
||||
}
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
package
|
||||
|
||||
public final class ResolveInitializerOfDestructuringDeclarationOnce : kotlin.script.templates.standard.ScriptTemplateWithArgs {
|
||||
public constructor ResolveInitializerOfDestructuringDeclarationOnce(/*0*/ args: kotlin.Array<kotlin.String>)
|
||||
public final override /*1*/ /*fake_override*/ val args: kotlin.Array<kotlin.String>
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public final class A {
|
||||
public constructor A(/*0*/ a: kotlin.Int)
|
||||
public final val a: kotlin.Int
|
||||
public final operator fun component1(): kotlin.Unit
|
||||
public final operator fun component2(): kotlin.Unit
|
||||
public final operator fun component3(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
@@ -23576,6 +23576,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("destructuringDeclarationsScript.kts")
|
||||
public void testDestructuringDeclarationsScript() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/script/destructuringDeclarationsScript.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("imports.kts")
|
||||
public void testImports() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/script/imports.kts");
|
||||
@@ -23588,6 +23594,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("resolveInitializerOfDestructuringDeclarationOnce.kts")
|
||||
public void testResolveInitializerOfDestructuringDeclarationOnce() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/script/resolveInitializerOfDestructuringDeclarationOnce.kts");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SimpleScript.kts")
|
||||
public void testSimpleScript() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/script/SimpleScript.kts");
|
||||
|
||||
@@ -617,6 +617,8 @@ class ResolveElementCache(
|
||||
|
||||
override fun getTypeAliases(): MutableMap<KtTypeAlias, TypeAliasDescriptor> = hashMapOf()
|
||||
|
||||
override fun getDestructuringDeclarationEntries(): MutableMap<KtDestructuringDeclarationEntry, PropertyDescriptor> = hashMapOf()
|
||||
|
||||
override fun getDeclaringScope(declaration: KtDeclaration): LexicalScope? = declaringScopes(declaration)
|
||||
|
||||
override fun getScripts(): MutableMap<KtScript, LazyScriptDescriptor> = hashMapOf()
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 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.
|
||||
@@ -85,6 +85,10 @@ class StubBasedPackageMemberDeclarationProvider(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun getAllDeclaredSubPackages(nameFilter: (Name) -> Boolean): Collection<FqName> {
|
||||
return PackageIndexUtil.getSubPackageFqNames(fqName, searchScope, project, nameFilter)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user