Pluggable Synthetic Objects
This commit is contained in:
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -162,4 +163,23 @@ object CodegenUtil {
|
||||
val document = file.viewProvider.document
|
||||
return document?.getLineNumber(if (markEndOffset) statement.textRange.endOffset else statement.textOffset)?.plus(1)
|
||||
}
|
||||
|
||||
// Returns the descriptor for a function (whose parameters match the given predicate) which should be generated in the class.
|
||||
// Note that we always generate equals/hashCode/toString in data classes, unless that would lead to a JVM signature clash with
|
||||
// another method, which can only happen if the method is declared in the data class (manually or via delegation).
|
||||
// Also there are no hard asserts or assumptions because such methods are generated for erroneous code as well (in light classes mode).
|
||||
fun getMemberToGenerate(
|
||||
classDescriptor: ClassDescriptor,
|
||||
name: String,
|
||||
isReturnTypeOk: (KotlinType) -> Boolean,
|
||||
areParametersOk: (List<ValueParameterDescriptor>) -> Boolean
|
||||
): FunctionDescriptor? =
|
||||
classDescriptor.unsubstitutedMemberScope.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND)
|
||||
.singleOrNull { function ->
|
||||
function.kind.let { kind -> kind == CallableMemberDescriptor.Kind.SYNTHESIZED || kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE } &&
|
||||
function.modality != Modality.FINAL &&
|
||||
areParametersOk(function.valueParameters) &&
|
||||
function.returnType != null &&
|
||||
isReturnTypeOk(function.returnType!!)
|
||||
}
|
||||
}
|
||||
|
||||
+11
-27
@@ -16,18 +16,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil.getMemberToGenerate
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
/**
|
||||
* A platform-independent logic for generating data class synthetic methods.
|
||||
@@ -79,17 +78,20 @@ abstract class DataClassMethodGenerator(private val declaration: KtClassOrObject
|
||||
}
|
||||
|
||||
private fun generateDataClassToStringIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = getMemberToGenerate("toString", KotlinBuiltIns::isString, List<ValueParameterDescriptor>::isEmpty) ?: return
|
||||
val function = getMemberToGenerate(classDescriptor, "toString",
|
||||
KotlinBuiltIns::isString, List<ValueParameterDescriptor>::isEmpty) ?: return
|
||||
generateToStringMethod(function, properties)
|
||||
}
|
||||
|
||||
private fun generateDataClassHashCodeIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = getMemberToGenerate("hashCode", KotlinBuiltIns::isInt, List<ValueParameterDescriptor>::isEmpty) ?: return
|
||||
val function = getMemberToGenerate(classDescriptor, "hashCode",
|
||||
KotlinBuiltIns::isInt, List<ValueParameterDescriptor>::isEmpty) ?: return
|
||||
generateHashCodeMethod(function, properties)
|
||||
}
|
||||
|
||||
private fun generateDataClassEqualsIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = getMemberToGenerate("equals", KotlinBuiltIns::isBoolean) { parameters ->
|
||||
val function = getMemberToGenerate(classDescriptor, "equals",
|
||||
KotlinBuiltIns::isBoolean) { parameters ->
|
||||
parameters.size == 1 && KotlinBuiltIns.isNullableAny(parameters.first().type)
|
||||
} ?: return
|
||||
generateEqualsMethod(function, properties)
|
||||
@@ -102,22 +104,4 @@ abstract class DataClassMethodGenerator(private val declaration: KtClassOrObject
|
||||
|
||||
private val primaryConstructorParameters: List<KtParameter>
|
||||
get() = (declaration as? KtClass)?.getPrimaryConstructorParameters().orEmpty()
|
||||
|
||||
// Returns the descriptor for a function (whose parameters match the given predicate) which should be generated in the data class.
|
||||
// Note that we always generate equals/hashCode/toString in data classes, unless that would lead to a JVM signature clash with
|
||||
// another method, which can only happen if the method is declared in the data class (manually or via delegation).
|
||||
// Also there are no hard asserts or assumptions because such methods are generated for erroneous code as well (in light classes mode).
|
||||
private fun getMemberToGenerate(
|
||||
name: String,
|
||||
isReturnTypeOk: (KotlinType) -> Boolean,
|
||||
areParametersOk: (List<ValueParameterDescriptor>) -> Boolean
|
||||
): FunctionDescriptor? =
|
||||
classDescriptor.unsubstitutedMemberScope.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND)
|
||||
.singleOrNull { function ->
|
||||
function.kind.let { kind -> kind == SYNTHESIZED || kind == FAKE_OVERRIDE } &&
|
||||
function.modality != Modality.FINAL &&
|
||||
areParametersOk(function.valueParameters) &&
|
||||
function.returnType != null &&
|
||||
isReturnTypeOk(function.returnType!!)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.codegen.context.ClassContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptorKt;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
|
||||
@@ -32,13 +34,13 @@ import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||
|
||||
public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
protected final KtClassOrObject myClass;
|
||||
protected final OwnerKind kind;
|
||||
protected final ClassDescriptor descriptor;
|
||||
public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject> {
|
||||
public final KtPureClassOrObject myClass;
|
||||
public final OwnerKind kind;
|
||||
public final ClassDescriptor descriptor;
|
||||
|
||||
protected ClassBodyCodegen(
|
||||
@NotNull KtClassOrObject myClass,
|
||||
@NotNull KtPureClassOrObject myClass,
|
||||
@NotNull ClassContext context,
|
||||
@NotNull ClassBuilder v,
|
||||
@NotNull GenerationState state,
|
||||
@@ -47,7 +49,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
super(state, parentCodegen, context, myClass, v);
|
||||
this.myClass = myClass;
|
||||
this.kind = context.getContextKind();
|
||||
this.descriptor = bindingContext.get(BindingContext.CLASS, myClass);
|
||||
this.descriptor = SyntheticClassOrObjectDescriptorKt.findClassDescriptor(myClass, bindingContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,8 +81,15 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
generateConstructors();
|
||||
generateDefaultImplsIfNeeded();
|
||||
|
||||
// Generate _declared_ companions
|
||||
for (KtObjectDeclaration companion : companions) {
|
||||
generateDeclaration(companion);
|
||||
genClassOrObject(companion);
|
||||
}
|
||||
|
||||
// Generate synthetic (non-declared) companion if needed
|
||||
ClassDescriptor companionObjectDescriptor = descriptor.getCompanionObjectDescriptor();
|
||||
if (companionObjectDescriptor instanceof SyntheticClassOrObjectDescriptor) {
|
||||
genSyntheticClassOrObject((SyntheticClassOrObjectDescriptor) companionObjectDescriptor);
|
||||
}
|
||||
|
||||
if (!DescriptorUtils.isInterface(descriptor)) {
|
||||
@@ -152,7 +161,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
@NotNull
|
||||
protected List<KtParameter> getPrimaryConstructorParameters() {
|
||||
if (myClass instanceof KtClass) {
|
||||
return ((KtClass) myClass).getPrimaryConstructorParameters();
|
||||
return myClass.getPrimaryConstructorParameters();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ class CollectionStubMethodGenerator(
|
||||
InstructionAdapter(mv),
|
||||
"java/lang/UnsupportedOperationException",
|
||||
"Operation is not supported for read-only collection")
|
||||
FunctionCodegen.endVisit(mv, "built-in stub for $signature", null)
|
||||
FunctionCodegen.endVisit(mv, "built-in stub for $signature")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtPureElement
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
@@ -52,7 +52,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
classBuilder: ClassBuilder,
|
||||
memberCodegen: MemberCodegen<*>,
|
||||
contextKind: OwnerKind,
|
||||
classOrObject: KtClassOrObject
|
||||
classOrObject: KtPureClassOrObject
|
||||
) {
|
||||
val methodElement = classOrObject.getPrimaryConstructor() ?: classOrObject
|
||||
|
||||
@@ -83,7 +83,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
* @return true if the overloads annotation was found on the element, false otherwise
|
||||
*/
|
||||
fun generateOverloadsIfNeeded(
|
||||
methodElement: KtElement?,
|
||||
methodElement: KtPureElement?,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
delegateFunctionDescriptor: FunctionDescriptor,
|
||||
contextKind: OwnerKind,
|
||||
@@ -122,7 +122,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
delegateFunctionDescriptor: FunctionDescriptor,
|
||||
classBuilder: ClassBuilder,
|
||||
memberCodegen: MemberCodegen<*>,
|
||||
methodElement: KtElement?,
|
||||
methodElement: KtPureElement?,
|
||||
contextKind: OwnerKind,
|
||||
substituteCount: Int
|
||||
) {
|
||||
@@ -248,7 +248,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
return functionDescriptor.valueParameters.filter { !it.declaresDefaultValue() || --remainingCount >= 0 }
|
||||
}
|
||||
|
||||
private fun isEmptyConstructorNeeded(constructorDescriptor: ConstructorDescriptor, classOrObject: KtClassOrObject): Boolean {
|
||||
private fun isEmptyConstructorNeeded(constructorDescriptor: ConstructorDescriptor, classOrObject: KtPureClassOrObject): Boolean {
|
||||
val classDescriptor = constructorDescriptor.constructedClass
|
||||
if (classDescriptor.kind != ClassKind.CLASS) return false
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
public final InstructionAdapter v;
|
||||
public final FrameMap myFrameMap;
|
||||
private final MethodContext context;
|
||||
public final MethodContext context;
|
||||
private final Type returnType;
|
||||
|
||||
private final CodegenStatementVisitor statementVisitor = new CodegenStatementVisitor(this);
|
||||
|
||||
@@ -44,10 +44,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
import org.jetbrains.kotlin.psi.KtFunction;
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction;
|
||||
import org.jetbrains.kotlin.psi.KtParameter;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
@@ -484,7 +481,7 @@ public class FunctionCodegen {
|
||||
if (indexOfLambdaOrdinal > 0) {
|
||||
int lambdaOrdinal = Integer.parseInt(name.substring(indexOfLambdaOrdinal + 1));
|
||||
|
||||
KtElement functionArgument = parentCodegen.element;
|
||||
KtPureElement functionArgument = parentCodegen.element;
|
||||
String functionName = "unknown";
|
||||
if (functionArgument instanceof KtFunction) {
|
||||
ValueParameterDescriptor inlineArgumentDescriptor =
|
||||
@@ -674,6 +671,18 @@ public class FunctionCodegen {
|
||||
kind == JvmMethodParameterKind.SUPER_CALL_PARAM;
|
||||
}
|
||||
|
||||
public static void endVisit(MethodVisitor mv, @Nullable String description) {
|
||||
endVisit(mv, description, (PsiElement)null);
|
||||
}
|
||||
|
||||
public static void endVisit(MethodVisitor mv, @Nullable String description, @Nullable KtPureElement method) {
|
||||
endVisit(mv, description, (PsiElement)(method == null ? null : method.getPsiOrParent()));
|
||||
}
|
||||
|
||||
public static void endVisit(MethodVisitor mv, @Nullable String description, @NotNull KtElement method) {
|
||||
endVisit(mv, description, (PsiElement)method);
|
||||
}
|
||||
|
||||
public static void endVisit(MethodVisitor mv, @Nullable String description, @Nullable PsiElement method) {
|
||||
try {
|
||||
mv.visitMaxs(-1, -1);
|
||||
|
||||
@@ -37,9 +37,6 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
@@ -105,7 +102,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
new ArrayList<Function2<ImplementationBodyCodegen, ClassBuilder, Unit>>();
|
||||
|
||||
public ImplementationBodyCodegen(
|
||||
@NotNull KtClassOrObject aClass,
|
||||
@NotNull KtPureClassOrObject aClass,
|
||||
@NotNull ClassContext context,
|
||||
@NotNull ClassBuilder v,
|
||||
@NotNull GenerationState state,
|
||||
@@ -212,7 +209,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
v.defineClass(
|
||||
myClass,
|
||||
myClass.getPsiOrParent(),
|
||||
state.getClassFileVersion(),
|
||||
access,
|
||||
signature.getName(),
|
||||
@@ -221,7 +218,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
ArrayUtil.toStringArray(signature.getInterfaces())
|
||||
);
|
||||
|
||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||
v.visitSource(myClass.getContainingKtFile().getName(), null);
|
||||
|
||||
InlineCodegenUtil.initDefaultSourceMappingIfNeeded(context, this, state);
|
||||
|
||||
@@ -237,7 +234,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (isInterface(descriptor) && !isLocal && (!isJvm8Interface(descriptor, state) || state.getGenerateDefaultImplsForJvm8())) {
|
||||
Type defaultImplsType = state.getTypeMapper().mapDefaultImpls(descriptor);
|
||||
ClassBuilder defaultImplsBuilder =
|
||||
state.getFactory().newVisitor(JvmDeclarationOriginKt.DefaultImpls(myClass, descriptor), defaultImplsType, myClass.getContainingFile());
|
||||
state.getFactory().newVisitor(JvmDeclarationOriginKt.DefaultImpls(myClass.getPsiOrParent(), descriptor), defaultImplsType, myClass.getContainingKtFile());
|
||||
|
||||
CodegenContext parentContext = context.getParentContext();
|
||||
assert parentContext != null : "Parent context of interface declaration should not be null";
|
||||
@@ -371,10 +368,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
generateToArray();
|
||||
|
||||
genClosureFields(context.closure, v, typeMapper);
|
||||
if (context.closure != null)
|
||||
genClosureFields(context.closure, v, typeMapper);
|
||||
|
||||
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
|
||||
extension.generateClassSyntheticParts(v, state, myClass, descriptor);
|
||||
extension.generateClassSyntheticParts(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,10 +479,33 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
public Type genPropertyOnStack(
|
||||
InstructionAdapter iv,
|
||||
MethodContext context,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
Type classAsmType,
|
||||
int index
|
||||
) {
|
||||
iv.load(index, classAsmType);
|
||||
if (couldUseDirectAccessToProperty(propertyDescriptor, /* forGetter = */ true,
|
||||
/* isDelegated = */ false, context, state.getShouldInlineConstVals())) {
|
||||
Type type = typeMapper.mapType(propertyDescriptor.getType());
|
||||
String fieldName = ((FieldOwnerContext) context.getParentContext()).getFieldName(propertyDescriptor, false);
|
||||
iv.getfield(classAsmType.getInternalName(), fieldName, type.getDescriptor());
|
||||
return type;
|
||||
}
|
||||
else {
|
||||
//noinspection ConstantConditions
|
||||
Method method = typeMapper.mapAsmMethod(propertyDescriptor.getGetter());
|
||||
iv.invokevirtual(classAsmType.getInternalName(), method.getName(), method.getDescriptor(), false);
|
||||
return method.getReturnType();
|
||||
}
|
||||
}
|
||||
|
||||
private void generateFunctionsForDataClasses() {
|
||||
if (!descriptor.isData()) return;
|
||||
|
||||
new DataClassMethodGeneratorImpl(myClass, bindingContext).generate();
|
||||
if (!(myClass instanceof KtClassOrObject)) return;
|
||||
new DataClassMethodGeneratorImpl((KtClassOrObject)myClass, bindingContext).generate();
|
||||
}
|
||||
|
||||
private class DataClassMethodGeneratorImpl extends DataClassMethodGenerator {
|
||||
@@ -520,10 +541,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
for (PropertyDescriptor propertyDescriptor : properties) {
|
||||
Type asmType = typeMapper.mapType(propertyDescriptor);
|
||||
|
||||
Type thisPropertyType = genPropertyOnStack(iv, context, propertyDescriptor, 0);
|
||||
Type thisPropertyType = genPropertyOnStack(iv, context, propertyDescriptor, ImplementationBodyCodegen.this.classAsmType, 0);
|
||||
StackValue.coerce(thisPropertyType, asmType, iv);
|
||||
|
||||
Type otherPropertyType = genPropertyOnStack(iv, context, propertyDescriptor, 2);
|
||||
Type otherPropertyType = genPropertyOnStack(iv, context, propertyDescriptor, ImplementationBodyCodegen.this.classAsmType, 2);
|
||||
StackValue.coerce(otherPropertyType, asmType, iv);
|
||||
|
||||
if (asmType.getSort() == Type.FLOAT) {
|
||||
@@ -566,7 +587,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.mul(Type.INT_TYPE);
|
||||
}
|
||||
|
||||
Type propertyType = genPropertyOnStack(iv, context, propertyDescriptor, 0);
|
||||
Type propertyType = genPropertyOnStack(iv, context, propertyDescriptor, ImplementationBodyCodegen.this.classAsmType, 0);
|
||||
Type asmType = typeMapper.mapType(propertyDescriptor);
|
||||
StackValue.coerce(propertyType, asmType, iv);
|
||||
|
||||
@@ -621,7 +642,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
genInvokeAppendMethod(iv, JAVA_STRING_TYPE);
|
||||
|
||||
Type type = genPropertyOnStack(iv, context, propertyDescriptor, 0);
|
||||
Type type = genPropertyOnStack(iv, context, propertyDescriptor, ImplementationBodyCodegen.this.classAsmType, 0);
|
||||
|
||||
if (type.getSort() == Type.ARRAY) {
|
||||
Type elementType = correctElementType(type);
|
||||
@@ -648,23 +669,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
FunctionCodegen.endVisit(mv, "toString", myClass);
|
||||
}
|
||||
|
||||
private Type genPropertyOnStack(InstructionAdapter iv, MethodContext context, @NotNull PropertyDescriptor propertyDescriptor, int index) {
|
||||
iv.load(index, classAsmType);
|
||||
if (couldUseDirectAccessToProperty(propertyDescriptor, /* forGetter = */ true,
|
||||
/* isDelegated = */ false, context, state.getShouldInlineConstVals())) {
|
||||
Type type = typeMapper.mapType(propertyDescriptor.getType());
|
||||
String fieldName = ((FieldOwnerContext) context.getParentContext()).getFieldName(propertyDescriptor, false);
|
||||
iv.getfield(classAsmType.getInternalName(), fieldName, type.getDescriptor());
|
||||
return type;
|
||||
}
|
||||
else {
|
||||
//noinspection ConstantConditions
|
||||
Method method = typeMapper.mapAsmMethod(propertyDescriptor.getGetter());
|
||||
iv.invokevirtual(classAsmType.getInternalName(), method.getName(), method.getDescriptor(), false);
|
||||
return method.getReturnType();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateComponentFunction(@NotNull FunctionDescriptor function, @NotNull final ValueParameterDescriptor parameter) {
|
||||
PsiElement originalElement = DescriptorToSourceUtils.descriptorToDeclaration(parameter);
|
||||
@@ -684,7 +688,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, descriptorToDeclaration(parameter));
|
||||
assert property != null : "Property descriptor is not found for primary constructor parameter: " + parameter;
|
||||
|
||||
Type propertyType = genPropertyOnStack(iv, context, property, 0);
|
||||
Type propertyType = genPropertyOnStack(iv, context, property, ImplementationBodyCodegen.this.classAsmType, 0);
|
||||
StackValue.coerce(propertyType, componentType, iv);
|
||||
}
|
||||
iv.areturn(componentType);
|
||||
@@ -848,7 +852,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (!state.getClassBuilderMode().generateBodies) return;
|
||||
// Invoke the object constructor but ignore the result because INSTANCE will be initialized in the first line of <init>
|
||||
InstructionAdapter v = createOrGetClInitCodegen().v;
|
||||
markLineNumberForElement(element, v);
|
||||
markLineNumberForElement(element.getPsiOrParent(), v);
|
||||
v.anew(classAsmType);
|
||||
v.invokespecial(classAsmType.getInternalName(), "<init>", "()V", false);
|
||||
|
||||
@@ -860,11 +864,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
KtObjectDeclaration companionObject = CollectionsKt.firstOrNull(((KtClass) myClass).getCompanionObjects());
|
||||
assert companionObject != null : "Companion object not found: " + myClass.getText();
|
||||
@Nullable KtObjectDeclaration companionObject = CollectionsKt.firstOrNull(myClass.getCompanionObjects());
|
||||
|
||||
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject),
|
||||
ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
|
||||
}
|
||||
|
||||
private void generateCompanionObjectBackingFieldCopies() {
|
||||
@@ -935,7 +939,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
final KtPrimaryConstructor primaryConstructor = myClass.getPrimaryConstructor();
|
||||
JvmDeclarationOrigin origin = JvmDeclarationOriginKt
|
||||
.OtherOrigin(primaryConstructor != null ? primaryConstructor : myClass, constructorDescriptor);
|
||||
.OtherOrigin(primaryConstructor != null ? primaryConstructor : myClass.getPsiOrParent(), constructorDescriptor);
|
||||
functionCodegen.generateMethod(origin, constructorDescriptor, constructorContext,
|
||||
new FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@Override
|
||||
@@ -1332,7 +1336,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
CodegenUtilKt.reportTarget6InheritanceErrorIfNeeded(descriptor, myClass, restrictedInheritance, state);
|
||||
CodegenUtilKt.reportTarget6InheritanceErrorIfNeeded(descriptor, myClass.getPsiOrParent(), restrictedInheritance, state);
|
||||
}
|
||||
|
||||
private void generateDelegationToDefaultImpl(@NotNull final FunctionDescriptor traitFun, @NotNull final FunctionDescriptor inheritedFun) {
|
||||
|
||||
@@ -26,20 +26,19 @@ import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.DelegationToDefaultImpls
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import java.util.*
|
||||
|
||||
class InterfaceImplBodyCodegen(
|
||||
aClass: KtClassOrObject,
|
||||
aClass: KtPureClassOrObject,
|
||||
context: ClassContext,
|
||||
v: ClassBuilder,
|
||||
state: GenerationState,
|
||||
@@ -50,11 +49,11 @@ class InterfaceImplBodyCodegen(
|
||||
|
||||
override fun generateDeclaration() {
|
||||
v.defineClass(
|
||||
myClass, state.classFileVersion, ACC_PUBLIC or ACC_FINAL or ACC_SUPER,
|
||||
myClass.psiOrParent, state.classFileVersion, ACC_PUBLIC or ACC_FINAL or ACC_SUPER,
|
||||
typeMapper.mapDefaultImpls(descriptor).internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
|
||||
)
|
||||
v.visitSource(myClass.containingFile.name, null)
|
||||
v.visitSource(myClass.containingKtFile.name, null)
|
||||
}
|
||||
|
||||
override fun classForInnerClassRecord(): ClassDescriptor? {
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.name.SpecialNames;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
@@ -73,15 +74,18 @@ import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt.Synthetic;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclarationContainer*/> implements InnerClassConsumer {
|
||||
protected final GenerationState state;
|
||||
public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarationContainer*/> implements InnerClassConsumer {
|
||||
public final GenerationState state;
|
||||
|
||||
protected final T element;
|
||||
protected final FieldOwnerContext context;
|
||||
protected final ClassBuilder v;
|
||||
protected final FunctionCodegen functionCodegen;
|
||||
protected final PropertyCodegen propertyCodegen;
|
||||
protected final KotlinTypeMapper typeMapper;
|
||||
protected final BindingContext bindingContext;
|
||||
|
||||
public final ClassBuilder v;
|
||||
public final FunctionCodegen functionCodegen;
|
||||
public final PropertyCodegen propertyCodegen;
|
||||
public final KotlinTypeMapper typeMapper;
|
||||
public final BindingContext bindingContext;
|
||||
|
||||
protected final JvmFileClassesProvider fileClassesProvider;
|
||||
private final MemberCodegen<?> parentCodegen;
|
||||
private final ReifiedTypeParametersUsages reifiedTypeParametersUsages = new ReifiedTypeParametersUsages();
|
||||
@@ -260,9 +264,21 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
if (descriptor.getName().equals(SpecialNames.NO_NAME_PROVIDED)) {
|
||||
badDescriptor(descriptor, state.getClassBuilderMode());
|
||||
}
|
||||
genClassOrObject(parentContext, aClass, state, parentCodegen, descriptor);
|
||||
}
|
||||
|
||||
private static void genClassOrObject(
|
||||
@NotNull CodegenContext parentContext,
|
||||
@NotNull KtPureClassOrObject aClass,
|
||||
@NotNull GenerationState state,
|
||||
@Nullable MemberCodegen<?> parentCodegen,
|
||||
@NotNull ClassDescriptor descriptor
|
||||
) {
|
||||
|
||||
Type classType = state.getTypeMapper().mapClass(descriptor);
|
||||
ClassBuilder classBuilder = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(aClass, descriptor), classType, aClass.getContainingFile());
|
||||
ClassBuilder classBuilder = state.getFactory().newVisitor(
|
||||
JvmDeclarationOriginKt.OtherOrigin(aClass, descriptor),
|
||||
classType, aClass.getContainingKtFile());
|
||||
ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
|
||||
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, parentCodegen, false).generate();
|
||||
}
|
||||
@@ -277,6 +293,10 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
genClassOrObject(context, aClass, state, this);
|
||||
}
|
||||
|
||||
public void genSyntheticClassOrObject(SyntheticClassOrObjectDescriptor descriptor) {
|
||||
genClassOrObject(context, descriptor.getSyntheticDeclaration(), state, this, descriptor);
|
||||
}
|
||||
|
||||
private void writeInnerClasses() {
|
||||
// JVMS7 (4.7.6): a nested class or interface member will have InnerClasses information
|
||||
// for each enclosing class and for each immediate member
|
||||
@@ -389,7 +409,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected final ExpressionCodegen createOrGetClInitCodegen() {
|
||||
public final ExpressionCodegen createOrGetClInitCodegen() {
|
||||
if (clInit == null) {
|
||||
DeclarationDescriptor contextDescriptor = context.getContextDescriptor();
|
||||
SimpleFunctionDescriptorImpl clInitDescriptor = createClInitFunctionDescriptor(contextDescriptor);
|
||||
@@ -400,7 +420,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected MethodVisitor createClInitMethodVisitor(@NotNull DeclarationDescriptor contextDescriptor) {
|
||||
public MethodVisitor createClInitMethodVisitor(@NotNull DeclarationDescriptor contextDescriptor) {
|
||||
return v.newMethod(JvmDeclarationOriginKt.OtherOrigin(contextDescriptor), ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
}
|
||||
|
||||
@@ -599,7 +619,8 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
@NotNull
|
||||
public DefaultSourceMapper getOrCreateSourceMapper() {
|
||||
if (sourceMapper == null) {
|
||||
sourceMapper = new DefaultSourceMapper(SourceInfo.Companion.createInfo(element, getClassName()));
|
||||
// note: this is used for in InlineCodegen and the element is always physical (KtElement) there
|
||||
sourceMapper = new DefaultSourceMapper(SourceInfo.Companion.createInfo((KtElement)element, getClassName()));
|
||||
}
|
||||
return sourceMapper;
|
||||
}
|
||||
@@ -634,7 +655,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
new FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@Override
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
markLineNumberForElement(element, codegen.v);
|
||||
markLineNumberForElement(element.getPsiOrParent(), codegen.v);
|
||||
|
||||
generateMethodCallTo(original, accessor, codegen.v).coerceTo(signature.getReturnType(), codegen.v);
|
||||
|
||||
@@ -669,7 +690,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
|
||||
InstructionAdapter iv = codegen.v;
|
||||
|
||||
markLineNumberForElement(element, iv);
|
||||
markLineNumberForElement(element.getPsiOrParent(), iv);
|
||||
|
||||
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
|
||||
for (int i = 0, reg = 0; i < argTypes.length; i++) {
|
||||
|
||||
@@ -145,7 +145,7 @@ public class SamWrapperCodegen {
|
||||
iv.putfield(ownerType.getInternalName(), FUNCTION_FIELD_NAME, functionType.getDescriptor());
|
||||
|
||||
iv.visitInsn(RETURN);
|
||||
FunctionCodegen.endVisit(iv, "constructor of SAM wrapper", null);
|
||||
FunctionCodegen.endVisit(iv, "constructor of SAM wrapper");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1159,7 +1159,7 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
static class Property extends StackValueWithSimpleReceiver {
|
||||
public static class Property extends StackValueWithSimpleReceiver {
|
||||
private final CallableMethod getter;
|
||||
private final CallableMethod setter;
|
||||
private final Type backingFieldOwner;
|
||||
|
||||
@@ -223,7 +223,7 @@ fun ClassBuilder.generateMethod(
|
||||
|
||||
|
||||
fun reportTarget6InheritanceErrorIfNeeded(
|
||||
classDescriptor: ClassDescriptor, classElement: KtClassOrObject, restrictedInheritance: List<FunctionDescriptor>, state:GenerationState
|
||||
classDescriptor: ClassDescriptor, classElement: PsiElement, restrictedInheritance: List<FunctionDescriptor>, state:GenerationState
|
||||
) {
|
||||
if (!restrictedInheritance.isEmpty()) {
|
||||
val groupBy = restrictedInheritance.groupBy { descriptor -> descriptor.containingDeclaration as ClassDescriptor }
|
||||
|
||||
+5
-13
@@ -16,15 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.extensions
|
||||
|
||||
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
interface ExpressionCodegenExtension {
|
||||
companion object : ProjectExtensionDescriptor<ExpressionCodegenExtension>(
|
||||
@@ -47,10 +44,5 @@ interface ExpressionCodegenExtension {
|
||||
*/
|
||||
fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
|
||||
|
||||
fun generateClassSyntheticParts(
|
||||
classBuilder: ClassBuilder,
|
||||
state: GenerationState,
|
||||
classOrObject: KtClassOrObject,
|
||||
descriptor: ClassDescriptor
|
||||
) {}
|
||||
fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) {}
|
||||
}
|
||||
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
|
||||
import org.jetbrains.kotlin.codegen.*;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
||||
import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||
@@ -82,7 +81,6 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
||||
@@ -136,6 +134,13 @@ public class KotlinTypeMapper {
|
||||
return bindingContext.get(ASM_TYPE, classDescriptor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getPredefinedInternalNameForClass(@NotNull ClassDescriptor classDescriptor) {
|
||||
Type type = getPredefinedTypeForClass(classDescriptor);
|
||||
return type == null ? null : type.getInternalName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processErrorType(@NotNull KotlinType kotlinType, @NotNull ClassDescriptor descriptor) {
|
||||
if (classBuilderMode.generateBodies) {
|
||||
|
||||
@@ -94,6 +94,7 @@ import org.jetbrains.kotlin.name.isValidJavaFqName
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
|
||||
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
|
||||
@@ -167,6 +168,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
project.registerService(JvmVirtualFileFinderFactory::class.java, finderFactory)
|
||||
|
||||
ExpressionCodegenExtension.registerExtensionPoint(project)
|
||||
SyntheticResolveExtension.registerExtensionPoint(project)
|
||||
ClassBuilderInterceptorExtension.registerExtensionPoint(project)
|
||||
AnalysisHandlerExtension.registerExtensionPoint(project)
|
||||
PackageFragmentProviderExtension.registerExtensionPoint(project)
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ public interface ErrorsJvm {
|
||||
|
||||
DiagnosticFactory0<KtExpression> WHEN_ENUM_CAN_BE_NULL_IN_JAVA = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
DiagnosticFactory3<KtExpression, DeclarationDescriptor, DeclarationDescriptor, String> TARGET6_INTERFACE_INHERITANCE = DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory3<PsiElement, DeclarationDescriptor, DeclarationDescriptor, String> TARGET6_INTERFACE_INHERITANCE = DiagnosticFactory3.create(ERROR);
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
Object _initializer = new Object() {
|
||||
|
||||
+14
-3
@@ -18,8 +18,9 @@ package org.jetbrains.kotlin.resolve.jvm.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPureElement
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.*
|
||||
|
||||
@@ -55,9 +56,19 @@ fun OtherOrigin(element: PsiElement?, descriptor: DeclarationDescriptor?): JvmDe
|
||||
JvmDeclarationOrigin.NO_ORIGIN
|
||||
else JvmDeclarationOrigin(OTHER, element, descriptor)
|
||||
|
||||
fun OtherOrigin(element: KtPureElement?, descriptor: DeclarationDescriptor?): JvmDeclarationOrigin =
|
||||
OtherOrigin(element?.psiOrParent as PsiElement, descriptor)
|
||||
|
||||
fun OtherOrigin(element: KtElement, descriptor: DeclarationDescriptor?): JvmDeclarationOrigin =
|
||||
OtherOrigin(element as PsiElement, descriptor)
|
||||
|
||||
fun OtherOrigin(element: PsiElement): JvmDeclarationOrigin = OtherOrigin(element, null)
|
||||
|
||||
fun OtherOrigin(descriptor: DeclarationDescriptor): JvmDeclarationOrigin = OtherOrigin(null, descriptor)
|
||||
fun OtherOrigin(element: KtPureElement): JvmDeclarationOrigin = OtherOrigin(element, null)
|
||||
|
||||
fun OtherOrigin(element: KtElement): JvmDeclarationOrigin = OtherOrigin(element, null)
|
||||
|
||||
fun OtherOrigin(descriptor: DeclarationDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(OTHER, null, descriptor)
|
||||
|
||||
fun Bridge(descriptor: DeclarationDescriptor, element: PsiElement? = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)): JvmDeclarationOrigin =
|
||||
JvmDeclarationOrigin(BRIDGE, element, descriptor)
|
||||
@@ -72,7 +83,7 @@ fun MultifileClass(representativeFile: KtFile?, descriptor: PackageFragmentDescr
|
||||
fun MultifileClassPart(file: KtFile, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin =
|
||||
JvmDeclarationOrigin(MULTIFILE_CLASS_PART, file, descriptor)
|
||||
|
||||
fun DefaultImpls(element: KtClassOrObject, descriptor: ClassDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(INTERFACE_DEFAULT_IMPL, element, descriptor)
|
||||
fun DefaultImpls(element: PsiElement?, descriptor: ClassDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(INTERFACE_DEFAULT_IMPL, element, descriptor)
|
||||
fun DelegationToDefaultImpls(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin =
|
||||
JvmDeclarationOrigin(DELEGATION_TO_DEFAULT_IMPLS, element, descriptor)
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
+2
-1
@@ -153,12 +153,13 @@ private object JvmTypeFactoryImpl : JvmTypeFactory<JvmType> {
|
||||
|
||||
}
|
||||
|
||||
private object TypeMappingConfigurationImpl : TypeMappingConfiguration<JvmType> {
|
||||
internal object TypeMappingConfigurationImpl : TypeMappingConfiguration<JvmType> {
|
||||
override fun commonSupertype(types: Collection<KotlinType>): KotlinType {
|
||||
throw AssertionError("There should be no intersection type in existing descriptors, but found: " + types.joinToString())
|
||||
}
|
||||
|
||||
override fun getPredefinedTypeForClass(classDescriptor: ClassDescriptor) = null
|
||||
override fun getPredefinedInternalNameForClass(classDescriptor: ClassDescriptor): String? = null
|
||||
|
||||
override fun processErrorType(kotlinType: KotlinType, descriptor: ClassDescriptor) {
|
||||
// DO nothing
|
||||
|
||||
+10
-5
@@ -51,6 +51,7 @@ interface TypeMappingConfiguration<out T : Any> {
|
||||
|
||||
fun commonSupertype(types: Collection<@JvmSuppressWildcards KotlinType>): KotlinType
|
||||
fun getPredefinedTypeForClass(classDescriptor: ClassDescriptor): T?
|
||||
fun getPredefinedInternalNameForClass(classDescriptor: ClassDescriptor): String?
|
||||
fun processErrorType(kotlinType: KotlinType, descriptor: ClassDescriptor)
|
||||
}
|
||||
|
||||
@@ -133,7 +134,7 @@ fun <T : Any> mapType(
|
||||
factory.javaLangClassType
|
||||
else
|
||||
typeMappingConfiguration.getPredefinedTypeForClass(descriptor.original)
|
||||
?: factory.createObjectType(computeInternalName(descriptor.original, typeMappingConfiguration.innerClassNameFactory))
|
||||
?: factory.createObjectType(computeInternalName(descriptor.original, typeMappingConfiguration))
|
||||
|
||||
writeGenericType(kotlinType, jvmType, mode)
|
||||
|
||||
@@ -189,7 +190,7 @@ private fun <T : Any> mapBuiltInType(
|
||||
|
||||
internal fun computeInternalName(
|
||||
klass: ClassDescriptor,
|
||||
innerClassNameFactory: (outer: String, inner: String) -> String = TypeMappingConfiguration.DEFAULT_INNER_CLASS_NAME_FACTORY
|
||||
typeMappingConfiguration: TypeMappingConfiguration<*> = TypeMappingConfigurationImpl
|
||||
): String {
|
||||
val container = klass.containingDeclaration
|
||||
|
||||
@@ -199,10 +200,14 @@ internal fun computeInternalName(
|
||||
return if (fqName.isRoot) name else fqName.asString().replace('.', '/') + '/' + name
|
||||
}
|
||||
|
||||
assert(container is ClassDescriptor) { "Unexpected container: $container for $klass" }
|
||||
val containerClass = container as? ClassDescriptor ?:
|
||||
throw IllegalArgumentException("Unexpected container: $container for $klass")
|
||||
|
||||
val containerInternalName = computeInternalName(container as ClassDescriptor, innerClassNameFactory)
|
||||
return if (klass.kind == ClassKind.ENUM_ENTRY) containerInternalName else innerClassNameFactory(containerInternalName, name)
|
||||
val containerInternalName =
|
||||
typeMappingConfiguration.getPredefinedInternalNameForClass(containerClass) ?:
|
||||
computeInternalName(containerClass, typeMappingConfiguration)
|
||||
return if (klass.kind == ClassKind.ENUM_ENTRY) containerInternalName
|
||||
else typeMappingConfiguration.innerClassNameFactory(containerInternalName, name)
|
||||
}
|
||||
|
||||
private fun getRepresentativeUpperBound(descriptor: TypeParameterDescriptor): KotlinType {
|
||||
|
||||
@@ -868,12 +868,12 @@ public abstract class KotlinBuiltIns {
|
||||
return getPrimitiveTypeByFqName(getFqName(descriptor)) != null;
|
||||
}
|
||||
|
||||
private static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
|
||||
public static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
|
||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
return descriptor instanceof ClassDescriptor && classFqNameEquals(descriptor, fqName);
|
||||
}
|
||||
|
||||
private static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqName fqName) {
|
||||
public static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqName fqName) {
|
||||
return isConstructedFromGivenClass(type, fqName.toUnsafe());
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
<extensionPoint name="expressionCodegenExtension"
|
||||
interface="org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension"
|
||||
area="IDEA_PROJECT"/>
|
||||
<extensionPoint name="syntheticResolveExtension"
|
||||
interface="org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension"
|
||||
area="IDEA_PROJECT"/>
|
||||
<extensionPoint name="findUsagesHandlerDecorator"
|
||||
interface="org.jetbrains.kotlin.plugin.findUsages.handlers.KotlinFindUsagesHandlerDecorator"
|
||||
area="IDEA_PROJECT"/>
|
||||
|
||||
+8
-6
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.android.synthetic.res.AndroidSyntheticFunction
|
||||
import org.jetbrains.kotlin.android.synthetic.res.AndroidSyntheticProperty
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.FunctionCodegen
|
||||
import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
@@ -245,13 +246,14 @@ class AndroidExpressionCodegenExtension : ExpressionCodegenExtension {
|
||||
return (extensionReceiver as ReceiverValue).type.constructor.declarationDescriptor
|
||||
}
|
||||
|
||||
override fun generateClassSyntheticParts(
|
||||
classBuilder: ClassBuilder,
|
||||
state: GenerationState,
|
||||
classOrObject: KtClassOrObject,
|
||||
descriptor: ClassDescriptor
|
||||
) {
|
||||
override fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) {
|
||||
val classBuilder = codegen.v
|
||||
val state = codegen.state
|
||||
val classOrObject = codegen.myClass
|
||||
val descriptor = codegen.descriptor
|
||||
|
||||
if (descriptor.kind != ClassKind.CLASS || descriptor.isInner || DescriptorUtils.isLocal(descriptor)) return
|
||||
if (classOrObject !is KtClassOrObject) return // works only only on physical classes, not synthetic ones
|
||||
|
||||
// Do not generate anything if class is not supported
|
||||
val androidClassType = AndroidClassType.getClassType(descriptor)
|
||||
|
||||
Reference in New Issue
Block a user