Skip to content

Commit d5b41bd

Browse files
authored
Remove dependency on JavaParser's solver, no need for it (#15)
* Remove dependency on JavaParser's solver, no need for it
1 parent bab7a1f commit d5b41bd

33 files changed

Lines changed: 1088 additions & 791 deletions

.editorconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ insert_final_newline = true
1010
charset = utf-8
1111
indent_style = tab
1212
indent_size = 4
13+
max_line_length = 180
1314

1415
[*.yml]
1516
indent_size = 2

build.gradle

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,16 @@ group = 'org.minimallycorrect.javatransformer'
1717
minimallyCorrectDefaults {
1818
description = "Applies transformations to .java and .class files"
1919
labels = ["java-transformation", "java-source", "java-bytecode", "java"]
20-
ignoreSunInternalWarnings = true
2120
configureProject(project)
2221
}
2322

2423
dependencies {
2524
testImplementation "junit:junit:4.12"
26-
//Can we make these dependencies optional? Reduced jar size if not using source for patching
2725
implementation 'org.ow2.asm:asm:7.2'
2826
implementation 'org.ow2.asm:asm-util:7.2'
2927
implementation 'org.ow2.asm:asm-tree:7.2'
30-
implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.6.24'
28+
implementation 'com.github.javaparser:javaparser-core:3.6.24'
29+
implementation 'com.google.code.findbugs:jsr305:3.0.2'
3130
}
3231

