-
Notifications
You must be signed in to change notification settings - Fork 70
Classes needed for lambda merging in ProGuard #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 31 commits
ca6936c
f0ed6b2
7f1f0af
b626bfc
e92a27b
2acc29c
e61c38d
e39c05e
5f24388
3338829
4f74d43
0d9cb78
8c81564
ea25197
fc68b07
cd4a6a3
5550c96
9860f9e
fcfa75e
a33e5da
bf8155b
b2877ea
9d3bb0c
8c82796
758be93
528e7a7
7821839
b542b9b
99065f7
4ef0e59
67cde7f
72a80b9
7eeff48
02e8fd0
660a391
59f7999
7d34770
7441f81
082b3a8
31f231d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package proguard.classfile.attribute.visitor; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add the ProGuardCORE header to all the classes? |
||
|
||
import proguard.classfile.Clazz; | ||
import proguard.classfile.constant.ClassConstant; | ||
import proguard.classfile.constant.Constant; | ||
import proguard.classfile.constant.visitor.ConstantVisitor; | ||
import proguard.classfile.visitor.ClassVisitor; | ||
|
||
public class ClassConstantToClassVisitor implements ConstantVisitor { | ||
|
||
private final ClassVisitor classVisitor; | ||
|
||
public ClassConstantToClassVisitor(ClassVisitor classVisitor) | ||
{ | ||
this.classVisitor = classVisitor; | ||
} | ||
|
||
public void visitAnyConstant(Clazz clazz, Constant constant) {} | ||
|
||
@Override | ||
public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { | ||
heckej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
if (this.classVisitor != null && classConstant.referencedClass != null) | ||
{ | ||
classConstant.referencedClass.accept(this.classVisitor); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package proguard.classfile.attribute.visitor; | ||
|
||
import proguard.classfile.Clazz; | ||
import proguard.classfile.ProgramClass; | ||
import proguard.classfile.attribute.InnerClassesInfo; | ||
import proguard.classfile.constant.visitor.ConstantVisitor; | ||
|
||
public class InnerClassInfoClassConstantVisitor implements InnerClassesInfoVisitor { | ||
heckej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
private final ConstantVisitor innerClassConstantVisitor; | ||
private final ConstantVisitor outerClassConstantVisitor; | ||
|
||
public InnerClassInfoClassConstantVisitor(ConstantVisitor innerClassConstantVisitor, ConstantVisitor outerClassConstantVisitor) | ||
{ | ||
this.innerClassConstantVisitor = innerClassConstantVisitor; | ||
this.outerClassConstantVisitor = outerClassConstantVisitor; | ||
} | ||
|
||
@Override | ||
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo) { | ||
if (this.innerClassConstantVisitor != null) | ||
{ | ||
innerClassesInfo.innerClassConstantAccept(clazz, this.innerClassConstantVisitor); | ||
} | ||
if (this.outerClassConstantVisitor != null) | ||
{ | ||
innerClassesInfo.outerClassConstantAccept(clazz, this.outerClassConstantVisitor); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package proguard.classfile.attribute.visitor; | ||
|
||
import proguard.classfile.Clazz; | ||
import proguard.classfile.attribute.InnerClassesAttribute; | ||
|
||
/** | ||
* This {@link AllInnerClassesInfoVisitor} revisits each {@link InnerClassesAttribute} everytime its amount of | ||
* referenced classes has been modified in the meantime. | ||
*/ | ||
public class ModifiedAllInnerClassesInfoVisitor extends AllInnerClassesInfoVisitor { | ||
heckej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
public ModifiedAllInnerClassesInfoVisitor(InnerClassesInfoVisitor innerClassesInfoVisitor) { | ||
super(innerClassesInfoVisitor); | ||
} | ||
|
||
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) | ||
{ | ||
int originalClassesCount = -1; | ||
while (originalClassesCount != innerClassesAttribute.u2classesCount) | ||
{ | ||
originalClassesCount = innerClassesAttribute.u2classesCount; | ||
super.visitInnerClassesAttribute(clazz, innerClassesAttribute); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package proguard.classfile.visitor; | ||
|
||
import proguard.classfile.Clazz; | ||
import proguard.classfile.constant.ClassConstant; | ||
import proguard.classfile.constant.Constant; | ||
import proguard.classfile.constant.visitor.ConstantVisitor; | ||
|
||
public class ClassConstantReferenceUpdater implements ConstantVisitor | ||
heckej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
{ | ||
private final Clazz originalClass; | ||
private final Clazz replacingClass; | ||
public ClassConstantReferenceUpdater(Clazz originalClass, Clazz replacingClass) | ||
{ | ||
this.originalClass = originalClass; | ||
this.replacingClass = replacingClass; | ||
} | ||
|
||
@Override | ||
public void visitAnyConstant(Clazz clazz, Constant constant) {} | ||
|
||
@Override | ||
public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { | ||
if (classConstant.referencedClass == originalClass) | ||
{ | ||
classConstant.referencedClass = replacingClass; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* ProGuard -- shrinking, optimization, obfuscation, and preverification | ||
* of Java bytecode. | ||
* | ||
* Copyright (c) 2002-2021 Guardsquare NV | ||
*/ | ||
|
||
package proguard.classfile.visitor; | ||
|
||
import proguard.classfile.*; | ||
|
||
/** | ||
* This {@link ClassVisitor} delegates its visits to given | ||
* acceptVisitor when the visited class has method with | ||
* given name and descriptor and delegates to rejectVisitor when | ||
* none of the class methods match. | ||
*/ | ||
public class ClassMethodFilter | ||
implements ClassVisitor | ||
{ | ||
private final String methodName; | ||
private final String descriptor; | ||
private final ClassVisitor acceptVisitor; | ||
private final ClassVisitor rejectVisitor; | ||
|
||
public ClassMethodFilter(String methodName, | ||
String descriptor, | ||
ClassVisitor acceptVisitor, | ||
ClassVisitor rejectVisitor) | ||
{ | ||
this.methodName = methodName; | ||
this.descriptor = descriptor; | ||
this.acceptVisitor = acceptVisitor; | ||
this.rejectVisitor = rejectVisitor; | ||
} | ||
|
||
@Override | ||
public void visitAnyClass(Clazz clazz) | ||
{ | ||
ClassVisitor delegateVisitor = delegateVisitor(clazz); | ||
if (delegateVisitor != null) | ||
{ | ||
delegateVisitor.visitAnyClass(clazz); | ||
heckej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
private ClassVisitor delegateVisitor(Clazz clazz) | ||
{ | ||
Method method = clazz.findMethod(methodName, descriptor); | ||
return method != null ? acceptVisitor : rejectVisitor; | ||
} | ||
} | ||
heckej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package proguard.classfile.visitor; | ||
|
||
import proguard.classfile.Clazz; | ||
import proguard.classfile.constant.ClassConstant; | ||
import proguard.classfile.constant.Constant; | ||
import proguard.classfile.constant.visitor.ConstantVisitor; | ||
|
||
public class ClassReferenceFinder implements ConstantVisitor | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might be replacable by the following It's extracted from Usable like the following:
But I see that
|
||
{ | ||
private final Clazz referencedClass; | ||
private boolean classIsReferenced = false; | ||
|
||
public ClassReferenceFinder(Clazz referencedClass) | ||
{ | ||
this.referencedClass = referencedClass; | ||
} | ||
|
||
public void visitAnyConstant(Clazz clazz, Constant constant) {} | ||
|
||
public void visitClassConstant(Clazz clazz, ClassConstant classConstant) | ||
{ | ||
if (classConstant.referencedClass != null && classConstant.referencedClass.equals(referencedClass)) | ||
{ | ||
this.classIsReferenced = true; | ||
} | ||
} | ||
|
||
public boolean classReferenceFound() | ||
{ | ||
return this.classIsReferenced; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,29 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
package proguard.classfile.visitor; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import proguard.classfile.Clazz; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import proguard.classfile.Method; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import proguard.classfile.attribute.Attribute; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import proguard.classfile.attribute.CodeAttribute; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import proguard.classfile.attribute.visitor.AttributeVisitor; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public class CodeSizeCounter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
implements AttributeVisitor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private int totalCodeSize = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Implementations for AttributeVisitor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
totalCodeSize += codeAttribute.u4codeLength; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public int getCount() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return totalCodeSize; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+9
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
We have a class like this already but it's not in ProGuardCORE at the moment. There's already the Can you move this also into the attribute/visitor package, since it's an |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package proguard.classfile.visitor; | ||
|
||
import proguard.classfile.Clazz; | ||
import proguard.classfile.constant.Constant; | ||
import proguard.classfile.constant.Utf8Constant; | ||
import proguard.classfile.constant.visitor.ConstantVisitor; | ||
|
||
public class DescriptorTypeUpdater implements ConstantVisitor | ||
{ | ||
private final String originalType; | ||
private final String replacingType; | ||
public DescriptorTypeUpdater(String originalType, String replacingType) | ||
{ | ||
this.originalType = originalType; | ||
this.replacingType = replacingType; | ||
} | ||
|
||
@Override | ||
public void visitAnyConstant(Clazz clazz, Constant constant) {} | ||
|
||
@Override | ||
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) { | ||
utf8Constant.setString(utf8Constant.getString().replace(originalType, replacingType)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here we should be using a
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package proguard.classfile.visitor; | ||
|
||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import proguard.classfile.*; | ||
import proguard.classfile.constant.FieldrefConstant; | ||
import proguard.classfile.constant.visitor.ConstantVisitor; | ||
import proguard.classfile.editor.ClassBuilder; | ||
import proguard.classfile.editor.ClassEditor; | ||
|
||
public class FieldCopier implements MemberVisitor, ConstantVisitor { | ||
|
||
|
||
private final ClassBuilder classBuilder; | ||
private final ClassEditor classEditor; | ||
private final FieldRenamer fieldRenamer; | ||
private ProgramField lastCopiedField; | ||
private boolean hasCopiedField = false; | ||
private static final Logger logger = LogManager.getLogger(FieldCopier.class); | ||
|
||
public FieldCopier(ClassBuilder builder, FieldRenamer renamer) | ||
{ | ||
this.classBuilder = builder; | ||
this.classEditor = new ClassEditor(builder.getProgramClass()); | ||
this.fieldRenamer = renamer; | ||
} | ||
|
||
@Override | ||
public void visitProgramField(ProgramClass programClass, ProgramField programField) | ||
{ | ||
String fieldName = programField.getName(programClass); | ||
if (this.fieldRenamer != null) | ||
{ | ||
fieldName = fieldRenamer.getNextFieldName(); | ||
} | ||
|
||
String fieldDescriptor = programField.getDescriptor(programClass); | ||
Field oldField = classBuilder.getProgramClass().findField(fieldName, null); | ||
Field oldFieldSameDescriptor = classBuilder.getProgramClass().findField(fieldName, fieldDescriptor); | ||
if (oldField != null && oldFieldSameDescriptor == null) | ||
{ | ||
String oldFieldDescriptor = oldField.getDescriptor(classBuilder.getProgramClass()); | ||
//logger.warn("Field " + fieldName + " already exists in class " + classBuilder.getProgramClass() + " with different descriptor: " + oldFieldDescriptor + " <-> " + fieldDescriptor + ". The field will be duplicated with different descriptors."); | ||
// Merge the field types: generalise to a common super type | ||
//fieldDescriptor = ClassConstants.TYPE_JAVA_LANG_OBJECT; | ||
} | ||
else if (oldFieldSameDescriptor != null) | ||
{ | ||
this.classEditor.removeField(oldFieldSameDescriptor); | ||
} | ||
ProgramField copiedField = classBuilder.addAndReturnField(programField.u2accessFlags, fieldName, fieldDescriptor); | ||
if (this.fieldRenamer != null) | ||
{ | ||
this.fieldRenamer.visitProgramField(classBuilder.getProgramClass(), copiedField); | ||
} | ||
this.lastCopiedField = copiedField; | ||
this.hasCopiedField = true; | ||
} | ||
|
||
@Override | ||
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) { | ||
fieldrefConstant.referencedFieldAccept(this); | ||
} | ||
|
||
public ProgramField getLastCopiedField() | ||
{ | ||
return this.lastCopiedField; | ||
} | ||
|
||
public boolean hasCopiedField() | ||
{ | ||
return this.hasCopiedField; | ||
} | ||
|
||
public void reset() | ||
{ | ||
this.hasCopiedField = false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package proguard.classfile.visitor; | ||
|
||
import proguard.classfile.Clazz; | ||
import proguard.classfile.constant.Constant; | ||
import proguard.classfile.constant.FieldrefConstant; | ||
import proguard.classfile.constant.visitor.ConstantVisitor; | ||
import proguard.classfile.util.ClassUtil; | ||
import proguard.util.ListParser; | ||
import proguard.util.NameParser; | ||
import proguard.util.StringMatcher; | ||
|
||
public class FieldReferenceFinder implements ConstantVisitor { | ||
heckej marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
private final Clazz referencedClass; | ||
private final StringMatcher regularExpressionMatcher; | ||
private final ConstantVisitor constantVisitor; | ||
private boolean fieldReferenceFound = false; | ||
|
||
public FieldReferenceFinder(Clazz referencedClass, | ||
String fieldNameRegularExpression, | ||
ConstantVisitor constantVisitor) | ||
{ | ||
this.referencedClass = referencedClass; | ||
this.regularExpressionMatcher = new ListParser(new NameParser(null)).parse(fieldNameRegularExpression); | ||
this.constantVisitor = constantVisitor; | ||
} | ||
|
||
@Override | ||
public void visitAnyConstant(Clazz clazz, Constant constant) {} | ||
|
||
@Override | ||
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant) | ||
{ | ||
if (fieldrefConstant.referencedClass == referencedClass | ||
&& this.regularExpressionMatcher.matches(fieldrefConstant.getName(clazz))) | ||
{ | ||
this.fieldReferenceFound = true; | ||
fieldrefConstant.accept(clazz, this.constantVisitor); | ||
} | ||
} | ||
|
||
public boolean isFieldReferenceFound() | ||
{ | ||
return this.fieldReferenceFound; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.