Pluggable Synthetic Objects

This commit is contained in:
Roman Elizarov
2016-11-03 12:54:25 +03:00
parent 7a4b6a1462
commit 8affb2726f
50 changed files with 731 additions and 222 deletions
@@ -16,10 +16,10 @@
package org.jetbrains.kotlin.extensions
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.project.Project
import com.intellij.openapi.extensions.ExtensionPoint
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
open class ProjectExtensionDescriptor<T>(name: String, private val extensionClass: Class<T>) {
val extensionPointName: ExtensionPointName<T> = ExtensionPointName.create(name)!!
@@ -36,7 +36,7 @@ open class ProjectExtensionDescriptor<T>(name: String, private val extensionClas
Extensions.getArea(project).getExtensionPoint(extensionPointName).registerExtension(extension)
}
fun getInstances(project: Project): Collection<T> {
fun getInstances(project: Project): List<T> {
val projectArea = Extensions.getArea(project)
if (!projectArea.hasExtensionPoint(extensionPointName.name!!)) return listOf()
@@ -83,7 +83,7 @@ open class KtClass : KtClassOrObject {
return StringUtil.join(parts, ".")
}
fun getCompanionObjects(): List<KtObjectDeclaration> = getBody()?.allCompanionObjects.orEmpty()
override fun getCompanionObjects(): List<KtObjectDeclaration> = getBody()?.allCompanionObjects.orEmpty()
fun getClassOrInterfaceKeyword(): PsiElement? = findChildByType(TokenSet.create(KtTokens.CLASS_KEYWORD, KtTokens.INTERFACE_KEYWORD))
}
@@ -29,12 +29,13 @@ import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
abstract class KtClassOrObject :
KtTypeParameterListOwnerStub<KotlinClassOrObjectStub<out KtClassOrObject>>, KtDeclarationContainer, KtNamedDeclaration {
KtTypeParameterListOwnerStub<KotlinClassOrObjectStub<out KtClassOrObject>>, KtDeclarationContainer, KtNamedDeclaration, KtPureClassOrObject {
constructor(node: ASTNode) : super(node)
constructor(stub: KotlinClassOrObjectStub<out KtClassOrObject>, nodeType: IStubElementType<*, *>) : super(stub, nodeType)
fun getSuperTypeList(): KtSuperTypeList? = getStubOrPsiChild(KtStubElementTypes.SUPER_TYPE_LIST)
open fun getSuperTypeListEntries(): List<KtSuperTypeListEntry> = getSuperTypeList()?.entries.orEmpty()
override fun getSuperTypeListEntries(): List<KtSuperTypeListEntry> = getSuperTypeList()?.entries.orEmpty()
fun addSuperTypeListEntry(superTypeListEntry: KtSuperTypeListEntry): KtSuperTypeListEntry {
getSuperTypeList()?.let {
@@ -42,7 +43,7 @@ abstract class KtClassOrObject :
if (single != null && single.typeReference?.typeElement == null) {
return single.replace(superTypeListEntry) as KtSuperTypeListEntry
}
return EditCommaSeparatedListHelper.addItem(it, getSuperTypeListEntries(), superTypeListEntry)
return EditCommaSeparatedListHelper.addItem(it, superTypeListEntries, superTypeListEntry)
}
val psiFactory = KtPsiFactory(this)
@@ -85,31 +86,34 @@ abstract class KtClassOrObject :
fun isTopLevel(): Boolean = stub?.isTopLevel() ?: (parent == null || parent is KtFile)
fun isLocal(): Boolean = stub?.isLocal() ?: KtPsiUtil.isLocal(this)
override fun getDeclarations() = getBody()?.declarations.orEmpty()
override fun isLocal(): Boolean = stub?.isLocal() ?: KtPsiUtil.isLocal(this)
override fun getDeclarations(): List<KtDeclaration> = getBody()?.declarations.orEmpty()
override fun getPresentation(): ItemPresentation? = ItemPresentationProviders.getItemPresentation(this)
fun getPrimaryConstructor(): KtPrimaryConstructor? = getStubOrPsiChild(KtStubElementTypes.PRIMARY_CONSTRUCTOR)
override fun getPrimaryConstructor(): KtPrimaryConstructor? = getStubOrPsiChild(KtStubElementTypes.PRIMARY_CONSTRUCTOR)
fun getPrimaryConstructorModifierList(): KtModifierList? = getPrimaryConstructor()?.modifierList
fun getPrimaryConstructorParameterList(): KtParameterList? = getPrimaryConstructor()?.valueParameterList
fun getPrimaryConstructorParameters(): List<KtParameter> = getPrimaryConstructorParameterList()?.parameters.orEmpty()
override fun getPrimaryConstructorModifierList(): KtModifierList? = primaryConstructor?.modifierList
fun hasExplicitPrimaryConstructor(): Boolean = getPrimaryConstructor() != null
fun getPrimaryConstructorParameterList(): KtParameterList? = primaryConstructor?.valueParameterList
override fun getPrimaryConstructorParameters(): List<KtParameter> = getPrimaryConstructorParameterList()?.parameters.orEmpty()
override fun hasExplicitPrimaryConstructor(): Boolean = primaryConstructor != null
override fun hasPrimaryConstructor(): Boolean = hasExplicitPrimaryConstructor() || !hasSecondaryConstructors()
fun hasPrimaryConstructor(): Boolean = hasExplicitPrimaryConstructor() || !hasSecondaryConstructors()
private fun hasSecondaryConstructors(): Boolean = !getSecondaryConstructors().isEmpty()
fun getSecondaryConstructors(): List<KtSecondaryConstructor> = getBody()?.secondaryConstructors.orEmpty()
override fun getSecondaryConstructors(): List<KtSecondaryConstructor> = getBody()?.secondaryConstructors.orEmpty()
fun isAnnotation(): Boolean = hasModifier(KtTokens.ANNOTATION_KEYWORD)
override fun delete() {
CheckUtil.checkWritable(this)
val file = getContainingKtFile()
val file = containingKtFile
if (!isTopLevel() || file.declarations.size > 1) {
super.delete()
}
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.psi
import com.intellij.psi.NavigatablePsiElement
import com.intellij.psi.PsiReference
interface KtElement : NavigatablePsiElement {
fun getContainingKtFile(): KtFile
interface KtElement : NavigatablePsiElement, KtPureElement {
fun <D> acceptChildren(visitor: KtVisitor<Void, D>, data: D)
fun <R, D> accept(visitor: KtVisitor<R, D>, data: D): R
@@ -90,4 +90,10 @@ public class KtElementImpl extends ASTWrapperPsiElement implements KtElement {
public PsiReference[] getReferences() {
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
}
@NotNull
@Override
public KtElement getPsiOrParent() {
return this;
}
}
@@ -111,4 +111,10 @@ public class KtElementImplStub<T extends StubElement<?>> extends StubBasedPsiEle
) {
return Arrays.asList(getStubOrPsiChildren(elementType, elementType.getArrayFactory()));
}
@NotNull
@Override
public KtElement getPsiOrParent() {
return this;
}
}
@@ -283,4 +283,10 @@ public class KtFile extends PsiFileBase implements KtDeclarationContainer, KtAnn
}
return result;
}
@NotNull
@Override
public KtElement getPsiOrParent() {
return this;
}
}
@@ -98,4 +98,10 @@ public class KtLambdaExpression extends LazyParseablePsiElement implements KtExp
public String toString() {
return getNode().getElementType().toString();
}
@NotNull
@Override
public KtElement getPsiOrParent() {
return this;
}
}
@@ -67,4 +67,6 @@ class KtObjectDeclaration : KtClassOrObject {
fun isObjectLiteral(): Boolean = _stub?.isObjectLiteral() ?: (parent is KtObjectLiteralExpression)
fun getObjectKeyword(): PsiElement? = findChildByType(KtTokens.OBJECT_KEYWORD)
override fun getCompanionObjects(): List<KtObjectDeclaration> = emptyList()
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2016 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.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import java.util.List;
/**
* A minimal interface that {@link KtClassOrObject} implements for the purpose of code-generation that does not need the full power of PSI.
* This interface can be easily implemented by synthetic elements to generate code for them.
*/
public interface KtPureClassOrObject extends KtPureElement, KtDeclarationContainer {
@Nullable
String getName();
boolean isLocal();
@NotNull
@ReadOnly
List<KtSuperTypeListEntry> getSuperTypeListEntries();
@NotNull
@ReadOnly
List<KtObjectDeclaration> getCompanionObjects();
boolean hasExplicitPrimaryConstructor();
boolean hasPrimaryConstructor();
@Nullable
KtPrimaryConstructor getPrimaryConstructor();
@Nullable
KtModifierList getPrimaryConstructorModifierList();
@NotNull
@ReadOnly
List<KtParameter> getPrimaryConstructorParameters();
@NotNull
@ReadOnly
List<KtSecondaryConstructor> getSecondaryConstructors();
}
@@ -0,0 +1,42 @@
/*
* Copyright 2010-2016 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.psi;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
/**
* A minimal interface that {@link KtElement} implements for the purpose of code-generation that does not need the full power of PSI.
* This interface can be easily implemented by synthetic elements to generate code for them.
*/
public interface KtPureElement {
/**
* Returns this or parent source element (for synthetic element declarations).
* Use it only for the purposes of source attribution.
*/
@NotNull
KtElement getPsiOrParent();
/**
* Returns parent source element.
*/
@NotNull
PsiElement getParent();
@NotNull
KtFile getContainingKtFile();
}
@@ -0,0 +1,158 @@
/*
* Copyright 2010-2016 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.psi.synthetics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
import org.jetbrains.kotlin.resolve.lazy.descriptors.ClassResolutionScopesSupport
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassMemberScope
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor
/*
* This class introduces all attributes that are needed for synthetic classes/object so far.
* This list may grow in the future, adding more constructor parameters.
* This class has its own synthetic declaration inside.
*/
class SyntheticClassOrObjectDescriptor(
c: LazyClassContext,
parentClassOrObject: KtPureClassOrObject,
containingDeclaration: DeclarationDescriptor,
name: Name,
source: SourceElement,
outerScope: LexicalScope,
private val modality: Modality,
private val visibility: Visibility,
private val kind: ClassKind,
private val isCompanionObject: Boolean
) : ClassDescriptorBase(c.storageManager, containingDeclaration, name, source, false), ClassDescriptorWithResolutionScopes {
val syntheticDeclaration: KtPureClassOrObject = SyntheticDeclaration(parentClassOrObject, name.asString())
private val thisDescriptor: SyntheticClassOrObjectDescriptor get() = this // code readability
private val typeConstructor = SyntheticTypeConstructor(c.storageManager)
private val resolutionScopesSupport = ClassResolutionScopesSupport(thisDescriptor, c.storageManager, { outerScope })
private val syntheticSupertypes = mutableListOf<KotlinType>().apply { c.syntheticResolveExtension.addSyntheticSupertypes(thisDescriptor, this) }
private val unsubstitutedMemberScope = LazyClassMemberScope(c, SyntheticClassMemberDeclarationProvider(syntheticDeclaration), this, c.trace)
private val unsubstitutedPrimaryConstructor = createUnsubstitutedPrimaryConstructor()
override val annotations: Annotations get() = Annotations.EMPTY
override fun getModality() = modality
override fun getVisibility() = visibility
override fun getKind() = kind
override fun isCompanionObject() = isCompanionObject
override fun isInner() = false
override fun isData() = false
override fun isPlatform() = false
override fun isImpl() = false
override fun getCompanionObjectDescriptor() = null
override fun getTypeConstructor(): TypeConstructor = typeConstructor
override fun getUnsubstitutedPrimaryConstructor() = unsubstitutedPrimaryConstructor
override fun getConstructors() = listOf(unsubstitutedPrimaryConstructor)
override fun getDeclaredTypeParameters() = emptyList<TypeParameterDescriptor>()
override fun getStaticScope() = MemberScope.Empty
override fun getUnsubstitutedMemberScope() = unsubstitutedMemberScope
override fun getDeclaredCallableMembers(): List<CallableMemberDescriptor> =
DescriptorUtils.getAllDescriptors(unsubstitutedMemberScope).filterIsInstance<CallableMemberDescriptor>().filter {
it.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE
}
override fun getScopeForClassHeaderResolution(): LexicalScope = resolutionScopesSupport.scopeForClassHeaderResolution()
override fun getScopeForConstructorHeaderResolution(): LexicalScope = resolutionScopesSupport.scopeForConstructorHeaderResolution()
override fun getScopeForCompanionObjectHeaderResolution(): LexicalScope = resolutionScopesSupport.scopeForCompanionObjectHeaderResolution()
override fun getScopeForMemberDeclarationResolution(): LexicalScope = resolutionScopesSupport.scopeForMemberDeclarationResolution()
override fun getScopeForStaticMemberDeclarationResolution(): LexicalScope = resolutionScopesSupport.scopeForStaticMemberDeclarationResolution()
override fun getScopeForInitializerResolution(): LexicalScope = throw UnsupportedOperationException("Not supported for synthetic class or object")
override fun toString(): String = "synthetic class " + name.toString() + " in " + containingDeclaration
private fun createUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor {
val constructor = DescriptorFactory.createPrimaryConstructorForObject(thisDescriptor, source)
constructor.returnType = getDefaultType()
return constructor
}
private inner class SyntheticTypeConstructor(storageManager: StorageManager) : AbstractClassTypeConstructor(storageManager) {
override fun getParameters(): List<TypeParameterDescriptor> = emptyList()
override fun isFinal(): Boolean = true
override fun isDenotable(): Boolean = true
override fun getDeclarationDescriptor(): ClassifierDescriptor = thisDescriptor
override fun computeSupertypes(): Collection<KotlinType> = syntheticSupertypes
override val supertypeLoopChecker: SupertypeLoopChecker = SupertypeLoopChecker.EMPTY
}
private class SyntheticClassMemberDeclarationProvider(
override val correspondingClassOrObject: KtPureClassOrObject
) : ClassMemberDeclarationProvider {
override val ownerInfo: KtClassLikeInfo? = null
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 getClassOrObjectDeclarations(name: Name): Collection<KtClassLikeInfo> = emptyList()
override fun getTypeAliasDeclarations(name: Name): Collection<KtTypeAlias> = emptyList()
}
internal inner class SyntheticDeclaration(
private val _parent: KtPureElement,
private val _name: String
) : KtPureClassOrObject {
fun descriptor() = thisDescriptor
override fun getName(): String? = _name
override fun isLocal(): Boolean = false
override fun getDeclarations(): List<KtDeclaration> = emptyList()
override fun getSuperTypeListEntries(): List<KtSuperTypeListEntry> = emptyList()
override fun getCompanionObjects(): List<KtObjectDeclaration> = emptyList()
override fun hasExplicitPrimaryConstructor(): Boolean = false
override fun hasPrimaryConstructor(): Boolean = false
override fun getPrimaryConstructor(): KtPrimaryConstructor? = null
override fun getPrimaryConstructorModifierList(): KtModifierList? = null
override fun getPrimaryConstructorParameters(): List<KtParameter> = emptyList()
override fun getSecondaryConstructors(): List<KtSecondaryConstructor> = emptyList()
override fun getPsiOrParent() = _parent.psiOrParent
override fun getParent() = _parent.psiOrParent
override fun getContainingKtFile() = _parent.containingKtFile
}
}
fun KtPureElement.findClassDescriptor(bindingContext: BindingContext): ClassDescriptor = when (this) {
is PsiElement -> BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, this)
is SyntheticClassOrObjectDescriptor.SyntheticDeclaration -> descriptor()
else -> throw IllegalArgumentException("$this shall be PsiElement or SyntheticClassOrObjectDescriptor.SyntheticDeclaration")
}
@@ -21,13 +21,14 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION
import org.jetbrains.kotlin.diagnostics.Errors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
import org.jetbrains.kotlin.psi.KtPureClassOrObject
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
class DelegationResolver<T : CallableMemberDescriptor> private constructor(
private val classOrObject: KtClassOrObject,
private val classOrObject: KtPureClassOrObject,
private val ownerDescriptor: ClassDescriptor,
private val existingMembers: Collection<CallableDescriptor>,
private val trace: BindingTrace,
@@ -68,7 +69,8 @@ class DelegationResolver<T : CallableMemberDescriptor> private constructor(
private fun checkClashWithOtherDelegatedMember(candidate: T, delegatedMembers: Collection<T>): Boolean {
val alreadyDelegated = delegatedMembers.firstOrNull { isOverridableBy(it, candidate) }
if (alreadyDelegated != null) {
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(classOrObject, classOrObject, alreadyDelegated))
if (classOrObject is KtClassOrObject) // report errors only for physical (non-synthetic) classes or objects
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(classOrObject, classOrObject, alreadyDelegated))
return true
}
return false
@@ -98,7 +100,7 @@ class DelegationResolver<T : CallableMemberDescriptor> private constructor(
companion object {
fun <T : CallableMemberDescriptor> generateDelegatedMembers(
classOrObject: KtClassOrObject,
classOrObject: KtPureClassOrObject,
ownerDescriptor: ClassDescriptor,
existingMembers: Collection<CallableDescriptor>,
trace: BindingTrace,
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import kotlin.Pair;
import kotlin.collections.CollectionsKt;
@@ -47,6 +48,7 @@ import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory;
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
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.*;
@@ -82,6 +84,7 @@ public class DescriptorResolver {
private final FunctionsTypingVisitor functionsTypingVisitor;
private final DestructuringDeclarationResolver destructuringDeclarationResolver;
private final ModifiersChecker modifiersChecker;
private final SyntheticResolveExtension syntheticResolveExtension;
public DescriptorResolver(
@NotNull AnnotationResolver annotationResolver,
@@ -95,7 +98,8 @@ public class DescriptorResolver {
@NotNull LanguageVersionSettings languageVersionSettings,
@NotNull FunctionsTypingVisitor functionsTypingVisitor,
@NotNull DestructuringDeclarationResolver destructuringDeclarationResolver,
@NotNull ModifiersChecker modifiersChecker
@NotNull ModifiersChecker modifiersChecker,
@NotNull Project project
) {
this.annotationResolver = annotationResolver;
this.builtIns = builtIns;
@@ -109,16 +113,18 @@ public class DescriptorResolver {
this.functionsTypingVisitor = functionsTypingVisitor;
this.destructuringDeclarationResolver = destructuringDeclarationResolver;
this.modifiersChecker = modifiersChecker;
this.syntheticResolveExtension = SyntheticResolveExtension.Companion.getInstance(project);
}
public List<KotlinType> resolveSupertypes(
@NotNull LexicalScope scope,
@NotNull ClassDescriptor classDescriptor,
@NotNull KtClassOrObject jetClass,
@Nullable KtPureClassOrObject correspondingClassOrObject,
BindingTrace trace
) {
List<KotlinType> supertypes = Lists.newArrayList();
List<KtSuperTypeListEntry> delegationSpecifiers = jetClass.getSuperTypeListEntries();
List<KtSuperTypeListEntry> delegationSpecifiers = correspondingClassOrObject == null ? Collections.<KtSuperTypeListEntry>emptyList() :
correspondingClassOrObject.getSuperTypeListEntries();
Collection<KotlinType> declaredSupertypes = resolveSuperTypeListEntries(
scope,
delegationSpecifiers,
@@ -132,8 +138,11 @@ public class DescriptorResolver {
supertypes.add(0, builtIns.getEnumType(classDescriptor.getDefaultType()));
}
syntheticResolveExtension.addSyntheticSupertypes(classDescriptor, supertypes);
if (supertypes.isEmpty()) {
KotlinType defaultSupertype = getDefaultSupertype(jetClass, trace, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
KotlinType defaultSupertype = correspondingClassOrObject == null ? builtIns.getAnyType() :
getDefaultSupertype(correspondingClassOrObject, trace, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
addValidSupertype(supertypes, defaultSupertype);
}
@@ -146,7 +155,7 @@ public class DescriptorResolver {
}
}
private boolean containsClass(Collection<KotlinType> result) {
private static boolean containsClass(Collection<KotlinType> result) {
for (KotlinType type : result) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.INTERFACE) {
@@ -156,16 +165,17 @@ public class DescriptorResolver {
return false;
}
private KotlinType getDefaultSupertype(KtClassOrObject jetClass, BindingTrace trace, boolean isAnnotation) {
private KotlinType getDefaultSupertype(KtPureClassOrObject ktClass, BindingTrace trace, boolean isAnnotation) {
// TODO : beautify
if (jetClass instanceof KtEnumEntry) {
KtClassOrObject parent = KtStubbedPsiUtil.getContainingDeclaration(jetClass, KtClassOrObject.class);
if (ktClass instanceof KtEnumEntry) {
KtEnumEntry enumEntry = (KtEnumEntry) ktClass;
KtClassOrObject parent = KtStubbedPsiUtil.getContainingDeclaration(enumEntry, KtClassOrObject.class);
ClassDescriptor parentDescriptor = trace.getBindingContext().get(BindingContext.CLASS, parent);
if (parentDescriptor.getTypeConstructor().getParameters().isEmpty()) {
return parentDescriptor.getDefaultType();
}
else {
trace.report(NO_GENERICS_IN_SUPERTYPE_SPECIFIER.on(jetClass.getNameIdentifier()));
trace.report(NO_GENERICS_IN_SUPERTYPE_SPECIFIER.on(enumEntry.getNameIdentifier()));
return ErrorUtils.createErrorType("Supertype not specified");
}
}
@@ -449,15 +459,15 @@ public class DescriptorResolver {
@NotNull
public static ClassConstructorDescriptorImpl createAndRecordPrimaryConstructorForObject(
@Nullable KtClassOrObject object,
@Nullable KtPureClassOrObject object,
@NotNull ClassDescriptor classDescriptor,
@NotNull BindingTrace trace
) {
ClassConstructorDescriptorImpl constructorDescriptor =
DescriptorFactory.createPrimaryConstructorForObject(classDescriptor, KotlinSourceElementKt.toSourceElement(object));
if (object != null) {
if (object instanceof PsiElement) {
KtPrimaryConstructor primaryConstructor = object.getPrimaryConstructor();
trace.record(CONSTRUCTOR, primaryConstructor != null ? primaryConstructor : object, constructorDescriptor);
trace.record(CONSTRUCTOR, primaryConstructor != null ? primaryConstructor : (PsiElement)object, constructorDescriptor);
}
return constructorDescriptor;
}
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.resolve
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
@@ -251,7 +252,7 @@ class FunctionDescriptorResolver(
fun resolvePrimaryConstructorDescriptor(
scope: LexicalScope,
classDescriptor: ClassDescriptor,
classElement: KtClassOrObject,
classElement: KtPureClassOrObject,
trace: BindingTrace
): ClassConstructorDescriptorImpl? {
if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY || !classElement.hasPrimaryConstructor()) return null
@@ -288,7 +289,7 @@ class FunctionDescriptorResolver(
classDescriptor: ClassDescriptor,
isPrimary: Boolean,
modifierList: KtModifierList?,
declarationToTrace: KtDeclaration,
declarationToTrace: KtPureElement,
valueParameters: List<KtParameter>,
trace: BindingTrace
): ClassConstructorDescriptorImpl {
@@ -304,7 +305,8 @@ class FunctionDescriptorResolver(
if (classDescriptor.isImpl) {
constructorDescriptor.isImpl = true
}
trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor)
if (declarationToTrace is PsiElement)
trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor)
val parameterScope = LexicalWritableScope(
scope,
constructorDescriptor,
@@ -0,0 +1,73 @@
/*
* Copyright 2010-2016 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.extensions
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import java.util.*
//----------------------------------------------------------------
// extension interface
interface SyntheticResolveExtension {
companion object : ProjectExtensionDescriptor<SyntheticResolveExtension>(
"org.jetbrains.kotlin.syntheticResolveExtension", SyntheticResolveExtension::class.java) {
fun getInstance(project: Project): SyntheticResolveExtension {
val instances = getInstances(project)
if (instances.size == 1) return instances.single()
// return list combiner here
return object : SyntheticResolveExtension {
override fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name? =
instances.firstNotNullResult { it.getSyntheticCompanionObjectNameIfNeeded(thisDescriptor) }
override fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) =
instances.forEach { it.addSyntheticSupertypes(thisDescriptor, supertypes) }
override fun generateSyntheticMethods(thisDescriptor: ClassDescriptor, name: Name,
fromSupertypes: List<SimpleFunctionDescriptor>,
result: MutableCollection<SimpleFunctionDescriptor>) =
instances.forEach { it.generateSyntheticMethods(thisDescriptor, name, fromSupertypes, result) }
override fun generateSyntheticProperties(thisDescriptor: ClassDescriptor, name: Name,
fromSupertypes: ArrayList<PropertyDescriptor>,
result: MutableSet<PropertyDescriptor>) =
instances.forEach { it.generateSyntheticProperties(thisDescriptor, name, fromSupertypes, result) }
}
}
}
fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name?
fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {}
fun generateSyntheticMethods(thisDescriptor: ClassDescriptor,
name: Name,
fromSupertypes: List<SimpleFunctionDescriptor>,
result: MutableCollection<SimpleFunctionDescriptor>) {}
fun generateSyntheticProperties(thisDescriptor: ClassDescriptor,
name: Name,
fromSupertypes:
ArrayList<PropertyDescriptor>,
result: MutableSet<PropertyDescriptor>) {}
}
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
import org.jetbrains.kotlin.storage.StorageManager
@@ -38,4 +39,5 @@ interface LazyClassContext {
val lookupTracker: LookupTracker
val supertypeLoopChecker: SupertypeLoopChecker
val languageVersionSettings: LanguageVersionSettings
val syntheticResolveExtension: SyntheticResolveExtension
}
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension;
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo;
import org.jetbrains.kotlin.resolve.lazy.data.KtClassOrObjectInfo;
import org.jetbrains.kotlin.resolve.lazy.data.KtScriptInfo;
@@ -81,6 +82,8 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
private SupertypeLoopChecker supertypeLoopsResolver;
private LanguageVersionSettings languageVersionSettings;
private final SyntheticResolveExtension syntheticResolveExtension;
@Inject
public void setJetImportFactory(KtImportsFactory jetImportFactory) {
this.jetImportFactory = jetImportFactory;
@@ -192,6 +195,8 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
return createAnnotations(file, file.getDanglingAnnotations());
}
});
syntheticResolveExtension = SyntheticResolveExtension.Companion.getInstance(project);
}
private LazyAnnotations createAnnotations(KtFile file, List<KtAnnotationEntry> annotationEntries) {
@@ -439,4 +444,10 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
public LanguageVersionSettings getLanguageVersionSettings() {
return languageVersionSettings;
}
@NotNull
@Override
public SyntheticResolveExtension getSyntheticResolveExtension() {
return syntheticResolveExtension;
}
}
@@ -41,7 +41,7 @@ public interface KtClassLikeInfo extends KtDeclarationContainer {
@NotNull
PsiElement getScopeAnchor();
@Nullable
@Nullable // can be null in KtScript
KtClassOrObject getCorrespondingClassOrObject();
@Nullable
@@ -16,8 +16,15 @@
package org.jetbrains.kotlin.resolve.lazy.declarations
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtPureClassOrObject
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo
interface ClassMemberDeclarationProvider : DeclarationProvider {
fun getOwnerInfo(): KtClassLikeInfo
val ownerInfo: KtClassLikeInfo? // is null for synthetic classes/object that don't present in the source code
val correspondingClassOrObject: KtPureClassOrObject? get() = ownerInfo?.correspondingClassOrObject
val primaryConstructorParameters: List<KtParameter> get() = ownerInfo?.primaryConstructorParameters ?: emptyList()
val companionObjects: List<KtObjectDeclaration> get() = ownerInfo?.companionObjects ?: emptyList()
}
@@ -16,28 +16,25 @@
package org.jetbrains.kotlin.resolve.lazy.declarations
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo
import org.jetbrains.kotlin.storage.StorageManager
class PsiBasedClassMemberDeclarationProvider(
storageManager: StorageManager,
private val classInfo: KtClassLikeInfo)
override val ownerInfo: KtClassLikeInfo)
: AbstractPsiBasedDeclarationProvider(storageManager), ClassMemberDeclarationProvider {
override fun getOwnerInfo() = classInfo
override fun doCreateIndex(index: AbstractPsiBasedDeclarationProvider.Index) {
for (declaration in classInfo.declarations) {
for (declaration in ownerInfo.declarations) {
index.putToIndex(declaration)
}
for (parameter in classInfo.primaryConstructorParameters) {
for (parameter in ownerInfo.primaryConstructorParameters) {
if (parameter.hasValOrVar()) {
index.putToIndex(parameter)
}
}
}
override fun toString() = "Declarations for $classInfo"
override fun toString() = "Declarations for $ownerInfo"
}
@@ -45,20 +45,23 @@ protected constructor(
) : MemberScopeImpl() {
protected val storageManager: StorageManager = c.storageManager
private val classDescriptors: MemoizedFunctionToNotNull<Name, List<ClassDescriptor>> = storageManager.createMemoizedFunction { resolveClassDescriptor(it) }
private val classDescriptors: MemoizedFunctionToNotNull<Name, List<ClassDescriptor>> = storageManager.createMemoizedFunction { doGetClasses(it) }
private val functionDescriptors: MemoizedFunctionToNotNull<Name, Collection<SimpleFunctionDescriptor>> = storageManager.createMemoizedFunction { doGetFunctions(it) }
private val propertyDescriptors: MemoizedFunctionToNotNull<Name, Collection<PropertyDescriptor>> = storageManager.createMemoizedFunction { doGetProperties(it) }
private val typeAliasDescriptors: MemoizedFunctionToNotNull<Name, Collection<TypeAliasDescriptor>> = storageManager.createMemoizedFunction { doGetTypeAliases(it) }
private fun resolveClassDescriptor(name: Name): List<ClassDescriptor> {
return declarationProvider.getClassOrObjectDeclarations(name).map {
private fun doGetClasses(name: Name): List<ClassDescriptor> {
val result = Sets.newLinkedHashSet<ClassDescriptor>()
declarationProvider.getClassOrObjectDeclarations(name).mapTo(result) {
if (it is KtScriptInfo)
LazyScriptDescriptor(c as ResolveSession, thisDescriptor, name, it)
else {
val isExternal = it.modifierList?.hasModifier(KtTokens.EXTERNAL_KEYWORD) ?: false
LazyClassDescriptor(c, thisDescriptor, name, it, isExternal)
}
}.toReadOnlyList()
}
getNonDeclaredClasses(name, result)
return result.toReadOnlyList()
}
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
@@ -95,6 +98,8 @@ protected constructor(
protected abstract fun getScopeForMemberDeclarationResolution(declaration: KtDeclaration): LexicalScope
protected abstract fun getNonDeclaredClasses(name: Name, result: MutableSet<ClassDescriptor>)
protected abstract fun getNonDeclaredFunctions(name: Name, result: MutableSet<SimpleFunctionDescriptor>)
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext;
@@ -65,6 +66,7 @@ import java.util.Collections;
import java.util.List;
import static kotlin.collections.CollectionsKt.firstOrNull;
import static org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC;
import static org.jetbrains.kotlin.diagnostics.Errors.CYCLIC_INHERITANCE_HIERARCHY;
import static org.jetbrains.kotlin.diagnostics.Errors.TYPE_PARAMETERS_IN_ENUM;
import static org.jetbrains.kotlin.resolve.BindingContext.TYPE;
@@ -80,6 +82,9 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
};
private final LazyClassContext c;
@Nullable // can be null in KtScript
private final KtClassOrObject classOrObject;
private final ClassMemberDeclarationProvider declarationProvider;
private final LazyClassTypeConstructor typeConstructor;
@@ -93,7 +98,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
private final Annotations annotations;
private final Annotations danglingAnnotations;
private final NullableLazyValue<LazyClassDescriptor> companionObjectDescriptor;
private final NullableLazyValue<ClassDescriptorWithResolutionScopes> companionObjectDescriptor;
private final MemoizedFunctionToNotNull<KtObjectDeclaration, ClassDescriptor> extraCompanionObjectDescriptors;
private final LazyClassMemberScope unsubstitutedMemberScope;
@@ -120,7 +125,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
);
this.c = c;
final KtClassOrObject classOrObject = classLikeInfo.getCorrespondingClassOrObject();
classOrObject = classLikeInfo.getCorrespondingClassOrObject();
if (classOrObject != null) {
this.c.getTrace().record(BindingContext.CLASS, classOrObject, this);
}
@@ -225,9 +230,9 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
);
}
this.companionObjectDescriptor = storageManager.createNullableLazyValue(new Function0<LazyClassDescriptor>() {
this.companionObjectDescriptor = storageManager.createNullableLazyValue(new Function0<ClassDescriptorWithResolutionScopes>() {
@Override
public LazyClassDescriptor invoke() {
public ClassDescriptorWithResolutionScopes invoke() {
return computeCompanionObjectDescriptor(getCompanionObjectIfAllowed());
}
});
@@ -411,7 +416,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
}
@Override
public LazyClassDescriptor getCompanionObjectDescriptor() {
public ClassDescriptorWithResolutionScopes getCompanionObjectDescriptor() {
return companionObjectDescriptor.invoke();
}
@@ -440,7 +445,9 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
}
@Nullable
private LazyClassDescriptor computeCompanionObjectDescriptor(@Nullable KtObjectDeclaration companionObject) {
private ClassDescriptorWithResolutionScopes computeCompanionObjectDescriptor(@Nullable KtObjectDeclaration companionObject) {
if (companionObject == null)
return createSyntheticCompanionObjectDescriptor();
KtClassLikeInfo companionObjectInfo = getCompanionObjectInfo(companionObject);
if (!(companionObjectInfo instanceof KtClassOrObjectInfo)) {
return null;
@@ -449,15 +456,26 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
assert name != null;
getUnsubstitutedMemberScope().getContributedClassifier(name, NoLookupLocation.WHEN_GET_COMPANION_OBJECT);
ClassDescriptor companionObjectDescriptor = c.getTrace().get(BindingContext.CLASS, companionObject);
if (companionObjectDescriptor instanceof LazyClassDescriptor) {
if (companionObjectDescriptor instanceof ClassDescriptorWithResolutionScopes) {
assert DescriptorUtils.isCompanionObject(companionObjectDescriptor) : "Not a companion object: " + companionObjectDescriptor;
return (LazyClassDescriptor) companionObjectDescriptor;
return (ClassDescriptorWithResolutionScopes)companionObjectDescriptor;
}
else {
return null;
}
}
private ClassDescriptorWithResolutionScopes createSyntheticCompanionObjectDescriptor() {
Name syntheticCompanionName = c.getSyntheticResolveExtension().getSyntheticCompanionObjectNameIfNeeded(this);
if (syntheticCompanionName == null)
return null;
return new SyntheticClassOrObjectDescriptor(c,
/* parentClassOrObject= */ classOrObject,
this, syntheticCompanionName, getSource(),
/* outerScope= */ getOuterScope(),
Modality.FINAL, PUBLIC, ClassKind.OBJECT, true);
}
@Nullable
private static KtClassLikeInfo getCompanionObjectInfo(@Nullable KtObjectDeclaration companionObject) {
if (companionObject != null) {
@@ -49,9 +49,9 @@ import java.util.*
open class LazyClassMemberScope(
c: LazyClassContext,
declarationProvider: ClassMemberDeclarationProvider,
thisClass: LazyClassDescriptor,
thisClass: ClassDescriptorWithResolutionScopes,
trace: BindingTrace
) : AbstractLazyMemberScope<LazyClassDescriptor, ClassMemberDeclarationProvider>(c, declarationProvider, thisClass, trace) {
) : AbstractLazyMemberScope<ClassDescriptorWithResolutionScopes, ClassMemberDeclarationProvider>(c, declarationProvider, thisClass, trace) {
private val descriptorsFromDeclaredElements = storageManager.createLazyValue {
computeDescriptorsFromDeclaredElements(DescriptorKindFilter.ALL, MemberScope.ALL_NAME_FILTER, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS)
@@ -82,6 +82,7 @@ open class LazyClassMemberScope(
}
addDataClassMethods(result, location)
addSyntheticCompanionObject(result, location)
result.trimToSize()
return result
@@ -129,6 +130,10 @@ open class LazyClassMemberScope(
return functions
}
override fun getNonDeclaredClasses(name: Name, result: MutableSet<ClassDescriptor>) {
generateSyntheticCompanionObject(name, result)
}
override fun getNonDeclaredFunctions(name: Name, result: MutableSet<SimpleFunctionDescriptor>) {
val location = NoLookupLocation.FOR_ALREADY_TRACKED
@@ -138,6 +143,7 @@ open class LazyClassMemberScope(
}
result.addAll(generateDelegatingDescriptors(name, EXTRACT_FUNCTIONS, result))
generateDataClassMethods(result, name, location, fromSupertypes)
c.syntheticResolveExtension.generateSyntheticMethods(thisDescriptor, name, fromSupertypes, result)
generateFakeOverrides(name, fromSupertypes, result, SimpleFunctionDescriptor::class.java)
}
@@ -150,8 +156,8 @@ open class LazyClassMemberScope(
if (!thisDescriptor.isData) return
val constructor = getPrimaryConstructor() ?: return
val primaryConstructorParameters = declarationProvider.primaryConstructorParameters
val primaryConstructorParameters = declarationProvider.getOwnerInfo().primaryConstructorParameters
assert(constructor.valueParameters.size == primaryConstructorParameters.size) { "From descriptor: " + constructor.valueParameters.size + " but from PSI: " + primaryConstructorParameters.size }
if (DataClassDescriptorResolver.isComponentLike(name)) {
@@ -210,6 +216,21 @@ open class LazyClassMemberScope(
}
}
private fun addSyntheticCompanionObject(result: MutableCollection<DeclarationDescriptor>, location: LookupLocation) {
val syntheticCompanionName = c.syntheticResolveExtension.getSyntheticCompanionObjectNameIfNeeded(thisDescriptor) ?: return
val descriptor = getContributedClassifier(syntheticCompanionName, location) ?: return
result.add(descriptor)
}
private fun generateSyntheticCompanionObject(name: Name, result: MutableSet<ClassDescriptor>) {
val syntheticCompanionName = c.syntheticResolveExtension.getSyntheticCompanionObjectNameIfNeeded(thisDescriptor) ?: return
if (name == syntheticCompanionName && result.none { it.isCompanionObject }) {
// forces creation of companion object if needed
val companionObjectDescriptor = thisDescriptor.companionObjectDescriptor ?: return
result.add(companionObjectDescriptor)
}
}
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
// TODO: this should be handled by lazy property descriptors
val properties = super.getContributedVariables(name, location)
@@ -235,17 +256,17 @@ open class LazyClassMemberScope(
fromSupertypes.addAll(supertype.memberScope.getContributedVariables(name, NoLookupLocation.FOR_ALREADY_TRACKED))
}
result.addAll(generateDelegatingDescriptors(name, EXTRACT_PROPERTIES, result))
c.syntheticResolveExtension.generateSyntheticProperties(thisDescriptor, name, fromSupertypes, result)
generateFakeOverrides(name, fromSupertypes, result, PropertyDescriptor::class.java)
}
protected open fun createPropertiesFromPrimaryConstructorParameters(name: Name, result: MutableSet<PropertyDescriptor>) {
val classInfo = declarationProvider.getOwnerInfo()
// From primary constructor parameters
val primaryConstructor = getPrimaryConstructor() ?: return
val valueParameterDescriptors = primaryConstructor.valueParameters
val primaryConstructorParameters = classInfo.primaryConstructorParameters
val primaryConstructorParameters = declarationProvider.primaryConstructorParameters
assert(valueParameterDescriptors.size == primaryConstructorParameters.size) {
"From descriptor: ${valueParameterDescriptors.size} but from PSI: ${primaryConstructorParameters.size}"
}
@@ -264,8 +285,7 @@ open class LazyClassMemberScope(
}
private fun <T : CallableMemberDescriptor> generateDelegatingDescriptors(name: Name, extractor: MemberExtractor<T>, existingDescriptors: Collection<CallableDescriptor>): Collection<T> {
val classOrObject = declarationProvider.getOwnerInfo().correspondingClassOrObject
?: return setOf()
val classOrObject = declarationProvider.correspondingClassOrObject ?: return setOf()
val lazyTypeResolver = object : DelegationResolver.TypeResolver {
override fun resolve(reference: KtTypeReference): KotlinType? =
@@ -309,8 +329,7 @@ open class LazyClassMemberScope(
fun getPrimaryConstructor(): ClassConstructorDescriptor? = primaryConstructor()
protected open fun resolvePrimaryConstructor(): ClassConstructorDescriptor? {
val ownerInfo = declarationProvider.getOwnerInfo()
val classOrObject = ownerInfo.correspondingClassOrObject ?: return null
val classOrObject = declarationProvider.correspondingClassOrObject ?: return null
val hasPrimaryConstructor = classOrObject.hasExplicitPrimaryConstructor()
if (DescriptorUtils.isInterface(thisDescriptor) && !hasPrimaryConstructor) return null
@@ -330,7 +349,7 @@ open class LazyClassMemberScope(
}
private fun resolveSecondaryConstructors(): Collection<ClassConstructorDescriptor> {
val classOrObject = declarationProvider.getOwnerInfo().correspondingClassOrObject ?: return emptyList()
val classOrObject = declarationProvider.correspondingClassOrObject ?: return emptyList()
return classOrObject.getSecondaryConstructors().map { constructor ->
val descriptor = c.functionDescriptorResolver.resolveSecondaryConstructorDescriptor(
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.resolve.lazy.descriptors
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.incremental.record
@@ -42,6 +39,10 @@ class LazyPackageMemberScope(
override fun getScopeForMemberDeclarationResolution(declaration: KtDeclaration)
= resolveSession.fileScopeProvider.getFileResolutionScope(declaration.getContainingKtFile())
override fun getNonDeclaredClasses(name: Name, result: MutableSet<ClassDescriptor>) {
// No extra classes
}
override fun getNonDeclaredFunctions(name: Name, result: MutableSet<SimpleFunctionDescriptor>) {
// No extra functions
}
@@ -16,12 +16,13 @@
package org.jetbrains.kotlin.resolve.source
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.descriptors.SourceElement
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtPureElement
class KotlinSourceElement(override val psi: KtElement) : PsiSourceElement
fun KtElement?.toSourceElement(): SourceElement = if (this == null) SourceElement.NO_SOURCE else KotlinSourceElement(this)
fun KtPureElement?.toSourceElement(): SourceElement = if (this == null) SourceElement.NO_SOURCE else KotlinSourceElement(psiOrParent)
fun SourceElement.getPsi(): PsiElement? = (this as? PsiSourceElement)?.psi
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.debugText.getDebugText
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
import org.jetbrains.kotlin.resolve.lazy.*
import org.jetbrains.kotlin.resolve.lazy.data.KtClassInfoUtil
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo
@@ -68,7 +69,8 @@ class LocalClassifierAnalyzer(
classOrObject: KtClassOrObject
) {
val module = DescriptorUtils.getContainingModule(containingDeclaration)
val moduleContext = globalContext.withProject(classOrObject.getProject()).withModule(module)
val project = classOrObject.getProject()
val moduleContext = globalContext.withProject(project).withModule(module)
val container = createContainerForLazyLocalClassifierAnalyzer(
moduleContext,
context.trace,
@@ -88,7 +90,8 @@ class LocalClassifierAnalyzer(
typeResolver,
annotationResolver,
supertypeLoopChecker,
languageVersionSettings
languageVersionSettings,
SyntheticResolveExtension.getInstance(project)
)
)
@@ -112,7 +115,8 @@ class LocalClassDescriptorHolder(
val typeResolver: TypeResolver,
val annotationResolver: AnnotationResolver,
val supertypeLoopChecker: SupertypeLoopChecker,
val languageVersionSettings: LanguageVersionSettings
val languageVersionSettings: LanguageVersionSettings,
val syntheticResolveExtension: SyntheticResolveExtension
) {
// We do not need to synchronize here, because this code is used strictly from one thread
private var classDescriptor: ClassDescriptor? = null
@@ -149,6 +153,7 @@ class LocalClassDescriptorHolder(
override val lookupTracker: LookupTracker = LookupTracker.DO_NOTHING
override val supertypeLoopChecker = this@LocalClassDescriptorHolder.supertypeLoopChecker
override val languageVersionSettings = this@LocalClassDescriptorHolder.languageVersionSettings
override val syntheticResolveExtension = this@LocalClassDescriptorHolder.syntheticResolveExtension
}
,
containingDeclaration,