Don't generated redundant class files
This commit is contained in:
@@ -221,4 +221,10 @@ public final class ClassFileFactory extends GenerationStateAware implements Outp
|
||||
this.sourceFiles = sourceFiles;
|
||||
}
|
||||
}
|
||||
|
||||
public void removeInlinedClasses(Set<String> classNamesToRemove) {
|
||||
for (String classInternalName : classNamesToRemove) {
|
||||
generators.remove(classInternalName + ".class");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
|
||||
|
||||
try {
|
||||
node = createMethodNode(callableMethod);
|
||||
inlineCall(node);
|
||||
endCall(inlineCall(node));
|
||||
}
|
||||
catch (CompilationException e) {
|
||||
throw e;
|
||||
@@ -141,7 +141,13 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
|
||||
text, e, call.getCallElement());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void endCall(@NotNull InlineResult result) {
|
||||
leaveTemps();
|
||||
|
||||
state.getFactory().removeInlinedClasses(result.getClassesToRemove());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -191,7 +197,7 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
|
||||
return node;
|
||||
}
|
||||
|
||||
private void inlineCall(MethodNode node) {
|
||||
private InlineResult inlineCall(MethodNode node) {
|
||||
generateClosuresBodies();
|
||||
|
||||
List<ParameterInfo> realParams = new ArrayList<ParameterInfo>(actualParameters);
|
||||
@@ -205,16 +211,15 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
|
||||
InliningContext info =
|
||||
new InliningContext(expressionMap, null, null, null, state,
|
||||
codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()),
|
||||
codegen.getContext(), call, Collections.<String, String>emptyMap());
|
||||
codegen.getContext(), call, Collections.<String, String>emptyMap(), false);
|
||||
|
||||
MethodInliner inliner = new MethodInliner(node, parameters, info, null, new LambdaFieldRemapper(), isSameModule); //with captured
|
||||
|
||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, initialFrameSize);
|
||||
|
||||
inliner.doInline(codegen.v, remapper);
|
||||
return inliner.doInline(codegen.v, remapper);
|
||||
}
|
||||
|
||||
|
||||
private void generateClosuresBodies() {
|
||||
for (LambdaInfo info : expressionMap.values()) {
|
||||
info.setNode(generateLambdaBody(info));
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.jet.codegen.inline;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class InlineResult {
|
||||
|
||||
private final Set<String> classesToRemove = new HashSet<String>();
|
||||
|
||||
private InlineResult() {
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static InlineResult create() {
|
||||
return new InlineResult();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InlineResult addAllClassesToRemove(@NotNull InlineResult child) {
|
||||
classesToRemove.addAll(child.classesToRemove);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void addClassToRemove(@NotNull String classInternalName) {
|
||||
classesToRemove.add(classInternalName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<String> getClassesToRemove() {
|
||||
return classesToRemove;
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import java.util.Map;
|
||||
|
||||
public class InliningContext {
|
||||
|
||||
public final Map<Integer, LambdaInfo> expresssionMap;
|
||||
public final Map<Integer, LambdaInfo> expressionMap;
|
||||
|
||||
public final List<InvokeCall> invokeCalls;
|
||||
|
||||
@@ -45,6 +45,8 @@ public class InliningContext {
|
||||
|
||||
public final Map<String, String> typeMapping;
|
||||
|
||||
public final boolean isInliningLambda;
|
||||
|
||||
public InliningContext(
|
||||
Map<Integer, LambdaInfo> map,
|
||||
List<InvokeCall> accesses,
|
||||
@@ -54,9 +56,10 @@ public class InliningContext {
|
||||
NameGenerator nameGenerator,
|
||||
CodegenContext startContext,
|
||||
Call call,
|
||||
Map<String, String> typeMapping
|
||||
Map<String, String> typeMapping,
|
||||
boolean isInliningLambda
|
||||
) {
|
||||
expresssionMap = map;
|
||||
expressionMap = map;
|
||||
invokeCalls = accesses;
|
||||
constructorInvocation = invocation;
|
||||
this.remapper = remapper;
|
||||
@@ -65,16 +68,26 @@ public class InliningContext {
|
||||
this.startContext = startContext;
|
||||
this.call = call;
|
||||
this.typeMapping = typeMapping;
|
||||
this.isInliningLambda = isInliningLambda;
|
||||
}
|
||||
|
||||
public InliningContext subInline(NameGenerator generator) {
|
||||
return subInline(generator, Collections.<String, String>emptyMap());
|
||||
}
|
||||
|
||||
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings) {
|
||||
HashMap<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
|
||||
newTypeMappings.putAll(additionalTypeMappings);
|
||||
return new InliningContext(expresssionMap, invokeCalls, constructorInvocation, remapper, state, generator, startContext, call,
|
||||
newTypeMappings);
|
||||
public InliningContext subInlineLambda(NameGenerator generator) {
|
||||
return subInline(generator, Collections.<String, String>emptyMap(), true);
|
||||
}
|
||||
|
||||
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings) {
|
||||
return subInline(generator, additionalTypeMappings, isInliningLambda);
|
||||
}
|
||||
|
||||
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings, boolean isInliningLambda) {
|
||||
Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
|
||||
newTypeMappings.putAll(additionalTypeMappings);
|
||||
return new InliningContext(expressionMap, invokeCalls, constructorInvocation, remapper, state, generator, startContext, call,
|
||||
newTypeMappings, isInliningLambda);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public class LambdaTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
public void doTransform(ConstructorInvocation invocation) {
|
||||
public InlineResult doTransform(ConstructorInvocation invocation) {
|
||||
ClassBuilder classBuilder = createClassBuilder();
|
||||
|
||||
//TODO: public visibility for inline function
|
||||
@@ -128,7 +128,7 @@ public class LambdaTransformer {
|
||||
remapper = new RegeneratedLambdaFieldRemapper(oldLambdaType.getInternalName(), newLambdaType.getInternalName(), parameters, invocation.getCapturedLambdasToInline());
|
||||
MethodInliner inliner = new MethodInliner(invoke, parameters, info.subInline(info.nameGenerator.subGenerator("lambda")), oldLambdaType,
|
||||
remapper, isSameModule);
|
||||
inliner.doInline(invokeVisitor, new VarRemapper.ParamRemapper(parameters, 0), remapper, false);
|
||||
InlineResult result = inliner.doInline(invokeVisitor, new VarRemapper.ParamRemapper(parameters, 0), remapper, false);
|
||||
invokeVisitor.visitMaxs(-1, -1);
|
||||
|
||||
generateConstructorAndFields(classBuilder, builder, invocation);
|
||||
@@ -150,6 +150,7 @@ public class LambdaTransformer {
|
||||
classBuilder.done();
|
||||
|
||||
invocation.setNewLambdaType(newLambdaType);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void generateConstructorAndFields(@NotNull ClassBuilder classBuilder, @NotNull ParametersBuilder builder, @NotNull ConstructorInvocation invocation) {
|
||||
|
||||
@@ -46,6 +46,8 @@ public class MethodInliner {
|
||||
//current state
|
||||
private final Map<String, String> currentTypeMapping = new HashMap<String, String>();
|
||||
|
||||
private final InlineResult result;
|
||||
|
||||
/*
|
||||
*
|
||||
* @param node
|
||||
@@ -68,14 +70,15 @@ public class MethodInliner {
|
||||
this.lambdaFieldRemapper = lambdaFieldRemapper;
|
||||
this.isSameModule = isSameModule;
|
||||
this.typeMapper = parent.state.getTypeMapper();
|
||||
this.result = InlineResult.create();
|
||||
}
|
||||
|
||||
|
||||
public void doInline(MethodVisitor adapter, VarRemapper.ParamRemapper remapper) {
|
||||
doInline(adapter, remapper, new LambdaFieldRemapper(), true);
|
||||
public InlineResult doInline(MethodVisitor adapter, VarRemapper.ParamRemapper remapper) {
|
||||
return doInline(adapter, remapper, new LambdaFieldRemapper(), true);
|
||||
}
|
||||
|
||||
public void doInline(
|
||||
public InlineResult doInline(
|
||||
MethodVisitor adapter,
|
||||
VarRemapper.ParamRemapper remapper,
|
||||
LambdaFieldRemapper capturedRemapper, boolean remapReturn
|
||||
@@ -98,6 +101,7 @@ public class MethodInliner {
|
||||
transformedNode.accept(visitor);
|
||||
visitor.visitLabel(end);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private MethodNode doInline(MethodNode node, final LambdaFieldRemapper capturedRemapper) {
|
||||
@@ -128,6 +132,11 @@ public class MethodInliner {
|
||||
isSameModule, newLambdaType);
|
||||
|
||||
transformer.doTransform(invocation);
|
||||
|
||||
if (parent.isInliningLambda) {
|
||||
//this class is transformed and original not used so we should remove original one after inlining
|
||||
result.addClassToRemove(invocation.getOwnerInternalName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,11 +163,14 @@ public class MethodInliner {
|
||||
Parameters lambdaParameters = info.addAllParameters(capturedRemapper);
|
||||
|
||||
setInlining(true);
|
||||
MethodInliner inliner = new MethodInliner(info.getNode(), lambdaParameters, parent.subInline(parent.nameGenerator.subGenerator("lambda")), info.getLambdaClassType(),
|
||||
capturedRemapper, true /*cause all calls in same module as lambda*/);
|
||||
MethodInliner inliner = new MethodInliner(info.getNode(), lambdaParameters, parent.subInlineLambda(
|
||||
parent.nameGenerator.subGenerator("lambda")), info.getLambdaClassType(),
|
||||
capturedRemapper, true /*cause all calls in same module as lambda*/
|
||||
);
|
||||
|
||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(lambdaParameters, valueParamShift);
|
||||
inliner.doInline(this.mv, remapper); //TODO add skipped this and receiver
|
||||
InlineResult lambdaResult = inliner.doInline(this.mv, remapper);//TODO add skipped this and receiver
|
||||
result.addAllClassesToRemove(lambdaResult);
|
||||
|
||||
//return value boxing/unboxing
|
||||
Method bridge = typeMapper.mapSignature(ClosureCodegen.getInvokeFunction(info.getFunctionDescriptor())).getAsmMethod();
|
||||
|
||||
Reference in New Issue
Block a user