Skip to content

Commit

Permalink
impr: Add back annotation path handling with index support
Browse files Browse the repository at this point in the history
  • Loading branch information
Col-E committed Dec 24, 2023
1 parent af00ca2 commit 8b173e1
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 19 deletions.
2 changes: 1 addition & 1 deletion jasm-composition-jvm/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repositories {
}

dependencies {
api 'com.github.Nowilltolife:blw:2fd007afca'
api 'com.github.Nowilltolife:blw:fc0f483e2f'
implementation 'org.ow2.asm:asm:9.6'

api project(path: ':jasm-core')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package me.darknet.assembler.compile.builder;

import dev.xdark.blw.classfile.generic.GenericFieldBuilder;
import dev.xdark.blw.type.ClassType;
import me.darknet.assembler.compile.analysis.AnalysisResults;
import me.darknet.assembler.compile.analysis.MethodAnalysisLookup;

Expand Down Expand Up @@ -40,6 +42,11 @@ public AnalysisResults results(String name, String descriptor) {
return methodAnalysisResults.get(identifier);
}

@Override
protected @NotNull GenericFieldBuilder newFieldBuilder(int accessFlags, String name, ClassType type) {
return new BlwReplaceFieldBuilder(accessFlags, name, type);
}

@Override
protected @NotNull GenericMethodBuilder newMethodBuilder(int accessFlags, String name, MethodType type) {
return new BlwReplaceMethodBuilder(accessFlags, name, type);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package me.darknet.assembler.compile.builder;

import dev.xdark.blw.classfile.generic.GenericFieldBuilder;
import dev.xdark.blw.type.ClassType;

public class BlwReplaceFieldBuilder extends GenericFieldBuilder {
public BlwReplaceFieldBuilder(int accessFlags, String name, ClassType type) {
super(accessFlags, name, type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public ASTMethodVisitor visitMethod(Modifiers modifiers, ASTIdentifier name, AST
@Override
public ASTAnnotationVisitor visitAnnotation(ASTIdentifier classType) {
InstanceType type = Types.instanceTypeFromInternalName(classType.literal());
return new BlwAnnotationVisitor(builder.putVisibleRuntimeAnnotation(type).child());
return new BlwAnnotationVisitor(builder.addVisibleRuntimeAnnotation(type).child());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public BlwMemberVisitor(MemberBuilder<T, M, ?> builder) {
@Override
public ASTAnnotationVisitor visitAnnotation(ASTIdentifier classType) {
return new BlwAnnotationVisitor(
builder.putVisibleRuntimeAnnotation(Types.instanceTypeFromInternalName(classType.literal())).child()
builder.addVisibleRuntimeAnnotation(Types.instanceTypeFromInternalName(classType.literal())).child()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import me.darknet.assembler.ast.primitive.ASTIdentifier;
import me.darknet.assembler.compile.JvmCompilerOptions;
import me.darknet.assembler.compile.builder.BlwReplaceClassBuilder;
import me.darknet.assembler.compile.builder.BlwReplaceFieldBuilder;
import me.darknet.assembler.compile.builder.BlwReplaceMethodBuilder;
import me.darknet.assembler.util.AnnotationInstaller;
import me.darknet.assembler.util.AnnotationKind;
import me.darknet.assembler.util.BlwModifiers;
import me.darknet.assembler.util.CastUtil;
import me.darknet.assembler.visitor.*;
Expand All @@ -18,34 +22,34 @@ public record BlwRootVisitor(BlwReplaceClassBuilder builder, JvmCompilerOptions

@Override
public ASTAnnotationVisitor visitAnnotation(ASTIdentifier name) {
// parse annotation path
var path = options.annotationPath().split("\\.");

// TODO: blw rewrite removed usage of this index
// make some test cases to validate behavior does not change
// Parse annotation path
var path = options.annotationPath().split("\\."); // TODO: What if the path is null?
int index = Integer.parseInt(path[path.length - 1]);

InstanceType type = builder.type();

AnnotationBuilder<?> nested = switch (path.length) {
case 2 -> builder.putVisibleRuntimeAnnotation(type).child();
case 5 -> {
case 3 -> {
AnnotationKind annotationDir = AnnotationKind.from(path[2]);
yield AnnotationInstaller.install(builder, annotationDir, index, type);
}
case 6 -> {
String target = path[2];
String member = path[3];
String descriptor = path[4];
yield switch (path[2]) {
AnnotationKind annotationDir = AnnotationKind.from(path[5]);
yield switch (target) {
case "field" -> {
FieldBuilder<Field, ?> fieldBuilder = builder.getFieldBuilder(member, descriptor);
BlwReplaceFieldBuilder fieldBuilder = CastUtil.cast(builder.getFieldBuilder(member, descriptor));
if (fieldBuilder != null)
yield fieldBuilder.putVisibleRuntimeAnnotation(type).child();
yield AnnotationInstaller.install(fieldBuilder, annotationDir, index, type);
throw new IllegalStateException("Unexpected missing field data: " + member);
}
case "method" -> {
MethodBuilder<Method, ?> methodBuilder = builder.getMethodBuilder(member, descriptor);
BlwReplaceMethodBuilder methodBuilder = CastUtil.cast(builder.getMethodBuilder(member, descriptor));
if (methodBuilder != null)
yield methodBuilder.putVisibleRuntimeAnnotation(type).child();
yield AnnotationInstaller.install(methodBuilder, annotationDir, index, type);
throw new IllegalStateException("Unexpected missing method data: " + member);
}
default -> throw new IllegalStateException("Unexpected value: " + path[2]);
default -> throw new IllegalStateException("Unexpected value: " + target);
};
}
default -> throw new IllegalStateException("Unexpected value: " + path.length);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package me.darknet.assembler.util;

import dev.xdark.blw.annotation.AnnotationBuilder;
import dev.xdark.blw.classfile.AnnotatedBuilder;
import dev.xdark.blw.type.InstanceType;
import org.jetbrains.annotations.NotNull;

public class AnnotationInstaller {
public static <A extends AnnotationBuilder<A>> @NotNull A install(@NotNull AnnotatedBuilder<?, ?> annotated,
@NotNull AnnotationKind kind,
int index, @NotNull InstanceType type) {
A builder = AnnotationBuilder.newAnnotationBuilder(type);
switch (kind) {
case VIS_ANNO -> {
if (index < 0) {
annotated.addVisibleRuntimeAnnotation(builder);
} else {
annotated.setVisibleRuntimeAnnotation(index, builder);
}
}
case INVIS_ANNO -> {
if (index < 0) {
annotated.addInvisibleRuntimeAnnotation(builder);
} else {
annotated.setInvisibleRuntimeAnnotation(index, builder);
}
}
default -> throw new IllegalArgumentException("Invalid anno-kind: " + kind);
}
return builder;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package me.darknet.assembler.compiler;

import me.darknet.assembler.util.AnnotationKind;

public interface CompilerOptions<B extends CompilerOptions<?>> {

/**
Expand Down Expand Up @@ -50,10 +52,17 @@ public interface CompilerOptions<B extends CompilerOptions<?>> {
B annotationPath(String path);

/**
* @return The annotation path
* Where {@code anno_type} is a {@link AnnotationKind} name or display name:
* <ul>
* <li>Class annotations: {@code <class>.<index>.<anno_type>}</li>
* <li>Member annotations: {@code <class>.[field/method].<name>.<descriptor>.<index>.<anno_type>}</li>
* </ul>
*
* @return The annotation path.
*/
String annotationPath();


/**
* Inheritance checker used when analyzing the compiled result to fill in the
* local type information
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package me.darknet.assembler.util;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Annotation storage kind, where storage is just for the internal class model,
* IE visibility and if it's a type-anno or not.
*/
public enum AnnotationKind {
VIS_ANNO("vis-a"),
INVIS_ANNO("invis-a"),
// TODO: Type annotation support in BLW
// VIS_TYPE_ANNO("vis-t"),
// INVIS_TYPE_ANNO("invis-t")
;

private final String display;

AnnotationKind(String display) {
this.display = display;
}

/**
* @param name
* Name of annotation kind.
*
* @return Kind matching the display or enum name.
* Falls back to {@link #VIS_ANNO} if unrecognized.
*/
public static @NotNull AnnotationKind from(@Nullable String name) {
for (AnnotationKind value : values())
if (value.display.equalsIgnoreCase(name) || value.name().equalsIgnoreCase(name))
return value;
return VIS_ANNO;
}
}

0 comments on commit 8b173e1

Please sign in to comment.