Fix duplicate field error on inlining several lambdas
This commit is contained in:
@@ -449,14 +449,6 @@ public class AsmUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static List<FieldInfo> transformCapturedParams(List<Pair<String, Type>> allFields, Type owner) {
|
||||
List<FieldInfo> result = new ArrayList<FieldInfo>();
|
||||
for (Pair<String, Type> field : allFields) {
|
||||
result.add(FieldInfo.createForHiddenField(owner, field.second, field.first));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int genAssignInstanceFieldFromParam(FieldInfo info, int index, InstructionAdapter iv) {
|
||||
assert !info.isStatic();
|
||||
Type fieldType = info.getFieldType();
|
||||
|
||||
+24
-15
@@ -285,26 +285,23 @@ public class AnonymousObjectTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
List<Pair<String, Type>> capturedFieldsToGenerate = new ArrayList<Pair<String, Type>>();
|
||||
for (CapturedParamInfo capturedParamInfo : allCapturedBuilder.listCaptured()) {
|
||||
if (capturedParamInfo.getLambda() == null) { //not inlined
|
||||
capturedFieldsToGenerate.add(new Pair<String, Type>(capturedParamInfo.getNewFieldName(), capturedParamInfo.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, descTypes.toArray(new Type[descTypes.size()]));
|
||||
|
||||
MethodVisitor constructorVisitor = classBuilder.newMethod(NO_ORIGIN,
|
||||
AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||
"<init>", constructorDescriptor,
|
||||
null, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
|
||||
//initialize captured fields
|
||||
List<FieldInfo> fields = AsmUtil.transformCapturedParams(capturedFieldsToGenerate, newLambdaType);
|
||||
List<NewJavaField> newFieldsWithSkipped = TransformationUtilsKt.getNewFieldsToGenerate(allCapturedBuilder.listCaptured());
|
||||
List<FieldInfo> fieldInfoWithSkipped = TransformationUtilsKt.transformToFieldInfo(newLambdaType, newFieldsWithSkipped);
|
||||
|
||||
int paramIndex = 0;
|
||||
InstructionAdapter capturedFieldInitializer = new InstructionAdapter(constructorVisitor);
|
||||
for (FieldInfo fieldInfo : fields) {
|
||||
AsmUtil.genAssignInstanceFieldFromParam(fieldInfo, capturedIndexes[paramIndex], capturedFieldInitializer);
|
||||
for (int i = 0; i < fieldInfoWithSkipped.size(); i++) {
|
||||
FieldInfo fieldInfo = fieldInfoWithSkipped.get(i);
|
||||
if (!newFieldsWithSkipped.get(i).getSkip()) {
|
||||
AsmUtil.genAssignInstanceFieldFromParam(fieldInfo, capturedIndexes[paramIndex], capturedFieldInitializer);
|
||||
}
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
@@ -328,8 +325,7 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
inlineMethodAndUpdateGlobalResult(anonymousObjectGen, parentRemapper, capturedFieldInitializer, constructor, constructorInlineBuilder, true);
|
||||
constructorVisitor.visitEnd();
|
||||
|
||||
AsmUtil.genClosureFields(capturedFieldsToGenerate, classBuilder);
|
||||
AsmUtil.genClosureFields(TransformationUtilsKt.toNameTypePair(TransformationUtilsKt.filterSkipped(newFieldsWithSkipped)), classBuilder);
|
||||
//TODO for inline method make public class
|
||||
anonymousObjectGen.setNewConstructorDescriptor(constructorDescriptor);
|
||||
}
|
||||
@@ -390,7 +386,7 @@ public class AnonymousObjectTransformer {
|
||||
}
|
||||
};
|
||||
|
||||
List<LambdaInfo> capturedLambdas = new ArrayList<LambdaInfo>(); //captured var of inlined parameter
|
||||
Set<LambdaInfo> capturedLambdas = new LinkedHashSet<LambdaInfo>(); //captured var of inlined parameter
|
||||
List<CapturedParamInfo> constructorAdditionalFakeParams = new ArrayList<CapturedParamInfo>();
|
||||
Map<Integer, LambdaInfo> indexToLambda = anonymousObjectGen.getLambdasToInline();
|
||||
Set<Integer> capturedParams = new HashSet<Integer>();
|
||||
@@ -459,10 +455,16 @@ public class AnonymousObjectTransformer {
|
||||
Map<String, LambdaInfo> capturedLambdasToInline = new HashMap<String, LambdaInfo>(); //captured var of inlined parameter
|
||||
List<CapturedParamDesc> allRecapturedParameters = new ArrayList<CapturedParamDesc>();
|
||||
boolean addCapturedNotAddOuter = parentFieldRemapper.isRoot() || (parentFieldRemapper instanceof InlinedLambdaRemapper && parentFieldRemapper.getParent().isRoot());
|
||||
Map<String, CapturedParamInfo> alreadyAdded = new HashMap<String, CapturedParamInfo>();
|
||||
for (LambdaInfo info : capturedLambdas) {
|
||||
if (addCapturedNotAddOuter) {
|
||||
for (CapturedParamDesc desc : info.getCapturedVars()) {
|
||||
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, getNewFieldName(desc.getFieldName(), false));
|
||||
String key = desc.getFieldName() + "$$$" + desc.getType().getClassName();
|
||||
CapturedParamInfo alreadyAddedParam = alreadyAdded.get(key);
|
||||
|
||||
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(
|
||||
desc,
|
||||
alreadyAddedParam != null ? alreadyAddedParam.getNewFieldName() : getNewFieldName(desc.getFieldName(), false));
|
||||
StackValue composed = StackValue.field(desc.getType(),
|
||||
oldObjectType, /*TODO owner type*/
|
||||
recapturedParamInfo.getNewFieldName(),
|
||||
@@ -472,6 +474,13 @@ public class AnonymousObjectTransformer {
|
||||
allRecapturedParameters.add(desc);
|
||||
|
||||
constructorParamBuilder.addCapturedParam(recapturedParamInfo, recapturedParamInfo.getNewFieldName()).setRemapValue(composed);
|
||||
if (alreadyAddedParam != null) {
|
||||
recapturedParamInfo.setSkipInConstructor(true);
|
||||
}
|
||||
|
||||
if (isThis0(desc.getFieldName())) {
|
||||
alreadyAdded.put(key, recapturedParamInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
capturedLambdasToInline.put(info.getLambdaClassType().getInternalName(), info);
|
||||
|
||||
@@ -33,6 +33,8 @@ public class CapturedParamInfo extends ParameterInfo {
|
||||
|
||||
private final String newFieldName;
|
||||
|
||||
private boolean skipInConstructor;
|
||||
|
||||
public CapturedParamInfo(@NotNull CapturedParamDesc desc, boolean skipped, int index, int remapIndex) {
|
||||
this(desc, desc.getFieldName(), skipped, index, remapIndex);
|
||||
}
|
||||
@@ -68,6 +70,7 @@ public class CapturedParamInfo extends ParameterInfo {
|
||||
public CapturedParamInfo clone(int newIndex, StackValue newRamapIndex) {
|
||||
CapturedParamInfo capturedParamInfo = new CapturedParamInfo(desc, newFieldName, isSkipped, newIndex, newRamapIndex);
|
||||
capturedParamInfo.setLambda(lambda);
|
||||
capturedParamInfo.setSkipInConstructor(skipInConstructor);
|
||||
return capturedParamInfo;
|
||||
}
|
||||
|
||||
@@ -75,4 +78,12 @@ public class CapturedParamInfo extends ParameterInfo {
|
||||
public String getContainingLambdaName() {
|
||||
return desc.getContainingLambdaName();
|
||||
}
|
||||
|
||||
public boolean isSkipInConstructor() {
|
||||
return skipInConstructor;
|
||||
}
|
||||
|
||||
public void setSkipInConstructor(boolean skipInConstructor) {
|
||||
this.skipInConstructor = skipInConstructor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.codegen.inline
|
||||
|
||||
import com.intellij.openapi.util.Pair
|
||||
import org.jetbrains.kotlin.codegen.FieldInfo
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class NewJavaField(val name: String, val type: Type, val skip: Boolean)
|
||||
|
||||
fun getNewFieldsToGenerate(params: List<CapturedParamInfo>): List<NewJavaField> {
|
||||
return params.filter {
|
||||
//not inlined
|
||||
it.lambda == null
|
||||
}.map {
|
||||
NewJavaField(it.newFieldName, it.type, it.isSkipInConstructor)
|
||||
}
|
||||
}
|
||||
|
||||
fun transformToFieldInfo(lambdaType: Type, newFields: List<NewJavaField>): List<FieldInfo> {
|
||||
return newFields.map { field ->
|
||||
FieldInfo.createForHiddenField(lambdaType, field.type, field.name)
|
||||
}
|
||||
}
|
||||
|
||||
fun filterSkipped(fields: List<NewJavaField>): List<NewJavaField> {
|
||||
return fields.filter { !it.skip }
|
||||
}
|
||||
|
||||
fun toNameTypePair(fields: List<NewJavaField>): List<Pair<String, Type>> = fields.map { Pair(it.name, it.type) }
|
||||
Reference in New Issue
Block a user