Pluggable Synthetic Objects
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user