Pluggable Synthetic Objects
This commit is contained in:
@@ -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();
|
||||
}
|
||||
+158
@@ -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,
|
||||
|
||||
+73
@@ -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
|
||||
|
||||
+8
-1
@@ -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()
|
||||
}
|
||||
|
||||
+5
-8
@@ -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"
|
||||
}
|
||||
|
||||
+9
-4
@@ -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> {
|
||||
|
||||
+26
-8
@@ -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) {
|
||||
|
||||
+29
-10
@@ -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(
|
||||
|
||||
+5
-4
@@ -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
|
||||
|
||||
+8
-3
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user