Supported reification for anonymous objects and lambdas
This commit is contained in:
committed by
Andrey Breslav
parent
a689f6d243
commit
21699e1753
+39
-10
@@ -17,16 +17,18 @@
|
||||
package org.jetbrains.jet.codegen.inline;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConstructorInvocation {
|
||||
public class AnonymousObjectGeneration {
|
||||
|
||||
private final String ownerInternalName;
|
||||
|
||||
private final String desc;
|
||||
private final String constructorDesc;
|
||||
|
||||
private final Map<Integer, LambdaInfo> lambdasToInline;
|
||||
|
||||
@@ -41,19 +43,39 @@ public class ConstructorInvocation {
|
||||
private Map<String, LambdaInfo> capturedLambdasToInline;
|
||||
|
||||
private final boolean capturedOuterRegenerated;
|
||||
private final boolean needReification;
|
||||
private final boolean alreadyRegenerated;
|
||||
private final boolean isStaticOrigin;
|
||||
|
||||
ConstructorInvocation(
|
||||
AnonymousObjectGeneration(
|
||||
@NotNull String ownerInternalName,
|
||||
@NotNull String desc,
|
||||
@NotNull Map<Integer, LambdaInfo> lambdasToInline,
|
||||
boolean needReification,
|
||||
boolean isSameModule,
|
||||
boolean capturedOuterRegenerated
|
||||
@NotNull Map<Integer, LambdaInfo> lambdasToInline,
|
||||
boolean capturedOuterRegenerated,
|
||||
boolean alreadyRegenerated,
|
||||
@Nullable String constructorDesc,
|
||||
boolean isStaticOrigin
|
||||
) {
|
||||
this.ownerInternalName = ownerInternalName;
|
||||
this.desc = desc;
|
||||
this.constructorDesc = constructorDesc;
|
||||
this.lambdasToInline = lambdasToInline;
|
||||
this.isSameModule = isSameModule;
|
||||
this.capturedOuterRegenerated = capturedOuterRegenerated;
|
||||
this.needReification = needReification;
|
||||
this.alreadyRegenerated = alreadyRegenerated;
|
||||
this.isStaticOrigin = isStaticOrigin;
|
||||
}
|
||||
|
||||
public AnonymousObjectGeneration(
|
||||
@NotNull String ownerInternalName, boolean isSameModule, boolean needReification,
|
||||
boolean alreadyRegenerated,
|
||||
boolean isStaticOrigin
|
||||
) {
|
||||
this(
|
||||
ownerInternalName, isSameModule, needReification,
|
||||
new HashMap<Integer, LambdaInfo>(), false, alreadyRegenerated, null, isStaticOrigin
|
||||
);
|
||||
}
|
||||
|
||||
public String getOwnerInternalName() {
|
||||
@@ -61,7 +83,9 @@ public class ConstructorInvocation {
|
||||
}
|
||||
|
||||
public boolean shouldRegenerate() {
|
||||
return !lambdasToInline.isEmpty() || !isSameModule || capturedOuterRegenerated;
|
||||
return !alreadyRegenerated && (
|
||||
!lambdasToInline.isEmpty() || !isSameModule || capturedOuterRegenerated || needReification
|
||||
);
|
||||
}
|
||||
|
||||
public Map<Integer, LambdaInfo> getLambdasToInline() {
|
||||
@@ -100,7 +124,12 @@ public class ConstructorInvocation {
|
||||
this.capturedLambdasToInline = capturedLambdasToInline;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
@Nullable
|
||||
public String getConstructorDesc() {
|
||||
return constructorDesc;
|
||||
}
|
||||
|
||||
public boolean isStaticOrigin() {
|
||||
return isStaticOrigin;
|
||||
}
|
||||
}
|
||||
+39
-20
@@ -79,10 +79,21 @@ public class AnonymousObjectTransformer {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InlineResult doTransform(@NotNull ConstructorInvocation invocation, @NotNull FieldRemapper parentRemapper) {
|
||||
public InlineResult doTransform(@NotNull final AnonymousObjectGeneration anonymousObjectGen, @NotNull FieldRemapper parentRemapper) {
|
||||
ClassBuilder classBuilder = createClassBuilder();
|
||||
final List<MethodNode> methodsToTransform = new ArrayList<MethodNode>();
|
||||
|
||||
final InlineResult result = InlineResult.create();
|
||||
reader.accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
|
||||
@Override
|
||||
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
|
||||
if (signature != null) {
|
||||
ReifiedTypeInliner.SignatureReificationResult signatureResult = inliningContext.reifedTypeInliner.reifySignature(signature);
|
||||
signature = signatureResult.getNewSignature();
|
||||
result.markAsNeededFurtherReificationIf(signatureResult.getNeedFurtherReification());
|
||||
}
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOuterClass(@NotNull String owner, String name, String desc) {
|
||||
@@ -131,46 +142,47 @@ public class AnonymousObjectTransformer {
|
||||
ParametersBuilder allCapturedParamBuilder = ParametersBuilder.newBuilder();
|
||||
ParametersBuilder constructorParamBuilder = ParametersBuilder.newBuilder();
|
||||
List<CapturedParamInfo> additionalFakeParams =
|
||||
extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder, invocation);
|
||||
extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder, anonymousObjectGen);
|
||||
|
||||
InlineResult result = InlineResult.create();
|
||||
for (MethodNode next : methodsToTransform) {
|
||||
MethodVisitor visitor = newMethod(classBuilder, next);
|
||||
InlineResult funResult = inlineMethod(invocation, parentRemapper, visitor, next, allCapturedParamBuilder);
|
||||
InlineResult funResult = inlineMethod(anonymousObjectGen, parentRemapper, visitor, next, allCapturedParamBuilder);
|
||||
result.addAllClassesToRemove(funResult);
|
||||
result.markAsNeededFurtherReificationIf(funResult.needFurtherReification());
|
||||
}
|
||||
|
||||
InlineResult constructorResult =
|
||||
generateConstructorAndFields(classBuilder, allCapturedParamBuilder, constructorParamBuilder, invocation, parentRemapper, additionalFakeParams);
|
||||
generateConstructorAndFields(classBuilder, allCapturedParamBuilder, constructorParamBuilder, anonymousObjectGen, parentRemapper, additionalFakeParams);
|
||||
|
||||
result.addAllClassesToRemove(constructorResult);
|
||||
|
||||
classBuilder.done();
|
||||
|
||||
invocation.setNewLambdaType(newLambdaType);
|
||||
anonymousObjectGen.setNewLambdaType(newLambdaType);
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private InlineResult inlineMethod(
|
||||
@NotNull ConstructorInvocation invocation,
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGen,
|
||||
@NotNull FieldRemapper parentRemapper,
|
||||
@NotNull MethodVisitor resultVisitor,
|
||||
@NotNull MethodNode sourceNode,
|
||||
@NotNull ParametersBuilder capturedBuilder
|
||||
) {
|
||||
|
||||
boolean neededFurtherReification = inliningContext.reifedTypeInliner.reifyInstructions(sourceNode.instructions);
|
||||
Parameters parameters = getMethodParametersWithCaptured(capturedBuilder, sourceNode);
|
||||
|
||||
RegeneratedLambdaFieldRemapper remapper =
|
||||
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(),
|
||||
parameters, invocation.getCapturedLambdasToInline(),
|
||||
parameters, anonymousObjectGen.getCapturedLambdasToInline(),
|
||||
parentRemapper);
|
||||
|
||||
MethodInliner inliner = new MethodInliner(sourceNode, parameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
||||
remapper, isSameModule, "Transformer for " + invocation.getOwnerInternalName());
|
||||
remapper, isSameModule, "Transformer for " + anonymousObjectGen.getOwnerInternalName());
|
||||
|
||||
InlineResult result = inliner.doInline(resultVisitor, new LocalVarRemapper(parameters, 0), false, LabelOwner.NOT_APPLICABLE);
|
||||
result.markAsNeededFurtherReificationIf(neededFurtherReification);
|
||||
resultVisitor.visitMaxs(-1, -1);
|
||||
resultVisitor.visitEnd();
|
||||
return result;
|
||||
@@ -180,7 +192,7 @@ public class AnonymousObjectTransformer {
|
||||
@NotNull ClassBuilder classBuilder,
|
||||
@NotNull ParametersBuilder allCapturedBuilder,
|
||||
@NotNull ParametersBuilder constructorInlineBuilder,
|
||||
@NotNull ConstructorInvocation invocation,
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGen,
|
||||
@NotNull FieldRemapper parentRemapper,
|
||||
@NotNull List<CapturedParamInfo> constructorAdditionalFakeParams
|
||||
) {
|
||||
@@ -251,11 +263,11 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
RegeneratedLambdaFieldRemapper remapper =
|
||||
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(),
|
||||
constructorParameters, invocation.getCapturedLambdasToInline(),
|
||||
constructorParameters, anonymousObjectGen.getCapturedLambdasToInline(),
|
||||
parentRemapper);
|
||||
|
||||
MethodInliner inliner = new MethodInliner(constructor, constructorParameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
||||
remapper, isSameModule, "Transformer for constructor of " + invocation.getOwnerInternalName());
|
||||
remapper, isSameModule, "Transformer for constructor of " + anonymousObjectGen.getOwnerInternalName());
|
||||
InlineResult result = inliner.doInline(capturedFieldInitializer, new LocalVarRemapper(constructorParameters, 0), false,
|
||||
LabelOwner.NOT_APPLICABLE);
|
||||
constructorVisitor.visitMaxs(-1, -1);
|
||||
@@ -263,7 +275,7 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
AsmUtil.genClosureFields(capturedFieldsToGenerate, classBuilder);
|
||||
//TODO for inline method make public class
|
||||
invocation.setNewConstructorDescriptor(constructorDescriptor);
|
||||
anonymousObjectGen.setNewConstructorDescriptor(constructorDescriptor);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -302,19 +314,19 @@ public class AnonymousObjectTransformer {
|
||||
@NotNull MethodNode constructor,
|
||||
@NotNull ParametersBuilder capturedParamBuilder,
|
||||
@NotNull ParametersBuilder constructorParamBuilder,
|
||||
@NotNull final ConstructorInvocation invocation
|
||||
@NotNull final AnonymousObjectGeneration anonymousObjectGen
|
||||
) {
|
||||
|
||||
CapturedParamOwner owner = new CapturedParamOwner() {
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.getObjectType(invocation.getOwnerInternalName());
|
||||
return Type.getObjectType(anonymousObjectGen.getOwnerInternalName());
|
||||
}
|
||||
};
|
||||
|
||||
List<LambdaInfo> capturedLambdas = new ArrayList<LambdaInfo>(); //captured var of inlined parameter
|
||||
List<CapturedParamInfo> constructorAdditionalFakeParams = new ArrayList<CapturedParamInfo>();
|
||||
Map<Integer, LambdaInfo> indexToLambda = invocation.getLambdasToInline();
|
||||
Map<Integer, LambdaInfo> indexToLambda = anonymousObjectGen.getLambdasToInline();
|
||||
Set<Integer> capturedParams = new HashSet<Integer>();
|
||||
|
||||
//load captured parameters and patch instruction list (NB: there is also could be object fields)
|
||||
@@ -355,7 +367,14 @@ public class AnonymousObjectTransformer {
|
||||
}
|
||||
|
||||
constructorParamBuilder.addThis(oldObjectType, false);
|
||||
Type [] types = Type.getArgumentTypes(invocation.getDesc());
|
||||
String constructorDesc = anonymousObjectGen.getConstructorDesc();
|
||||
|
||||
if (constructorDesc == null) {
|
||||
// in case of anonymous object with empty closure
|
||||
constructorDesc = Type.getMethodDescriptor(Type.VOID_TYPE);
|
||||
}
|
||||
|
||||
Type [] types = Type.getArgumentTypes(constructorDesc);
|
||||
for (Type type : types) {
|
||||
LambdaInfo info = indexToLambda.get(constructorParamBuilder.getNextValueParameterIndex());
|
||||
ParameterInfo parameterInfo = constructorParamBuilder.addNextParameter(type, info != null, null);
|
||||
@@ -389,8 +408,8 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
|
||||
|
||||
invocation.setAllRecapturedParameters(allRecapturedParameters);
|
||||
invocation.setCapturedLambdasToInline(capturedLambdasToInline);
|
||||
anonymousObjectGen.setAllRecapturedParameters(allRecapturedParameters);
|
||||
anonymousObjectGen.setCapturedLambdasToInline(capturedLambdasToInline);
|
||||
|
||||
return constructorAdditionalFakeParams;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ public class InlineCodegen implements CallGenerator {
|
||||
.subGenerator(functionDescriptor.getName().asString()),
|
||||
codegen.getContext(),
|
||||
callElement,
|
||||
codegen.getParentCodegen().getClassName());
|
||||
codegen.getParentCodegen().getClassName(), reifiedTypeInliner);
|
||||
|
||||
MethodInliner inliner = new MethodInliner(node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule, "Method inlining " + callElement.getText()); //with captured
|
||||
|
||||
|
||||
@@ -232,6 +232,10 @@ public class InlineCodegenUtil {
|
||||
return "<init>".equals(methodName) && isAnonymousClass(internalName);
|
||||
}
|
||||
|
||||
public static boolean isAnonymousSingletonLoad(@NotNull String internalName, @NotNull String fieldName) {
|
||||
return JvmAbi.INSTANCE_FIELD.equals(fieldName) && isAnonymousClass(internalName);
|
||||
}
|
||||
|
||||
public static boolean isAnonymousClass(String internalName) {
|
||||
String shortName = getLastNamePart(internalName);
|
||||
int index = shortName.lastIndexOf("$");
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Set;
|
||||
public class InlineResult {
|
||||
|
||||
private final Set<String> classesToRemove = new HashSet<String>();
|
||||
private boolean needFurtherReification = false;
|
||||
|
||||
private InlineResult() {
|
||||
|
||||
@@ -48,4 +49,12 @@ public class InlineResult {
|
||||
public Set<String> getClassesToRemove() {
|
||||
return classesToRemove;
|
||||
}
|
||||
|
||||
public boolean needFurtherReification() {
|
||||
return needFurtherReification;
|
||||
}
|
||||
|
||||
public void markAsNeededFurtherReificationIf(boolean condtition) {
|
||||
this.needFurtherReification |= condtition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ public class InliningContext {
|
||||
|
||||
public final Map<String, String> typeMapping;
|
||||
|
||||
public final ReifiedTypeInliner reifedTypeInliner;
|
||||
|
||||
public final boolean isInliningLambda;
|
||||
|
||||
public final boolean classRegeneration;
|
||||
@@ -47,6 +49,7 @@ public class InliningContext {
|
||||
@NotNull GenerationState state,
|
||||
@NotNull NameGenerator nameGenerator,
|
||||
@NotNull Map<String, String> typeMapping,
|
||||
@NotNull ReifiedTypeInliner reifedTypeInliner,
|
||||
boolean isInliningLambda,
|
||||
boolean classRegeneration
|
||||
) {
|
||||
@@ -55,6 +58,7 @@ public class InliningContext {
|
||||
this.state = state;
|
||||
this.nameGenerator = nameGenerator;
|
||||
this.typeMapping = typeMapping;
|
||||
this.reifedTypeInliner = reifedTypeInliner;
|
||||
this.isInliningLambda = isInliningLambda;
|
||||
this.classRegeneration = classRegeneration;
|
||||
}
|
||||
@@ -75,11 +79,12 @@ public class InliningContext {
|
||||
|
||||
public InliningContext subInlineWithClassRegeneration(@NotNull NameGenerator generator,
|
||||
@NotNull Map<String, String> additionalTypeMappings,
|
||||
@NotNull ConstructorInvocation constructorInvocation) {
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
|
||||
) {
|
||||
Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
|
||||
newTypeMappings.putAll(additionalTypeMappings);
|
||||
return new RegenetedClassContext(this, expressionMap, state, generator,
|
||||
newTypeMappings, isInliningLambda, constructorInvocation);
|
||||
newTypeMappings, reifedTypeInliner, isInliningLambda, anonymousObjectGeneration);
|
||||
|
||||
}
|
||||
|
||||
@@ -96,7 +101,7 @@ public class InliningContext {
|
||||
Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
|
||||
newTypeMappings.putAll(additionalTypeMappings);
|
||||
return new InliningContext(this, expressionMap, state, generator,
|
||||
newTypeMappings, isInliningLambda, isRegeneration);
|
||||
newTypeMappings, reifedTypeInliner, isInliningLambda, isRegeneration);
|
||||
}
|
||||
|
||||
public boolean isRoot() {
|
||||
|
||||
@@ -29,10 +29,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
import org.jetbrains.org.objectweb.asm.commons.RemappingMethodAdapter;
|
||||
@@ -62,7 +59,7 @@ public class MethodInliner {
|
||||
private final List<InvokeCall> invokeCalls = new ArrayList<InvokeCall>();
|
||||
|
||||
//keeps order
|
||||
private final List<ConstructorInvocation> constructorInvocations = new ArrayList<ConstructorInvocation>();
|
||||
private final List<AnonymousObjectGeneration> anonymousObjectGenerations = new ArrayList<AnonymousObjectGeneration>();
|
||||
//current state
|
||||
private final Map<String, String> currentTypeMapping = new HashMap<String, String>();
|
||||
|
||||
@@ -140,44 +137,55 @@ public class MethodInliner {
|
||||
|
||||
final MethodNode resultNode = new MethodNode(node.access, node.name, node.desc, node.signature, null);
|
||||
|
||||
final Iterator<ConstructorInvocation> iterator = constructorInvocations.iterator();
|
||||
final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator();
|
||||
|
||||
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode,
|
||||
new TypeRemapper(currentTypeMapping));
|
||||
|
||||
InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.totalSize()) {
|
||||
|
||||
private ConstructorInvocation invocation;
|
||||
private AnonymousObjectGeneration anonymousObjectGen;
|
||||
private void handleAnonymousObjectGeneration() {
|
||||
anonymousObjectGen = iterator.next();
|
||||
|
||||
if (anonymousObjectGen.shouldRegenerate()) {
|
||||
//TODO: need poping of type but what to do with local funs???
|
||||
Type newLambdaType = Type.getObjectType(inliningContext.nameGenerator.genLambdaClassName());
|
||||
currentTypeMapping.put(anonymousObjectGen.getOwnerInternalName(), newLambdaType.getInternalName());
|
||||
AnonymousObjectTransformer transformer =
|
||||
new AnonymousObjectTransformer(anonymousObjectGen.getOwnerInternalName(),
|
||||
inliningContext
|
||||
.subInlineWithClassRegeneration(
|
||||
inliningContext.nameGenerator,
|
||||
currentTypeMapping,
|
||||
anonymousObjectGen),
|
||||
isSameModule, newLambdaType
|
||||
);
|
||||
|
||||
InlineResult transformResult = transformer.doTransform(anonymousObjectGen, nodeRemapper);
|
||||
result.addAllClassesToRemove(transformResult);
|
||||
|
||||
if (inliningContext.isInliningLambda && !anonymousObjectGen.isStaticOrigin()) {
|
||||
// this class is transformed and original not used so we should remove original one after inlining
|
||||
// Note: It is unsafe to remove anonymous class that is referenced by GETSTATIC within lambda
|
||||
// because it can be local function from outer scope
|
||||
result.addClassToRemove(anonymousObjectGen.getOwnerInternalName());
|
||||
}
|
||||
|
||||
if (transformResult.needFurtherReification()) {
|
||||
ReifiedTypeInliner.putNeedClassReificationMarker(mv);
|
||||
result.markAsNeededFurtherReificationIf(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void anew(@NotNull Type type) {
|
||||
if (isAnonymousConstructorCall(type.getInternalName(), "<init>")) {
|
||||
invocation = iterator.next();
|
||||
|
||||
if (invocation.shouldRegenerate()) {
|
||||
//TODO: need poping of type but what to do with local funs???
|
||||
Type newLambdaType = Type.getObjectType(inliningContext.nameGenerator.genLambdaClassName());
|
||||
currentTypeMapping.put(invocation.getOwnerInternalName(), newLambdaType.getInternalName());
|
||||
AnonymousObjectTransformer transformer =
|
||||
new AnonymousObjectTransformer(invocation.getOwnerInternalName(),
|
||||
inliningContext
|
||||
.subInlineWithClassRegeneration(
|
||||
inliningContext.nameGenerator,
|
||||
currentTypeMapping,
|
||||
invocation),
|
||||
isSameModule, newLambdaType
|
||||
);
|
||||
|
||||
InlineResult transformResult = transformer.doTransform(invocation, nodeRemapper);
|
||||
result.addAllClassesToRemove(transformResult);
|
||||
|
||||
if (inliningContext.isInliningLambda) {
|
||||
//this class is transformed and original not used so we should remove original one after inlining
|
||||
result.addClassToRemove(invocation.getOwnerInternalName());
|
||||
}
|
||||
}
|
||||
handleAnonymousObjectGeneration();
|
||||
}
|
||||
|
||||
//in case of regenerated invocation type would be remapped to new one via remappingMethodAdapter
|
||||
//in case of regenerated anonymousObjectGen type would be remapped to new one via remappingMethodAdapter
|
||||
super.anew(type);
|
||||
}
|
||||
|
||||
@@ -222,24 +230,35 @@ public class MethodInliner {
|
||||
addInlineMarker(this, false);
|
||||
}
|
||||
else if (isAnonymousConstructorCall(owner, name)) { //TODO add method
|
||||
assert invocation != null : "<init> call not corresponds to new call" + owner + " " + name;
|
||||
if (invocation.shouldRegenerate()) {
|
||||
assert anonymousObjectGen != null : "<init> call not corresponds to new call" + owner + " " + name;
|
||||
if (anonymousObjectGen.shouldRegenerate()) {
|
||||
//put additional captured parameters on stack
|
||||
for (CapturedParamDesc capturedParamDesc : invocation.getAllRecapturedParameters()) {
|
||||
for (CapturedParamDesc capturedParamDesc : anonymousObjectGen.getAllRecapturedParameters()) {
|
||||
visitFieldInsn(Opcodes.GETSTATIC, capturedParamDesc.getContainingLambdaName(),
|
||||
"$$$" + capturedParamDesc.getFieldName(), capturedParamDesc.getType().getDescriptor());
|
||||
}
|
||||
super.visitMethodInsn(opcode, invocation.getNewLambdaType().getInternalName(), name, invocation.getNewConstructorDescriptor(), itf);
|
||||
invocation = null;
|
||||
super.visitMethodInsn(opcode, anonymousObjectGen.getNewLambdaType().getInternalName(), name, anonymousObjectGen.getNewConstructorDescriptor(), itf);
|
||||
anonymousObjectGen = null;
|
||||
} else {
|
||||
super.visitMethodInsn(opcode, changeOwnerForExternalPackage(owner, opcode), name, desc, itf);
|
||||
}
|
||||
}
|
||||
else if (ReifiedTypeInliner.isNeedClassReificationMarker(new MethodInsnNode(opcode, owner, name, desc, false))) {
|
||||
// we will put it if needed in anew processing
|
||||
}
|
||||
else {
|
||||
super.visitMethodInsn(opcode, changeOwnerForExternalPackage(owner, opcode), name, desc, itf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, @NotNull String owner, @NotNull String name, @NotNull String desc) {
|
||||
if (opcode == Opcodes.GETSTATIC && isAnonymousSingletonLoad(owner, name)) {
|
||||
handleAnonymousObjectGeneration();
|
||||
}
|
||||
super.visitFieldInsn(opcode, owner, name, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMaxs(int stack, int locals) {
|
||||
lambdasFinallyBlocks = resultNode.tryCatchBlocks.size();
|
||||
@@ -358,11 +377,17 @@ public class MethodInliner {
|
||||
AbstractInsnNode cur = node.instructions.getFirst();
|
||||
int index = 0;
|
||||
|
||||
boolean awaitClassReification = false;
|
||||
Set<LabelNode> possibleDeadLabels = new HashSet<LabelNode>();
|
||||
|
||||
while (cur != null) {
|
||||
Frame<SourceValue> frame = sources[index];
|
||||
|
||||
if (frame != null) {
|
||||
if (cur.getType() == AbstractInsnNode.METHOD_INSN) {
|
||||
if (ReifiedTypeInliner.isNeedClassReificationMarker(cur)) {
|
||||
awaitClassReification = true;
|
||||
}
|
||||
else if (cur.getType() == AbstractInsnNode.METHOD_INSN) {
|
||||
MethodInsnNode methodInsnNode = (MethodInsnNode) cur;
|
||||
String owner = methodInsnNode.owner;
|
||||
String desc = methodInsnNode.desc;
|
||||
@@ -403,11 +428,27 @@ public class MethodInliner {
|
||||
}
|
||||
}
|
||||
|
||||
constructorInvocations.add(new ConstructorInvocation(owner, desc, lambdaMapping, isSameModule, inliningContext.classRegeneration));
|
||||
anonymousObjectGenerations.add(
|
||||
buildConstructorInvocation(
|
||||
owner, desc, lambdaMapping, awaitClassReification
|
||||
)
|
||||
);
|
||||
awaitClassReification = false;
|
||||
}
|
||||
}
|
||||
else if (cur.getOpcode() == Opcodes.GETSTATIC) {
|
||||
FieldInsnNode fieldInsnNode = (FieldInsnNode) cur;
|
||||
String owner = fieldInsnNode.owner;
|
||||
if (isAnonymousSingletonLoad(owner, fieldInsnNode.name)) {
|
||||
anonymousObjectGenerations.add(
|
||||
new AnonymousObjectGeneration(
|
||||
owner, isSameModule, awaitClassReification, isAlreadyRegenerated(owner), true
|
||||
)
|
||||
);
|
||||
awaitClassReification = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AbstractInsnNode prevNode = cur;
|
||||
cur = cur.getNext();
|
||||
index++;
|
||||
@@ -446,6 +487,26 @@ public class MethodInliner {
|
||||
return start == end;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private AnonymousObjectGeneration buildConstructorInvocation(
|
||||
@NotNull String owner,
|
||||
@NotNull String desc,
|
||||
@NotNull Map<Integer, LambdaInfo> lambdaMapping,
|
||||
boolean needReification
|
||||
) {
|
||||
return new AnonymousObjectGeneration(
|
||||
owner, needReification, isSameModule, lambdaMapping,
|
||||
inliningContext.classRegeneration,
|
||||
isAlreadyRegenerated(owner),
|
||||
desc,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
private boolean isAlreadyRegenerated(@NotNull String owner) {
|
||||
return inliningContext.typeMapping.containsKey(owner);
|
||||
}
|
||||
|
||||
public LambdaInfo getLambdaIfExists(AbstractInsnNode insnNode) {
|
||||
if (insnNode.getOpcode() == Opcodes.ALOAD) {
|
||||
int varIndex = ((VarInsnNode) insnNode).var;
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Map;
|
||||
public class RegenetedClassContext extends InliningContext {
|
||||
|
||||
@NotNull
|
||||
private final ConstructorInvocation constructorInvocation;
|
||||
private final AnonymousObjectGeneration anonymousObjectGeneration;
|
||||
|
||||
protected RegenetedClassContext(
|
||||
@Nullable InliningContext parent,
|
||||
@@ -33,15 +33,16 @@ public class RegenetedClassContext extends InliningContext {
|
||||
@NotNull GenerationState state,
|
||||
@NotNull NameGenerator nameGenerator,
|
||||
@NotNull Map<String, String> typeMapping,
|
||||
@NotNull ReifiedTypeInliner reifiedTypeInliner,
|
||||
boolean isInliningLambda,
|
||||
@NotNull ConstructorInvocation constructorInvocation
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
|
||||
) {
|
||||
super(parent, map, state, nameGenerator, typeMapping, isInliningLambda, true);
|
||||
this.constructorInvocation = constructorInvocation;
|
||||
super(parent, map, state, nameGenerator, typeMapping, reifiedTypeInliner, isInliningLambda, true);
|
||||
this.anonymousObjectGeneration = anonymousObjectGeneration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassNameToInline() {
|
||||
return constructorInvocation.getOwnerInternalName();
|
||||
return anonymousObjectGeneration.getOwnerInternalName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,10 @@ public class RootInliningContext extends InliningContext {
|
||||
@NotNull NameGenerator nameGenerator,
|
||||
@NotNull CodegenContext startContext,
|
||||
@NotNull JetElement callElement,
|
||||
@NotNull String classNameToInline
|
||||
@NotNull String classNameToInline,
|
||||
@NotNull ReifiedTypeInliner inliner
|
||||
) {
|
||||
super(null, map, state, nameGenerator, Collections.<String, String>emptyMap(), false, false);
|
||||
super(null, map, state, nameGenerator, Collections.<String, String>emptyMap(), inliner, false, false);
|
||||
this.callElement = callElement;
|
||||
this.startContext = startContext;
|
||||
this.classNameToInline = classNameToInline;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
inline fun foo(x: String, block: (String) -> String) = block(x)
|
||||
|
||||
fun box(): String {
|
||||
val res = foo("abc") {
|
||||
fun bar(y: String) = y + "cde"
|
||||
bar(it)
|
||||
}
|
||||
|
||||
assertEquals("abccde", res)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
inline fun foo(x: String, block: (String) -> String) = block(x)
|
||||
|
||||
fun box(): String {
|
||||
val res = foo("abc") {
|
||||
fun bar(y: String) = y + "cde"
|
||||
foo(it) { bar(it) }
|
||||
}
|
||||
|
||||
assertEquals("abccde", res)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
inline fun foo(x: String, block: (String) -> String) = block(x)
|
||||
fun noInlineFoo(x: String, block: (String) -> String) = block(x)
|
||||
|
||||
fun box(): String {
|
||||
val res = foo("abc") {
|
||||
fun bar(y: String) = y + "cde"
|
||||
noInlineFoo(it) { bar(it) }
|
||||
}
|
||||
|
||||
assertEquals("abccde", res)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
inline fun foo(x: String, block: (String) -> String) = block(x)
|
||||
|
||||
fun box(): String {
|
||||
fun bar(y: String) = y + "cde"
|
||||
|
||||
val res = foo("abc") { bar(it) }
|
||||
|
||||
assertEquals("abccde", res)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
abstract class A {
|
||||
abstract fun f(): String
|
||||
}
|
||||
|
||||
inline fun<reified T> foo(): A {
|
||||
return object : A() {
|
||||
override fun f(): String {
|
||||
return javaClass<T>().getName()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val y = foo<String>();
|
||||
assertEquals("java.lang.String", y.f())
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
abstract class A<R> {
|
||||
abstract fun f(): String
|
||||
}
|
||||
|
||||
inline fun<reified T> foo(): A<T> {
|
||||
return object : A<T>() {
|
||||
override fun f(): String {
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val y = foo<String>();
|
||||
assertEquals("OK", y.f())
|
||||
assertEquals("A<java.lang.String>", y.javaClass.getGenericSuperclass()?.toString())
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
abstract class A<R> {
|
||||
abstract fun f(): String
|
||||
override fun toString() = f()
|
||||
}
|
||||
|
||||
abstract class G {
|
||||
abstract fun bar(): Any
|
||||
}
|
||||
|
||||
inline fun<reified T> foo(): G {
|
||||
return object : G() {
|
||||
override fun bar(): Any {
|
||||
return object : A<T>() {
|
||||
override fun f(): String = "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val y = foo<String>().bar();
|
||||
assertEquals("OK", y.toString())
|
||||
assertEquals("A<java.lang.String>", y.javaClass.getGenericSuperclass()?.toString())
|
||||
return "OK"
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun foo(block: () -> String) = block()
|
||||
inline fun<reified T> bar1(x: T): String = foo() {
|
||||
javaClass<T>().getName()
|
||||
}
|
||||
inline fun<reified T> bar2(x: T, y: String): String = foo() {
|
||||
javaClass<T>().getName() + "#" + y
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
assertEquals("java.lang.Integer", bar1(1))
|
||||
assertEquals("java.lang.String#OK", bar2("abc", "OK"))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
abstract class A<R> {
|
||||
abstract fun f(): String
|
||||
override fun toString() = f()
|
||||
}
|
||||
|
||||
abstract class G {
|
||||
abstract fun bar(): Any
|
||||
}
|
||||
|
||||
inline fun<reified T> baz(): G {
|
||||
return object : G() {
|
||||
override fun bar(): Any {
|
||||
return object : A<T>() {
|
||||
override fun f(): String = "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun<T1, T2, T3, T4, T5, T6, reified R1, reified R2> foo(): Pair<G, G> {
|
||||
return Pair(baz<R1>(), baz<R2>())
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val res = foo<Int, Int, Int, Int, Int, Int, Int, String>();
|
||||
val x1 = res.first.bar()
|
||||
val x2 = res.second.bar()
|
||||
assertEquals("OK", x1.toString())
|
||||
assertEquals("OK", x2.toString())
|
||||
assertEquals("A<java.lang.Integer>", x1.javaClass.getGenericSuperclass()?.toString())
|
||||
assertEquals("A<java.lang.String>", x2.javaClass.getGenericSuperclass()?.toString())
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun foo(block: () -> String) = block()
|
||||
|
||||
inline fun<reified T> bar1(): String = foo() {
|
||||
javaClass<T>().getName()
|
||||
}
|
||||
inline fun<reified T> bar2(y: String): String = foo() {
|
||||
javaClass<T>().getName() + "#" + y
|
||||
}
|
||||
|
||||
inline fun<T1, T2, reified R1, reified R2> bar3(y: String) =
|
||||
Pair(bar1<R1>(), bar2<R2>(y))
|
||||
|
||||
fun box(): String {
|
||||
val x = bar3<Any, Double, Int, String>("OK")
|
||||
|
||||
assertEquals("java.lang.Integer", x.first)
|
||||
assertEquals("java.lang.String#OK", x.second)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+70
-1
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.NonLocalReturns.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Reified.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class})
|
||||
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.LocalFunInLambda.class, BlackBoxWithStdlibCodegenTestGenerated.NonLocalReturns.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Reified.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class})
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInBoxWithStdlib() throws Exception {
|
||||
@@ -1452,6 +1452,39 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/localFunInLambda")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class LocalFunInLambda extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInLocalFunInLambda() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/localFunInLambda"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("definedWithinLambda.kt")
|
||||
public void testDefinedWithinLambda() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/localFunInLambda/definedWithinLambda.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("definedWithinLambdaInnerUsage1.kt")
|
||||
public void testDefinedWithinLambdaInnerUsage1() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/localFunInLambda/definedWithinLambdaInnerUsage1.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("definedWithinLambdaInnerUsage2.kt")
|
||||
public void testDefinedWithinLambdaInnerUsage2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/localFunInLambda/definedWithinLambdaInnerUsage2.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/localFunInLambda/simple.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/nonLocalReturns")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -2420,6 +2453,18 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reified"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousObject.kt")
|
||||
public void testAnonymousObject() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/anonymousObject.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousObjectReifiedSupertype.kt")
|
||||
public void testAnonymousObjectReifiedSupertype() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/anonymousObjectReifiedSupertype.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("checkcast.kt")
|
||||
public void testCheckcast() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/checkcast.kt");
|
||||
@@ -2438,6 +2483,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("innerAnonymousObject.kt")
|
||||
public void testInnerAnonymousObject() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/innerAnonymousObject.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("instanceof.kt")
|
||||
public void testInstanceof() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/instanceof.kt");
|
||||
@@ -2456,12 +2507,30 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nonInlineableLambdaInReifiedFunction.kt")
|
||||
public void testNonInlineableLambdaInReifiedFunction() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/nonInlineableLambdaInReifiedFunction.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveInnerAnonymousObject.kt")
|
||||
public void testRecursiveInnerAnonymousObject() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/recursiveInnerAnonymousObject.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveNewArray.kt")
|
||||
public void testRecursiveNewArray() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/recursiveNewArray.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveNonInlineableLambda.kt")
|
||||
public void testRecursiveNonInlineableLambda() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/recursiveNonInlineableLambda.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("safecast.kt")
|
||||
public void testSafecast() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/safecast.kt");
|
||||
|
||||
Reference in New Issue
Block a user