3332
tasks.withType(JavaCompile) {

src/main/java/org/minimallycorrect/javatransformer/api/ClassInfo.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
package org.minimallycorrect.javatransformer.api;
22

33
import java.util.List;
4-
import java.util.function.Function;
54
import java.util.stream.Stream;
65

76
import org.jetbrains.annotations.Contract;
87
import org.jetbrains.annotations.Nullable;
98

109
import org.minimallycorrect.javatransformer.internal.util.CollectionUtil;
1110

12-
public interface ClassInfo extends ClassMember {
11+
public interface ClassInfo extends ClassMember, HasTypeVariable {
1312
default void add(ClassMember member) {
1413
if (member instanceof MethodInfo)
1514
add((MethodInfo) member);
@@ -96,10 +95,6 @@ default Stream<ClassMember> getMembers() {
9695
return Stream.concat(getFields(), getMethods());
9796
}
9897

99-
default void accessFlags(Function<AccessFlags, AccessFlags> c) {
100-
setAccessFlags(c.apply(getAccessFlags()));
101-
}
102-
10398
@Override
10499
default ClassInfo getClassInfo() {
105100
return this;

src/main/java/org/minimallycorrect/javatransformer/api/JavaTransformer.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
import java.util.zip.ZipInputStream;
3232
import java.util.zip.ZipOutputStream;
3333

34-
import lombok.Getter;
3534
import lombok.NonNull;
36-
import lombok.Setter;
3735
import lombok.ToString;
3836
import lombok.val;
3937

@@ -42,11 +40,11 @@
4240
import org.objectweb.asm.ClassWriter;
4341
import org.objectweb.asm.tree.ClassNode;
4442

45-
import com.github.javaparser.*;
43+
import com.github.javaparser.JavaParser;
44+
import com.github.javaparser.ParseProblemException;
45+
import com.github.javaparser.ParseStart;
4646
import com.github.javaparser.ast.CompilationUnit;
4747
import com.github.javaparser.ast.body.TypeDeclaration;
48-
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
49-
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
5048

5149
import org.minimallycorrect.javatransformer.internal.ByteCodeInfo;
5250
import org.minimallycorrect.javatransformer.internal.SourceInfo;
@@ -58,8 +56,6 @@
5856
import org.minimallycorrect.javatransformer.internal.util.NodeUtil;
5957
import org.minimallycorrect.javatransformer.internal.util.StreamUtil;
6058

61-
@Getter
62-
@Setter
6359
@ToString
6460
public class JavaTransformer {
6561
private final List<Transformer> transformers = new ArrayList<>();
@@ -251,7 +247,7 @@ public Supplier<byte[]> transformJava(@NonNull Supplier<byte[]> data, @NonNull S
251247
CachingSupplier<TypeDeclaration<?>> supplier = CachingSupplier.of(() -> {
252248
byte[] bytes = data.get();
253249

254-
val parser = new JavaParser(new ParserConfiguration().setSymbolResolver(new JavaSymbolSolver((TypeSolver) classPath)));
250+
val parser = new JavaParser();
255251
val result = parser.parse(ParseStart.COMPILATION_UNIT, provider(new ByteArrayInputStream(bytes), Charset.forName("UTF8")));
256252
if (!result.isSuccessful()) {
257253
throw new ParseProblemException(result.getProblems());
@@ -346,6 +342,26 @@ public Class<?> defineClass(ClassLoader classLoader, String name) {
346342
return DefineClass.defineClass(classLoader, name, result);
347343
}
348344

345+
public List<Transformer> getTransformers() {
346+
return this.transformers;
347+
}
348+
349+
public Map<String, byte[]> getTransformedFiles() {
350+
return this.transformedFiles;
351+
}
352+
353+
public List<Consumer<JavaTransformer>> getAfterTransform() {
354+
return this.afterTransform;
355+
}
356+
357+
public ClassPath getClassPath() {
358+
return this.classPath;
359+
}
360+
361+
public void setClassPath(ClassPath classPath) {
362+
this.classPath = classPath;
363+
}
364+
349365
private enum PathType {
350366
JAR,
351367
FOLDER;

src/main/java/org/minimallycorrect/javatransformer/api/Parameter.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@
88
import lombok.EqualsAndHashCode;
99
import lombok.Getter;
1010
import lombok.NonNull;
11-
import lombok.ToString;
1211

1312
import org.jetbrains.annotations.Nullable;
1413

1514
@EqualsAndHashCode(exclude = {"annotationSupplier", "name"})
1615
@Getter
17-
@ToString
1816
public class Parameter implements Annotated {
1917
@Nullable
2018
public final String name;
@@ -39,4 +37,8 @@ public List<Annotation> getAnnotations() {
3937
return Collections.emptyList();
4038
return annotationSupplier.get();
4139
}
40+
41+
public String toString() {
42+
return "Parameter(name=" + this.getName() + ", type=" + this.getType() + ")";
43+
}
4244
}

src/main/java/org/minimallycorrect/javatransformer/api/Type.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,19 @@
4848
@Data
4949
public class Type {
5050
public static final Type UNKNOWN = new Type("Ljava/lang/Object;", "Tunknown;");
51+
public static final Type WILDCARD = new Type("Ljava/lang/Object;", "*");
5152
public static final Type OBJECT = Type.of("java.lang.Object");
5253
public static final Type BOOLEAN = new Type("Z");
5354
public static final Type DOUBLE = new Type("D");
5455
public static final Type FLOAT = new Type("F");
5556
public static final Type INT = new Type("I");
5657
public static final Type LONG = new Type("L");
58+
public static final Type CHAR = new Type("C");
59+
public static final Type STRING = Type.of("java.lang.String");
60+
public static final Type STATIC_META_CLASS = new Type("Ljvm/STATIC;", "Ljvm/STATIC;");
61+
public static final Type ANNOTATION = Type.of("java.lang.annotation.Annotation");
62+
public static final Type CLAZZ = Type.of("java.lang.Class");
63+
public static final Type LAMBDA = Type.of("Ljvm/LAMBDA;");
5764

5865
/**
5966
* A descriptor represents the real part of a type
@@ -102,6 +109,10 @@ private static void checkSignature(@Nullable String signature) {
102109
throw new TransformationException("Invalid signature '" + signature + "'. After generic bracket should either be '>' or ';'");
103110
}
104111

112+
public static Type staticMetaclassOf(Type type) {
113+
return STATIC_META_CLASS.withTypeArgument(type);
114+
}
115+
105116
public static Type of(String fullClassName) {
106117
// TODO: 23/01/2016 Handle inner classes properly? currently depend on following naming standards
107118
// depends on: lower case package names, uppercase first letter of class name
@@ -311,9 +322,13 @@ public Type withClassName(String name) {
311322
return new Type(descriptor, signature);
312323
}
313324

314-
public boolean isAssignableFrom(Type type) {
315-
return descriptor.equals(type.descriptor) ||
316-
(isClassType() && getClassName().equals("java.lang.Object") && (type.isArrayType() || type.isClassType()));
325+
public static boolean isAssignableFrom(Type to, Type from) {
326+
return to.descriptor.equals(from.descriptor) ||
327+
(to.isClassType() && to.getClassName().equals("java.lang.Object") && (from.isArrayType() || from.isClassType()));
328+
}
329+
330+
public boolean isStaticMetaClass() {
331+
return descriptor == STATIC_META_CLASS.descriptor;
317332
}
318333

319334
@AllArgsConstructor
@@ -368,6 +383,22 @@ public static DescriptorType of(char c) {
368383
throw new UnknownDescriptorTypeException("Unknnown descriptor type '" + c + "'");
369384
}
370385

386+
@Nullable
387+
public Integer getByteWidth() {
388+
switch (this) {
389+
case BYTE:
390+
return 1;
391+
case CHAR:
392+
case SHORT:
393+
return 2;
394+
case INT:
395+
return 4;
396+
case LONG:
397+
return 8;
398+
}
399+
return null;
400+
}
401+
371402
private static class UnknownDescriptorTypeException extends RuntimeException {
372403
private static final long serialVersionUID = 0;
373404

src/main/java/org/minimallycorrect/javatransformer/internal/AsmCodeFragmentGenerator.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,9 @@ private void convertTypes(MethodNodeInfoCodeFragment insertFragment, InsertionPo
345345
continue;
346346
}
347347
val input = movedInputTypes.get(index++);
348-
if (!iv.type.isAssignableFrom(input.type))
349-
throw new UnsupportedOperationException();
348+
// TODO this needs context to work properly maybe we should disable the check?
349+
// if (!Type.isAssignableFrom(iv.type, input.type))
350+
// throw new UnsupportedOperationException();
350351
switch (iv.location.type) {
351352
case STACK:
352353
val var = new VarInsnNode(AsmInstructions.getLoadInstructionForType(iv), input.location.index);
@@ -488,6 +489,12 @@ public <T extends CodeFragment> List<T> findFragments(Class<T> fragmentType) {
488489

489490
val result = new ArrayList<T>();
490491
AbstractInsnNode insn = getFirstInstruction();
492+
493+
// FIXME: null for abstract methods, shouldn't get here
494+
if (insn == null) {
495+
return result;
496+
}
497+
491498
val last = getLastInstruction();
492499
while (true) {
493500
if (constructor.getParameterTypes()[1].isAssignableFrom(insn.getClass()))
@@ -564,7 +571,8 @@ public MethodCall(ByteCodeInfo.MethodNodeInfo containingMethodNodeInfo, MethodIn
564571
@NonNull
565572
@Override
566573
public Type getContainingClassType() {
567-
return new Type('L' + instruction.owner + ';');
574+
val owner = instruction.owner;
575+
return new Type(owner.charAt(0) == '[' ? owner : 'L' + owner + ';');
568576
}
569577

570578
@NonNull

src/main/java/org/minimallycorrect/javatransformer/internal/ByteCodeInfo.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,11 @@ public void remove(FieldInfo field) {
120120

121121
@Override
122122
public Type getSuperType() {
123-
return new Type("L" + node.get().superName + ";");
123+
val superName = node.get().superName;
124+
if (superName == null) {
125+
return null;
126+
}
127+
return new Type("L" + superName + ";");
124128
}
125129

126130
@Override
@@ -152,6 +156,20 @@ MethodNodeInfo wrap(MethodNode node) {
152156
return new MethodNodeInfo(node);
153157
}
154158

159+
@Override
160+
public List<TypeVariable> getTypeVariables() {
161+
/*
162+
Test<T, D> gets signature:
163+
<T:Ljava/lang/Object;D:Ljava/lang/Object;>
164+
*/
165+
return Signature.getTypeVariables(node.get().signature);
166+
}
167+
168+
@Override
169+
public void setTypeVariables(List<TypeVariable> typeVariables) {
170+
throw new UnsupportedOperationException(); // TODO
171+
}
172+
155173
public class FieldNodeInfo implements FieldInfo {
156174
final FieldNode node;
157175
private Type type;

0 commit comments

Comments
 (0)