mirror of https://github.com/FabricMC/yarn.git
Format mapping poet code
This commit is contained in:
parent
02bc5e4a81
commit
48cf4b54d0
|
@ -39,6 +39,7 @@ dependencies {
|
||||||
implementation "net.fabricmc:mappingpoet:$properties.mappingpoet_version"
|
implementation "net.fabricmc:mappingpoet:$properties.mappingpoet_version"
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4.2'
|
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4.2'
|
||||||
implementation 'net.fabricmc:mapping-io:0.5.1'
|
implementation 'net.fabricmc:mapping-io:0.5.1'
|
||||||
|
implementation 'net.fabricmc:javapoet:0.1.1'
|
||||||
|
|
||||||
// Contains a number of useful utilities we can re-use.
|
// Contains a number of useful utilities we can re-use.
|
||||||
implementation ("net.fabricmc:fabric-loom:1.5.7") {
|
implementation ("net.fabricmc:fabric-loom:1.5.7") {
|
||||||
|
|
|
@ -13,9 +13,10 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet;
|
|
||||||
|
|
||||||
import static net.fabricmc.mappingpoet.FieldBuilder.parseAnnotation;
|
package net.fabricmc.filament.mappingpoet;
|
||||||
|
|
||||||
|
import static net.fabricmc.filament.mappingpoet.FieldBuilder.parseAnnotation;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -37,11 +38,11 @@ import org.objectweb.asm.tree.InnerClassNode;
|
||||||
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
|
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
|
||||||
import org.objectweb.asm.tree.MethodNode;
|
import org.objectweb.asm.tree.MethodNode;
|
||||||
|
|
||||||
import net.fabricmc.mappingpoet.signature.AnnotationAwareDescriptors;
|
import net.fabricmc.filament.mappingpoet.signature.AnnotationAwareDescriptors;
|
||||||
import net.fabricmc.mappingpoet.signature.AnnotationAwareSignatures;
|
import net.fabricmc.filament.mappingpoet.signature.AnnotationAwareSignatures;
|
||||||
import net.fabricmc.mappingpoet.signature.ClassSignature;
|
import net.fabricmc.filament.mappingpoet.signature.ClassSignature;
|
||||||
import net.fabricmc.mappingpoet.signature.TypeAnnotationMapping;
|
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationMapping;
|
||||||
import net.fabricmc.mappingpoet.signature.TypeAnnotationStorage;
|
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationStorage;
|
||||||
|
|
||||||
public class ClassBuilder {
|
public class ClassBuilder {
|
||||||
static final Handle OBJ_MTH_BOOTSTRAP = new Handle(
|
static final Handle OBJ_MTH_BOOTSTRAP = new Handle(
|
||||||
|
@ -88,6 +89,7 @@ public class ClassBuilder {
|
||||||
ClassName currentClassName = null;
|
ClassName currentClassName = null;
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ch = index == internalName.length() ? ';' : internalName.charAt(index);
|
ch = index == internalName.length() ? ';' : internalName.charAt(index);
|
||||||
|
|
||||||
|
@ -165,9 +167,11 @@ public class ClassBuilder {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(classNode.name);
|
sb.append(classNode.name);
|
||||||
sb.append("<");
|
sb.append("<");
|
||||||
|
|
||||||
for (TypeVariableName each : signature.generics()) {
|
for (TypeVariableName each : signature.generics()) {
|
||||||
sb.append("T").append(each.name).append(";");
|
sb.append("T").append(each.name).append(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append(">");
|
sb.append(">");
|
||||||
receiverSignature = sb.toString();
|
receiverSignature = sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -248,8 +252,9 @@ public class ClassBuilder {
|
||||||
for (AbstractInsnNode insn : method.instructions) {
|
for (AbstractInsnNode insn : method.instructions) {
|
||||||
if (insn instanceof InvokeDynamicInsnNode indy
|
if (insn instanceof InvokeDynamicInsnNode indy
|
||||||
&& indy.bsm.equals(OBJ_MTH_BOOTSTRAP)
|
&& indy.bsm.equals(OBJ_MTH_BOOTSTRAP)
|
||||||
&& indy.name.equals(method.name))
|
&& indy.name.equals(method.name)) {
|
||||||
continue methodsLoop;
|
continue methodsLoop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,6 +368,7 @@ public class ClassBuilder {
|
||||||
if (!Modifier.isStatic(innerClassNode.access)) {
|
if (!Modifier.isStatic(innerClassNode.access)) {
|
||||||
classBuilder.instanceInner = true;
|
classBuilder.instanceInner = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// consider emit warning if this.instanceInner is true when classBuilder.instanceInner is false
|
// consider emit warning if this.instanceInner is true when classBuilder.instanceInner is false
|
||||||
|
|
||||||
if (this.receiverSignature != null && classBuilder.instanceInner) {
|
if (this.receiverSignature != null && classBuilder.instanceInner) {
|
||||||
|
@ -374,9 +380,11 @@ public class ClassBuilder {
|
||||||
|
|
||||||
if (!innerClassGenerics.isEmpty()) {
|
if (!innerClassGenerics.isEmpty()) {
|
||||||
sb.append("<");
|
sb.append("<");
|
||||||
|
|
||||||
for (TypeVariableName each : innerClassGenerics) {
|
for (TypeVariableName each : innerClassGenerics) {
|
||||||
sb.append("T").append(each.name).append(";");
|
sb.append("T").append(each.name).append(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append(">");
|
sb.append(">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,17 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet;
|
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
package net.fabricmc.filament.mappingpoet;
|
||||||
import net.fabricmc.mappingpoet.signature.ClassStaticContext;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
|
||||||
|
import net.fabricmc.filament.mappingpoet.signature.ClassStaticContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an overall runtime environment, knows all inner class,
|
* Represents an overall runtime environment, knows all inner class,
|
||||||
* super class, etc. information.
|
* super class, etc. information.
|
||||||
|
@ -39,8 +41,9 @@ public record Environment(
|
||||||
|
|
||||||
public record ClassNamePointer(String simple, String outerClass) {
|
public record ClassNamePointer(String simple, String outerClass) {
|
||||||
public ClassName toClassName(ClassName outerClassName) {
|
public ClassName toClassName(ClassName outerClassName) {
|
||||||
if (simple == null)
|
if (simple == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return outerClassName.nestedClass(simple);
|
return outerClassName.nestedClass(simple);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,15 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet;
|
||||||
|
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.squareup.javapoet.AnnotationSpec;
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
import com.squareup.javapoet.ArrayTypeName;
|
import com.squareup.javapoet.ArrayTypeName;
|
||||||
|
@ -23,12 +31,6 @@ import com.squareup.javapoet.FieldSpec;
|
||||||
import com.squareup.javapoet.ParameterSpec;
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import net.fabricmc.mappingpoet.signature.AnnotationAwareDescriptors;
|
|
||||||
import net.fabricmc.mappingpoet.signature.AnnotationAwareSignatures;
|
|
||||||
import net.fabricmc.mappingpoet.signature.ClassStaticContext;
|
|
||||||
import net.fabricmc.mappingpoet.signature.TypeAnnotationBank;
|
|
||||||
import net.fabricmc.mappingpoet.signature.TypeAnnotationMapping;
|
|
||||||
import net.fabricmc.mappingpoet.signature.TypeAnnotationStorage;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.TypePath;
|
import org.objectweb.asm.TypePath;
|
||||||
|
@ -37,12 +39,12 @@ import org.objectweb.asm.tree.AnnotationNode;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import org.objectweb.asm.tree.FieldNode;
|
import org.objectweb.asm.tree.FieldNode;
|
||||||
|
|
||||||
import java.util.AbstractMap;
|
import net.fabricmc.filament.mappingpoet.signature.AnnotationAwareDescriptors;
|
||||||
import java.util.ArrayDeque;
|
import net.fabricmc.filament.mappingpoet.signature.AnnotationAwareSignatures;
|
||||||
import java.util.Deque;
|
import net.fabricmc.filament.mappingpoet.signature.ClassStaticContext;
|
||||||
import java.util.Iterator;
|
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationBank;
|
||||||
import java.util.List;
|
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationMapping;
|
||||||
import java.util.Map;
|
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationStorage;
|
||||||
|
|
||||||
public class FieldBuilder {
|
public class FieldBuilder {
|
||||||
private final MappingsStore mappings;
|
private final MappingsStore mappings;
|
||||||
|
@ -74,8 +76,10 @@ public class FieldBuilder {
|
||||||
ClassName annoClassName = (ClassName) typeFromDesc(annotation.desc);
|
ClassName annoClassName = (ClassName) typeFromDesc(annotation.desc);
|
||||||
AnnotationSpec.Builder builder = AnnotationSpec.builder(annoClassName);
|
AnnotationSpec.Builder builder = AnnotationSpec.builder(annoClassName);
|
||||||
List<Object> values = annotation.values;
|
List<Object> values = annotation.values;
|
||||||
|
|
||||||
if (values != null) {
|
if (values != null) {
|
||||||
Iterator<?> itr = values.iterator();
|
Iterator<?> itr = values.iterator();
|
||||||
|
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
String key = (String) itr.next();
|
String key = (String) itr.next();
|
||||||
Object value = itr.next();
|
Object value = itr.next();
|
||||||
|
@ -92,24 +96,30 @@ public class FieldBuilder {
|
||||||
if (value instanceof List) {
|
if (value instanceof List) {
|
||||||
return ((List<?>) value).stream().map(FieldBuilder::codeFromAnnoValue).collect(CodeBlock.joining(",", "{", "}"));
|
return ((List<?>) value).stream().map(FieldBuilder::codeFromAnnoValue).collect(CodeBlock.joining(",", "{", "}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof Character || value instanceof Number || value instanceof Boolean) {
|
if (value instanceof Character || value instanceof Number || value instanceof Boolean) {
|
||||||
return CodeBlock.builder().add("$L", value).build();
|
return CodeBlock.builder().add("$L", value).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof String) {
|
if (value instanceof String) {
|
||||||
return CodeBlock.builder().add("$S", value).build();
|
return CodeBlock.builder().add("$S", value).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof String[]) {
|
if (value instanceof String[]) {
|
||||||
String[] arr = (String[]) value;
|
String[] arr = (String[]) value;
|
||||||
ClassName enumClassName = (ClassName) typeFromDesc(arr[0]);
|
ClassName enumClassName = (ClassName) typeFromDesc(arr[0]);
|
||||||
String valueName = arr[1];
|
String valueName = arr[1];
|
||||||
return CodeBlock.builder().add("$T.$L", enumClassName, valueName).build();
|
return CodeBlock.builder().add("$T.$L", enumClassName, valueName).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof Type) {
|
if (value instanceof Type) {
|
||||||
return CodeBlock.builder().add("$T.class", typeFromDesc(((Type) value).getDescriptor())).build();
|
return CodeBlock.builder().add("$T.class", typeFromDesc(((Type) value).getDescriptor())).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof AnnotationNode) {
|
if (value instanceof AnnotationNode) {
|
||||||
return CodeBlock.builder().add(parseAnnotation((AnnotationNode) value).toString()).build();
|
return CodeBlock.builder().add(parseAnnotation((AnnotationNode) value).toString()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException(String.format("Don't know how to convert \"%s\" into annotation value", value));
|
throw new IllegalArgumentException(String.format("Don't know how to convert \"%s\" into annotation value", value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +130,7 @@ public class FieldBuilder {
|
||||||
public static Map.Entry<Integer, TypeName> parseType(final String desc, final int start) {
|
public static Map.Entry<Integer, TypeName> parseType(final String desc, final int start) {
|
||||||
int index = start;
|
int index = start;
|
||||||
int arrayLevel = 0;
|
int arrayLevel = 0;
|
||||||
|
|
||||||
while (desc.charAt(index) == '[') {
|
while (desc.charAt(index) == '[') {
|
||||||
arrayLevel++;
|
arrayLevel++;
|
||||||
index++;
|
index++;
|
||||||
|
@ -127,90 +138,91 @@ public class FieldBuilder {
|
||||||
|
|
||||||
TypeName current;
|
TypeName current;
|
||||||
switch (desc.charAt(index)) {
|
switch (desc.charAt(index)) {
|
||||||
case 'B': {
|
case 'B': {
|
||||||
current = TypeName.BYTE;
|
current = TypeName.BYTE;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'C': {
|
case 'C': {
|
||||||
current = TypeName.CHAR;
|
current = TypeName.CHAR;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'D': {
|
case 'D': {
|
||||||
current = TypeName.DOUBLE;
|
current = TypeName.DOUBLE;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'F': {
|
case 'F': {
|
||||||
current = TypeName.FLOAT;
|
current = TypeName.FLOAT;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'I': {
|
case 'I': {
|
||||||
current = TypeName.INT;
|
current = TypeName.INT;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'J': {
|
case 'J': {
|
||||||
current = TypeName.LONG;
|
current = TypeName.LONG;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'S': {
|
case 'S': {
|
||||||
current = TypeName.SHORT;
|
current = TypeName.SHORT;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'Z': {
|
case 'Z': {
|
||||||
current = TypeName.BOOLEAN;
|
current = TypeName.BOOLEAN;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'V': {
|
case 'V': {
|
||||||
current = TypeName.VOID;
|
current = TypeName.VOID;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'L': {
|
case 'L': {
|
||||||
int classNameSeparator = index;
|
int classNameSeparator = index;
|
||||||
index++;
|
index++;
|
||||||
int nameStart = index;
|
int nameStart = index;
|
||||||
ClassName currentClassName = null;
|
ClassName currentClassName = null;
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
do {
|
|
||||||
ch = desc.charAt(index);
|
|
||||||
|
|
||||||
if (ch == '$' || ch == ';') {
|
do {
|
||||||
// collect class name
|
ch = desc.charAt(index);
|
||||||
if (currentClassName == null) {
|
|
||||||
String packageName = nameStart < classNameSeparator ? desc.substring(nameStart, classNameSeparator).replace('/', '.') : "";
|
if (ch == '$' || ch == ';') {
|
||||||
String simpleName = desc.substring(classNameSeparator + 1, index);
|
// collect class name
|
||||||
currentClassName = ClassName.get(packageName, simpleName);
|
if (currentClassName == null) {
|
||||||
} else {
|
String packageName = nameStart < classNameSeparator ? desc.substring(nameStart, classNameSeparator).replace('/', '.') : "";
|
||||||
String simpleName = desc.substring(classNameSeparator + 1, index);
|
String simpleName = desc.substring(classNameSeparator + 1, index);
|
||||||
currentClassName = currentClassName.nestedClass(simpleName);
|
currentClassName = ClassName.get(packageName, simpleName);
|
||||||
}
|
} else {
|
||||||
|
String simpleName = desc.substring(classNameSeparator + 1, index);
|
||||||
|
currentClassName = currentClassName.nestedClass(simpleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch == '/' || ch == '$') {
|
|
||||||
// Start of simple name
|
|
||||||
classNameSeparator = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
} while (ch != ';');
|
|
||||||
|
|
||||||
if (currentClassName == null) {
|
|
||||||
throw invalidDesc(desc, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current = currentClassName;
|
if (ch == '/' || ch == '$') {
|
||||||
break;
|
// Start of simple name
|
||||||
}
|
classNameSeparator = index;
|
||||||
default:
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
} while (ch != ';');
|
||||||
|
|
||||||
|
if (currentClassName == null) {
|
||||||
throw invalidDesc(desc, index);
|
throw invalidDesc(desc, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = currentClassName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw invalidDesc(desc, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < arrayLevel; i++) {
|
for (int i = 0; i < arrayLevel; i++) {
|
||||||
|
@ -223,6 +235,7 @@ public class FieldBuilder {
|
||||||
public static Map.Entry<Integer, TypeName> parseAnnotatedType(final String desc, final int start, TypeAnnotationBank annotations, ClassStaticContext context) {
|
public static Map.Entry<Integer, TypeName> parseAnnotatedType(final String desc, final int start, TypeAnnotationBank annotations, ClassStaticContext context) {
|
||||||
int index = start;
|
int index = start;
|
||||||
Deque<List<AnnotationSpec>> arrayAnnos = new ArrayDeque<>();
|
Deque<List<AnnotationSpec>> arrayAnnos = new ArrayDeque<>();
|
||||||
|
|
||||||
while (desc.charAt(index) == '[') {
|
while (desc.charAt(index) == '[') {
|
||||||
arrayAnnos.push(annotations.getCurrentAnnotations());
|
arrayAnnos.push(annotations.getCurrentAnnotations());
|
||||||
annotations = annotations.advance(TypePath.ARRAY_ELEMENT, 0);
|
annotations = annotations.advance(TypePath.ARRAY_ELEMENT, 0);
|
||||||
|
@ -231,106 +244,108 @@ public class FieldBuilder {
|
||||||
|
|
||||||
TypeName current;
|
TypeName current;
|
||||||
switch (desc.charAt(index)) {
|
switch (desc.charAt(index)) {
|
||||||
case 'B': {
|
case 'B': {
|
||||||
current = TypeName.BYTE;
|
current = TypeName.BYTE;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'C': {
|
case 'C': {
|
||||||
current = TypeName.CHAR;
|
current = TypeName.CHAR;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'D': {
|
case 'D': {
|
||||||
current = TypeName.DOUBLE;
|
current = TypeName.DOUBLE;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'F': {
|
case 'F': {
|
||||||
current = TypeName.FLOAT;
|
current = TypeName.FLOAT;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'I': {
|
case 'I': {
|
||||||
current = TypeName.INT;
|
current = TypeName.INT;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'J': {
|
case 'J': {
|
||||||
current = TypeName.LONG;
|
current = TypeName.LONG;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'S': {
|
case 'S': {
|
||||||
current = TypeName.SHORT;
|
current = TypeName.SHORT;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'Z': {
|
case 'Z': {
|
||||||
current = TypeName.BOOLEAN;
|
current = TypeName.BOOLEAN;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'V': {
|
case 'V': {
|
||||||
current = TypeName.VOID;
|
current = TypeName.VOID;
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'L': {
|
case 'L': {
|
||||||
int classNameSeparator = index;
|
int classNameSeparator = index;
|
||||||
index++;
|
index++;
|
||||||
int nameStart = index;
|
int nameStart = index;
|
||||||
ClassName currentClassName = null;
|
ClassName currentClassName = null;
|
||||||
boolean instanceInner = false;
|
boolean instanceInner = false;
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
do {
|
|
||||||
ch = desc.charAt(index);
|
|
||||||
|
|
||||||
if (ch == '$' || ch == ';') {
|
do {
|
||||||
// collect class name
|
ch = desc.charAt(index);
|
||||||
if (currentClassName == null) {
|
|
||||||
String packageName = nameStart < classNameSeparator ? desc.substring(nameStart, classNameSeparator).replace('/', '.') : "";
|
|
||||||
String simpleName = desc.substring(classNameSeparator + 1, index);
|
|
||||||
currentClassName = ClassName.get(packageName, simpleName);
|
|
||||||
} else {
|
|
||||||
String simpleName = desc.substring(classNameSeparator + 1, index);
|
|
||||||
|
|
||||||
if (!instanceInner && context.isInstanceInner(desc.substring(nameStart, index))) {
|
if (ch == '$' || ch == ';') {
|
||||||
instanceInner = true;
|
// collect class name
|
||||||
}
|
if (currentClassName == null) {
|
||||||
|
String packageName = nameStart < classNameSeparator ? desc.substring(nameStart, classNameSeparator).replace('/', '.') : "";
|
||||||
|
String simpleName = desc.substring(classNameSeparator + 1, index);
|
||||||
|
currentClassName = ClassName.get(packageName, simpleName);
|
||||||
|
} else {
|
||||||
|
String simpleName = desc.substring(classNameSeparator + 1, index);
|
||||||
|
|
||||||
currentClassName = currentClassName.nestedClass(simpleName);
|
if (!instanceInner && context.isInstanceInner(desc.substring(nameStart, index))) {
|
||||||
|
instanceInner = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (instanceInner) {
|
currentClassName = currentClassName.nestedClass(simpleName);
|
||||||
currentClassName = AnnotationAwareDescriptors.annotate(currentClassName, annotations);
|
|
||||||
annotations = annotations.advance(TypePath.INNER_TYPE, 0);
|
if (instanceInner) {
|
||||||
}
|
currentClassName = AnnotationAwareDescriptors.annotate(currentClassName, annotations);
|
||||||
|
annotations = annotations.advance(TypePath.INNER_TYPE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch == '/' || ch == '$') {
|
|
||||||
// Start of simple name
|
|
||||||
classNameSeparator = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
} while (ch != ';');
|
|
||||||
|
|
||||||
if (currentClassName == null) {
|
|
||||||
throw invalidDesc(desc, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current = currentClassName;
|
if (ch == '/' || ch == '$') {
|
||||||
break;
|
// Start of simple name
|
||||||
}
|
classNameSeparator = index;
|
||||||
default:
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
} while (ch != ';');
|
||||||
|
|
||||||
|
if (currentClassName == null) {
|
||||||
throw invalidDesc(desc, index);
|
throw invalidDesc(desc, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = currentClassName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw invalidDesc(desc, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!arrayAnnos.isEmpty()) {
|
while (!arrayAnnos.isEmpty()) {
|
||||||
current = ArrayTypeName.of(current);
|
current = ArrayTypeName.of(current);
|
||||||
List<AnnotationSpec> currentAnnos = arrayAnnos.pop();
|
List<AnnotationSpec> currentAnnos = arrayAnnos.pop();
|
||||||
|
|
||||||
if (!currentAnnos.isEmpty()) {
|
if (!currentAnnos.isEmpty()) {
|
||||||
current = current.annotated(currentAnnos);
|
current = current.annotated(currentAnnos);
|
||||||
}
|
}
|
||||||
|
@ -346,31 +361,34 @@ public class FieldBuilder {
|
||||||
@Deprecated // use typeFromDesc, non-recursive
|
@Deprecated // use typeFromDesc, non-recursive
|
||||||
public static TypeName getFieldType(String desc) {
|
public static TypeName getFieldType(String desc) {
|
||||||
switch (desc) {
|
switch (desc) {
|
||||||
case "B":
|
case "B":
|
||||||
return TypeName.BYTE;
|
return TypeName.BYTE;
|
||||||
case "C":
|
case "C":
|
||||||
return TypeName.CHAR;
|
return TypeName.CHAR;
|
||||||
case "S":
|
case "S":
|
||||||
return TypeName.SHORT;
|
return TypeName.SHORT;
|
||||||
case "Z":
|
case "Z":
|
||||||
return TypeName.BOOLEAN;
|
return TypeName.BOOLEAN;
|
||||||
case "I":
|
case "I":
|
||||||
return TypeName.INT;
|
return TypeName.INT;
|
||||||
case "J":
|
case "J":
|
||||||
return TypeName.LONG;
|
return TypeName.LONG;
|
||||||
case "F":
|
case "F":
|
||||||
return TypeName.FLOAT;
|
return TypeName.FLOAT;
|
||||||
case "D":
|
case "D":
|
||||||
return TypeName.DOUBLE;
|
return TypeName.DOUBLE;
|
||||||
case "V":
|
case "V":
|
||||||
return TypeName.VOID;
|
return TypeName.VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.startsWith("[")) {
|
if (desc.startsWith("[")) {
|
||||||
return ArrayTypeName.of(getFieldType(desc.substring(1)));
|
return ArrayTypeName.of(getFieldType(desc.substring(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.startsWith("L")) {
|
if (desc.startsWith("L")) {
|
||||||
return ClassBuilder.parseInternalName(desc.substring(1).substring(0, desc.length() - 2));
|
return ClassBuilder.parseInternalName(desc.substring(1).substring(0, desc.length() - 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnsupportedOperationException("Unknown field type" + desc);
|
throw new UnsupportedOperationException("Unknown field type" + desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,56 +406,65 @@ public class FieldBuilder {
|
||||||
private CodeBlock makeInitializer(String desc) {
|
private CodeBlock makeInitializer(String desc) {
|
||||||
// fake initializers exclude fields from constant values
|
// fake initializers exclude fields from constant values
|
||||||
switch (desc.charAt(0)) {
|
switch (desc.charAt(0)) {
|
||||||
case 'B':
|
case 'B':
|
||||||
if (fieldNode.value instanceof Integer) {
|
if (fieldNode.value instanceof Integer) {
|
||||||
return CodeBlock.builder().add("(byte) $L", fieldNode.value).build();
|
return CodeBlock.builder().add("(byte) $L", fieldNode.value).build();
|
||||||
}
|
}
|
||||||
// fake initializer falls through
|
|
||||||
case 'C':
|
// fake initializer falls through
|
||||||
if (fieldNode.value instanceof Integer) {
|
case 'C':
|
||||||
int value = (int) fieldNode.value;
|
if (fieldNode.value instanceof Integer) {
|
||||||
char c = (char) value;
|
int value = (int) fieldNode.value;
|
||||||
return printChar(CodeBlock.builder(), c, value).build();
|
char c = (char) value;
|
||||||
}
|
return printChar(CodeBlock.builder(), c, value).build();
|
||||||
// fake initializer falls through
|
}
|
||||||
case 'D':
|
|
||||||
if (fieldNode.value instanceof Double) {
|
// fake initializer falls through
|
||||||
return CodeBlock.builder().add("$LD", fieldNode.value).build();
|
case 'D':
|
||||||
}
|
if (fieldNode.value instanceof Double) {
|
||||||
// fake initializer falls through
|
return CodeBlock.builder().add("$LD", fieldNode.value).build();
|
||||||
case 'I':
|
}
|
||||||
if (fieldNode.value instanceof Integer) {
|
|
||||||
return CodeBlock.builder().add("$L", fieldNode.value).build();
|
// fake initializer falls through
|
||||||
}
|
case 'I':
|
||||||
// fake initializer falls through
|
if (fieldNode.value instanceof Integer) {
|
||||||
case 'J':
|
return CodeBlock.builder().add("$L", fieldNode.value).build();
|
||||||
if (fieldNode.value instanceof Long) {
|
}
|
||||||
return CodeBlock.builder().add("$LL", fieldNode.value).build();
|
|
||||||
}
|
// fake initializer falls through
|
||||||
// fake initializer falls through
|
case 'J':
|
||||||
case 'S':
|
if (fieldNode.value instanceof Long) {
|
||||||
if (fieldNode.value instanceof Integer) {
|
return CodeBlock.builder().add("$LL", fieldNode.value).build();
|
||||||
return CodeBlock.builder().add("(short) $L", fieldNode.value).build();
|
}
|
||||||
}
|
|
||||||
return CodeBlock.builder().add("java.lang.Byte.parseByte(\"dummy\")").build();
|
// fake initializer falls through
|
||||||
case 'F':
|
case 'S':
|
||||||
if (fieldNode.value instanceof Float) {
|
if (fieldNode.value instanceof Integer) {
|
||||||
return CodeBlock.builder().add("$LF", fieldNode.value).build();
|
return CodeBlock.builder().add("(short) $L", fieldNode.value).build();
|
||||||
}
|
}
|
||||||
return CodeBlock.builder().add("java.lang.Float.parseFloat(\"dummy\")").build();
|
|
||||||
case 'Z':
|
return CodeBlock.builder().add("java.lang.Byte.parseByte(\"dummy\")").build();
|
||||||
if (fieldNode.value instanceof Integer) {
|
case 'F':
|
||||||
return CodeBlock.builder().add("$L", ((int) fieldNode.value) != 0).build();
|
if (fieldNode.value instanceof Float) {
|
||||||
}
|
return CodeBlock.builder().add("$LF", fieldNode.value).build();
|
||||||
return CodeBlock.builder().add("java.lang.Boolean.parseBoolean(\"dummy\")").build();
|
}
|
||||||
|
|
||||||
|
return CodeBlock.builder().add("java.lang.Float.parseFloat(\"dummy\")").build();
|
||||||
|
case 'Z':
|
||||||
|
if (fieldNode.value instanceof Integer) {
|
||||||
|
return CodeBlock.builder().add("$L", ((int) fieldNode.value) != 0).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return CodeBlock.builder().add("java.lang.Boolean.parseBoolean(\"dummy\")").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.equals("Ljava/lang/String;") && fieldNode.value instanceof String) {
|
if (desc.equals("Ljava/lang/String;") && fieldNode.value instanceof String) {
|
||||||
return CodeBlock.builder().add("$S", fieldNode.value).build();
|
return CodeBlock.builder().add("$S", fieldNode.value).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
return CodeBlock.builder().add(desc.equals("Ljava/lang/String;") ? "java.lang.String.valueOf(\"dummy\")" : "null").build();
|
return CodeBlock.builder().add(desc.equals("Ljava/lang/String;") ? "java.lang.String.valueOf(\"dummy\")" : "null").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static CodeBlock.Builder printChar(CodeBlock.Builder builder, char c, int value) {
|
private static CodeBlock.Builder printChar(CodeBlock.Builder builder, char c, int value) {
|
||||||
if (!Character.isValidCodePoint(value) || !Character.isDefined(value)) {
|
if (!Character.isValidCodePoint(value) || !Character.isDefined(value)) {
|
||||||
return builder.add("(char) $L", value);
|
return builder.add("(char) $L", value);
|
||||||
|
@ -446,20 +473,20 @@ public class FieldBuilder {
|
||||||
// See https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-EscapeSequence
|
// See https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-EscapeSequence
|
||||||
// ignore space or ", just use direct in those cases
|
// ignore space or ", just use direct in those cases
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\b':
|
case '\b':
|
||||||
return builder.add("'\\b'");
|
return builder.add("'\\b'");
|
||||||
case '\t':
|
case '\t':
|
||||||
return builder.add("'\\t'");
|
return builder.add("'\\t'");
|
||||||
case '\n':
|
case '\n':
|
||||||
return builder.add("'\\n'");
|
return builder.add("'\\n'");
|
||||||
case '\f':
|
case '\f':
|
||||||
return builder.add("'\\f'");
|
return builder.add("'\\f'");
|
||||||
case '\r':
|
case '\r':
|
||||||
return builder.add("'\\r'");
|
return builder.add("'\\r'");
|
||||||
case '\'':
|
case '\'':
|
||||||
return builder.add("'\\''");
|
return builder.add("'\\''");
|
||||||
case '\\':
|
case '\\':
|
||||||
return builder.add("'\\\\'");
|
return builder.add("'\\\\'");
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.add("'$L'", c);
|
return builder.add("'$L'", c);
|
||||||
|
@ -482,6 +509,7 @@ public class FieldBuilder {
|
||||||
if (regularAnnotations == null) {
|
if (regularAnnotations == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AnnotationNode annotation : regularAnnotations) {
|
for (AnnotationNode annotation : regularAnnotations) {
|
||||||
builder.addAnnotation(parseAnnotation(annotation));
|
builder.addAnnotation(parseAnnotation(annotation));
|
||||||
}
|
}
|
||||||
|
@ -496,6 +524,7 @@ public class FieldBuilder {
|
||||||
if (regularAnnotations == null) {
|
if (regularAnnotations == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AnnotationNode annotation : regularAnnotations) {
|
for (AnnotationNode annotation : regularAnnotations) {
|
||||||
paramBuilder.addAnnotation(parseAnnotation(annotation));
|
paramBuilder.addAnnotation(parseAnnotation(annotation));
|
||||||
}
|
}
|
||||||
|
@ -505,6 +534,7 @@ public class FieldBuilder {
|
||||||
if (fieldNode.signature != null) {
|
if (fieldNode.signature != null) {
|
||||||
return AnnotationAwareSignatures.parseFieldSignature(fieldNode.signature, annotations, context);
|
return AnnotationAwareSignatures.parseFieldSignature(fieldNode.signature, annotations, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseAnnotatedType(fieldNode.desc, 0, annotations.getBank(TypeReference.newTypeReference(TypeReference.FIELD)), context).getValue();
|
return parseAnnotatedType(fieldNode.desc, 0, annotations.getBank(TypeReference.newTypeReference(TypeReference.FIELD)), context).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -46,16 +47,16 @@ import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import org.objectweb.asm.tree.InnerClassNode;
|
import org.objectweb.asm.tree.InnerClassNode;
|
||||||
|
|
||||||
import net.fabricmc.mappingpoet.Environment.ClassNamePointer;
|
import net.fabricmc.filament.mappingpoet.Environment.ClassNamePointer;
|
||||||
import net.fabricmc.mappingpoet.Environment.NestedClassInfo;
|
import net.fabricmc.filament.mappingpoet.Environment.NestedClassInfo;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
if (args.length != 3 && args.length != 4) {
|
if (args.length != 3 && args.length != 4) {
|
||||||
System.out.println("<mappings> <inputJar> <outputDir> [<librariesDir>]");
|
System.out.println("<mappings> <inputJar> <outputDir> [<librariesDir>]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Path mappings = Paths.get(args[0]);
|
Path mappings = Paths.get(args[0]);
|
||||||
Path inputJar = Paths.get(args[1]);
|
Path inputJar = Paths.get(args[1]);
|
||||||
Path outputDirectory = Paths.get(args[2]);
|
Path outputDirectory = Paths.get(args[2]);
|
||||||
|
@ -65,8 +66,8 @@ public class Main {
|
||||||
if (Files.exists(outputDirectory)) {
|
if (Files.exists(outputDirectory)) {
|
||||||
try (var stream = Files.walk(outputDirectory)) {
|
try (var stream = Files.walk(outputDirectory)) {
|
||||||
stream.sorted(Comparator.reverseOrder())
|
stream.sorted(Comparator.reverseOrder())
|
||||||
.map(Path::toFile)
|
.map(Path::toFile)
|
||||||
.forEach(File::delete);
|
.forEach(File::delete);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +122,7 @@ public class Main {
|
||||||
scanNestedClasses(classNames, nestedClasses, librariesDir);
|
scanNestedClasses(classNames, nestedClasses, librariesDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
try (final JarFile jarFile = new JarFile(jar.toFile())) {
|
try (JarFile jarFile = new JarFile(jar.toFile())) {
|
||||||
Enumeration<JarEntry> entryEnumerator = jarFile.entries();
|
Enumeration<JarEntry> entryEnumerator = jarFile.entries();
|
||||||
|
|
||||||
while (entryEnumerator.hasMoreElements()) {
|
while (entryEnumerator.hasMoreElements()) {
|
||||||
|
@ -136,12 +137,15 @@ public class Main {
|
||||||
ClassNode classNode = new ClassNode();
|
ClassNode classNode = new ClassNode();
|
||||||
reader.accept(classNode, ClassReader.SKIP_CODE);
|
reader.accept(classNode, ClassReader.SKIP_CODE);
|
||||||
List<String> superNames = new ArrayList<>();
|
List<String> superNames = new ArrayList<>();
|
||||||
|
|
||||||
if (classNode.superName != null && !classNode.superName.equals("java/lang/Object")) {
|
if (classNode.superName != null && !classNode.superName.equals("java/lang/Object")) {
|
||||||
superNames.add(classNode.superName);
|
superNames.add(classNode.superName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classNode.interfaces != null) {
|
if (classNode.interfaces != null) {
|
||||||
superNames.addAll(classNode.interfaces);
|
superNames.addAll(classNode.interfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!superNames.isEmpty()) {
|
if (!superNames.isEmpty()) {
|
||||||
supers.put(classNode.name, superNames);
|
supers.put(classNode.name, superNames);
|
||||||
}
|
}
|
||||||
|
@ -183,7 +187,7 @@ public class Main {
|
||||||
return FileVisitResult.CONTINUE;
|
return FileVisitResult.CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (final JarFile jarFile = new JarFile(file.toFile())) {
|
try (JarFile jarFile = new JarFile(file.toFile())) {
|
||||||
Enumeration<JarEntry> entryEnumerator = jarFile.entries();
|
Enumeration<JarEntry> entryEnumerator = jarFile.entries();
|
||||||
|
|
||||||
while (entryEnumerator.hasMoreElements()) {
|
while (entryEnumerator.hasMoreElements()) {
|
||||||
|
@ -198,7 +202,8 @@ public class Main {
|
||||||
reader.accept(new ClassVisitor(Opcodes.ASM9) {
|
reader.accept(new ClassVisitor(Opcodes.ASM9) {
|
||||||
@Override
|
@Override
|
||||||
public void visitInnerClass(String name, String outerName, String simpleName, int access) {
|
public void visitInnerClass(String name, String outerName, String simpleName, int access) {
|
||||||
instanceInnerClasses.put(name, new Environment.NestedClassInfo(outerName, !Modifier.isStatic(access), simpleName));
|
instanceInnerClasses.put(name, new NestedClassInfo(outerName, !Modifier.isStatic(access), simpleName));
|
||||||
|
|
||||||
if (outerName != null) {
|
if (outerName != null) {
|
||||||
classNames.put(name, new ClassNamePointer(simpleName, outerName));
|
classNames.put(name, new ClassNamePointer(simpleName, outerName));
|
||||||
}
|
}
|
||||||
|
@ -234,11 +239,14 @@ public class Main {
|
||||||
private static void writeClass(MappingsStore mappings, ClassNode classNode, Map<String, ClassBuilder> existingClasses, Environment environment) {
|
private static void writeClass(MappingsStore mappings, ClassNode classNode, Map<String, ClassBuilder> existingClasses, Environment environment) {
|
||||||
// TODO make sure named jar has valid InnerClasses, use that info instead
|
// TODO make sure named jar has valid InnerClasses, use that info instead
|
||||||
String name = classNode.name;
|
String name = classNode.name;
|
||||||
|
|
||||||
{
|
{
|
||||||
//Block anonymous class and their nested classes
|
//Block anonymous class and their nested classes
|
||||||
int lastSearch = name.length();
|
int lastSearch = name.length();
|
||||||
|
|
||||||
while (lastSearch != -1) {
|
while (lastSearch != -1) {
|
||||||
lastSearch = name.lastIndexOf('$', lastSearch - 1);
|
lastSearch = name.lastIndexOf('$', lastSearch - 1);
|
||||||
|
|
||||||
// names starting with digit is illegal java
|
// names starting with digit is illegal java
|
||||||
if (isDigit(name.charAt(lastSearch + 1))) {
|
if (isDigit(name.charAt(lastSearch + 1))) {
|
||||||
return;
|
return;
|
||||||
|
@ -251,15 +259,16 @@ public class Main {
|
||||||
|
|
||||||
if (name.contains("$")) {
|
if (name.contains("$")) {
|
||||||
String parentClass = name.substring(0, name.lastIndexOf("$"));
|
String parentClass = name.substring(0, name.lastIndexOf("$"));
|
||||||
|
|
||||||
if (!existingClasses.containsKey(parentClass)) {
|
if (!existingClasses.containsKey(parentClass)) {
|
||||||
throw new RuntimeException("Could not find parent class: " + parentClass + " for " + classNode.name);
|
throw new RuntimeException("Could not find parent class: " + parentClass + " for " + classNode.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
existingClasses.get(parentClass).addInnerClass(classBuilder);
|
existingClasses.get(parentClass).addInnerClass(classBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
classBuilder.addMembers();
|
classBuilder.addMembers();
|
||||||
existingClasses.put(name, classBuilder);
|
existingClasses.put(name, classBuilder);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
|
|
@ -13,7 +13,16 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet;
|
||||||
|
|
||||||
|
import static net.fabricmc.mappingio.tree.MappingTreeView.SRC_NAMESPACE_ID;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.AbstractMap.SimpleImmutableEntry;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import net.fabricmc.mappingio.MappingReader;
|
import net.fabricmc.mappingio.MappingReader;
|
||||||
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
|
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
|
||||||
|
@ -24,14 +33,6 @@ import net.fabricmc.mappingio.tree.MappingTreeView.ElementMappingView;
|
||||||
import net.fabricmc.mappingio.tree.MappingTreeView.MethodMappingView;
|
import net.fabricmc.mappingio.tree.MappingTreeView.MethodMappingView;
|
||||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.AbstractMap.SimpleImmutableEntry;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static net.fabricmc.mappingio.tree.MappingTreeView.SRC_NAMESPACE_ID;
|
|
||||||
|
|
||||||
//Taken from loom
|
//Taken from loom
|
||||||
public class MappingsStore {
|
public class MappingsStore {
|
||||||
private final MappingTreeView tree;
|
private final MappingTreeView tree;
|
||||||
|
@ -44,16 +45,19 @@ public class MappingsStore {
|
||||||
|
|
||||||
private static MappingTreeView readMappings(Path input) {
|
private static MappingTreeView readMappings(Path input) {
|
||||||
var tree = new MemoryMappingTree();
|
var tree = new MemoryMappingTree();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MappingReader.read(input, MappingFormat.TINY_2, new MappingSourceNsSwitch(tree, "named"));
|
MappingReader.read(input, MappingFormat.TINY_2_FILE, new MappingSourceNsSwitch(tree, "named"));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("Failed to read mappings", e);
|
throw new RuntimeException("Failed to read mappings", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDoc(ElementMappingView element, DocAdder adder) {
|
private void addDoc(ElementMappingView element, DocAdder adder) {
|
||||||
String doc = element.getComment();
|
String doc = element.getComment();
|
||||||
|
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
adder.addJavadoc("$L", doc);
|
adder.addJavadoc("$L", doc);
|
||||||
}
|
}
|
||||||
|
@ -61,11 +65,14 @@ public class MappingsStore {
|
||||||
|
|
||||||
public void addClassDoc(DocAdder adder, String className) {
|
public void addClassDoc(DocAdder adder, String className) {
|
||||||
var classDef = tree.getClass(className);
|
var classDef = tree.getClass(className);
|
||||||
|
|
||||||
if (classDef == null) {
|
if (classDef == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addDoc(classDef, adder);
|
addDoc(classDef, adder);
|
||||||
adder.addJavadoc("\n");
|
adder.addJavadoc("\n");
|
||||||
|
|
||||||
for (int id = SRC_NAMESPACE_ID; id < maxNamespace; id++) {
|
for (int id = SRC_NAMESPACE_ID; id < maxNamespace; id++) {
|
||||||
String transformedName = classDef.getName(id);
|
String transformedName = classDef.getName(id);
|
||||||
adder.addJavadoc("@mapping {@literal $L:$L}\n", tree.getNamespaceName(id), transformedName);
|
adder.addJavadoc("@mapping {@literal $L:$L}\n", tree.getNamespaceName(id), transformedName);
|
||||||
|
@ -74,17 +81,20 @@ public class MappingsStore {
|
||||||
|
|
||||||
public void addFieldDoc(DocAdder addJavadoc, String owner, String name, String desc) {
|
public void addFieldDoc(DocAdder addJavadoc, String owner, String name, String desc) {
|
||||||
var classDef = tree.getClass(owner);
|
var classDef = tree.getClass(owner);
|
||||||
|
|
||||||
if (classDef == null) {
|
if (classDef == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fieldDef = classDef.getField(name, desc);
|
var fieldDef = classDef.getField(name, desc);
|
||||||
|
|
||||||
if (fieldDef == null) {
|
if (fieldDef == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addDoc(fieldDef, addJavadoc);
|
addDoc(fieldDef, addJavadoc);
|
||||||
addJavadoc.addJavadoc("\n");
|
addJavadoc.addJavadoc("\n");
|
||||||
|
|
||||||
for (int id = SRC_NAMESPACE_ID; id < maxNamespace; id++) {
|
for (int id = SRC_NAMESPACE_ID; id < maxNamespace; id++) {
|
||||||
String transformedName = fieldDef.getName(id);
|
String transformedName = fieldDef.getName(id);
|
||||||
String mixinForm = "L" + classDef.getName(id) + ";" + transformedName + ":" + fieldDef.getDesc(id);
|
String mixinForm = "L" + classDef.getName(id) + ";" + transformedName + ":" + fieldDef.getDesc(id);
|
||||||
|
@ -94,11 +104,14 @@ public class MappingsStore {
|
||||||
|
|
||||||
public Map.Entry<String, String> getParamNameAndDoc(Environment environment, String owner, String name, String desc, int index) {
|
public Map.Entry<String, String> getParamNameAndDoc(Environment environment, String owner, String name, String desc, int index) {
|
||||||
var found = searchMethod(environment, owner, name, desc);
|
var found = searchMethod(environment, owner, name, desc);
|
||||||
|
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
var methodDef = found.getValue();
|
var methodDef = found.getValue();
|
||||||
|
|
||||||
if (methodDef.getArgs().isEmpty()) {
|
if (methodDef.getArgs().isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return methodDef.getArgs().stream()
|
return methodDef.getArgs().stream()
|
||||||
.filter(param -> param.getLvIndex() == index)
|
.filter(param -> param.getLvIndex() == index)
|
||||||
// Map.entry() is null-hostile
|
// Map.entry() is null-hostile
|
||||||
|
@ -106,17 +119,20 @@ public class MappingsStore {
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMethodDoc(DocAdder adder, Environment environment, String owner, String name, String desc) {
|
public void addMethodDoc(DocAdder adder, Environment environment, String owner, String name, String desc) {
|
||||||
var found = searchMethod(environment, owner, name, desc);
|
var found = searchMethod(environment, owner, name, desc);
|
||||||
|
|
||||||
if (found == null) {
|
if (found == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var methodDef = found.getValue();
|
var methodDef = found.getValue();
|
||||||
var ownerDef = found.getKey();
|
var ownerDef = found.getKey();
|
||||||
|
|
||||||
if (!ownerDef.equals(methodDef.getOwner())) {
|
if (!ownerDef.equals(methodDef.getOwner())) {
|
||||||
adder.addJavadoc("{@inheritDoc}");
|
adder.addJavadoc("{@inheritDoc}");
|
||||||
} else {
|
} else {
|
||||||
|
@ -124,6 +140,7 @@ public class MappingsStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
adder.addJavadoc("\n");
|
adder.addJavadoc("\n");
|
||||||
|
|
||||||
for (int id = SRC_NAMESPACE_ID; id < maxNamespace; id++) {
|
for (int id = SRC_NAMESPACE_ID; id < maxNamespace; id++) {
|
||||||
String transformedName = methodDef.getName(id);
|
String transformedName = methodDef.getName(id);
|
||||||
String mixinForm = "L" + ownerDef.getName(id) + ";" + transformedName + methodDef.getDesc(id);
|
String mixinForm = "L" + ownerDef.getName(id) + ";" + transformedName + methodDef.getDesc(id);
|
||||||
|
@ -134,16 +151,19 @@ public class MappingsStore {
|
||||||
private Map.Entry<ClassMappingView, MethodMappingView> searchMethod(Environment environment, String owner, String name, String desc) {
|
private Map.Entry<ClassMappingView, MethodMappingView> searchMethod(Environment environment, String owner, String name, String desc) {
|
||||||
var classDef = tree.getClass(owner);
|
var classDef = tree.getClass(owner);
|
||||||
|
|
||||||
if (classDef == null)
|
if (classDef == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var methodDef = classDef.getMethod(name, desc);
|
var methodDef = classDef.getMethod(name, desc);
|
||||||
if (methodDef != null)
|
|
||||||
return Map.entry(methodDef.getOwner(), methodDef);
|
|
||||||
|
|
||||||
|
if (methodDef != null) {
|
||||||
|
return Map.entry(methodDef.getOwner(), methodDef);
|
||||||
|
}
|
||||||
|
|
||||||
for (String superName : environment.superTypes().getOrDefault(owner, List.of())) {
|
for (String superName : environment.superTypes().getOrDefault(owner, List.of())) {
|
||||||
var ret = searchMethod(environment, superName, name, desc);
|
var ret = searchMethod(environment, superName, name, desc);
|
||||||
|
|
||||||
if (ret != null) {
|
if (ret != null) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,23 +13,9 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet;
|
|
||||||
|
|
||||||
import com.squareup.javapoet.MethodSpec;
|
package net.fabricmc.filament.mappingpoet;
|
||||||
import com.squareup.javapoet.ParameterSpec;
|
|
||||||
import com.squareup.javapoet.TypeName;
|
|
||||||
import net.fabricmc.mappingpoet.signature.AnnotationAwareDescriptors;
|
|
||||||
import net.fabricmc.mappingpoet.signature.AnnotationAwareSignatures;
|
|
||||||
import net.fabricmc.mappingpoet.signature.MethodSignature;
|
|
||||||
import net.fabricmc.mappingpoet.signature.TypeAnnotationBank;
|
|
||||||
import net.fabricmc.mappingpoet.signature.TypeAnnotationMapping;
|
|
||||||
import net.fabricmc.mappingpoet.signature.TypeAnnotationStorage;
|
|
||||||
import org.objectweb.asm.TypeReference;
|
|
||||||
import org.objectweb.asm.tree.AnnotationNode;
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
|
||||||
import org.objectweb.asm.tree.MethodNode;
|
|
||||||
|
|
||||||
import javax.lang.model.element.Modifier;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -39,6 +25,23 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
|
import org.objectweb.asm.TypeReference;
|
||||||
|
import org.objectweb.asm.tree.AnnotationNode;
|
||||||
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
import org.objectweb.asm.tree.MethodNode;
|
||||||
|
|
||||||
|
import net.fabricmc.filament.mappingpoet.signature.AnnotationAwareDescriptors;
|
||||||
|
import net.fabricmc.filament.mappingpoet.signature.AnnotationAwareSignatures;
|
||||||
|
import net.fabricmc.filament.mappingpoet.signature.MethodSignature;
|
||||||
|
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationBank;
|
||||||
|
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationMapping;
|
||||||
|
import net.fabricmc.filament.mappingpoet.signature.TypeAnnotationStorage;
|
||||||
|
|
||||||
public class MethodBuilder {
|
public class MethodBuilder {
|
||||||
private static final Set<String> RESERVED_KEYWORDS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
private static final Set<String> RESERVED_KEYWORDS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||||
"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue",
|
"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue",
|
||||||
|
@ -83,6 +86,7 @@ public class MethodBuilder {
|
||||||
if (regularAnnotations == null || regularAnnotations.length <= index) {
|
if (regularAnnotations == null || regularAnnotations.length <= index) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addDirectAnnotations(builder, regularAnnotations[index]);
|
addDirectAnnotations(builder, regularAnnotations[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +94,7 @@ public class MethodBuilder {
|
||||||
if (regularAnnotations == null) {
|
if (regularAnnotations == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AnnotationNode annotation : regularAnnotations) {
|
for (AnnotationNode annotation : regularAnnotations) {
|
||||||
builder.addAnnotation(FieldBuilder.parseAnnotation(annotation));
|
builder.addAnnotation(FieldBuilder.parseAnnotation(annotation));
|
||||||
}
|
}
|
||||||
|
@ -104,8 +109,10 @@ public class MethodBuilder {
|
||||||
usedNames.add(suggestedName);
|
usedNames.add(suggestedName);
|
||||||
return suggestedName;
|
return suggestedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
int t = 2;
|
int t = 2;
|
||||||
String currentSuggestion = suggestedName + t;
|
String currentSuggestion = suggestedName + t;
|
||||||
|
|
||||||
while (usedNames.contains(currentSuggestion)) {
|
while (usedNames.contains(currentSuggestion)) {
|
||||||
t++;
|
t++;
|
||||||
currentSuggestion = suggestedName + t;
|
currentSuggestion = suggestedName + t;
|
||||||
|
@ -122,22 +129,29 @@ public class MethodBuilder {
|
||||||
int newEnd = str.length();
|
int newEnd = str.length();
|
||||||
int ltStart;
|
int ltStart;
|
||||||
ltStart = str.indexOf('<', newStart);
|
ltStart = str.indexOf('<', newStart);
|
||||||
|
|
||||||
if (ltStart != -1 && ltStart < newEnd) {
|
if (ltStart != -1 && ltStart < newEnd) {
|
||||||
newEnd = ltStart;
|
newEnd = ltStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
ltStart = str.indexOf('[', newStart);
|
ltStart = str.indexOf('[', newStart);
|
||||||
|
|
||||||
if (ltStart != -1 && ltStart < newEnd) {
|
if (ltStart != -1 && ltStart < newEnd) {
|
||||||
newEnd = ltStart;
|
newEnd = ltStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dotEnd;
|
int dotEnd;
|
||||||
|
|
||||||
if ((dotEnd = str.lastIndexOf(".", newEnd)) != -1) {
|
if ((dotEnd = str.lastIndexOf(".", newEnd)) != -1) {
|
||||||
newStart = dotEnd + 1;
|
newStart = dotEnd + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = Character.toLowerCase(str.charAt(newStart)) + str.substring(newStart + 1, newEnd);
|
str = Character.toLowerCase(str.charAt(newStart)) + str.substring(newStart + 1, newEnd);
|
||||||
|
|
||||||
if (str.equals("boolean")) {
|
if (str.equals("boolean")) {
|
||||||
str = "bool";
|
str = "bool";
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +179,7 @@ public class MethodBuilder {
|
||||||
if (regularAnnotations == null) {
|
if (regularAnnotations == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AnnotationNode annotation : regularAnnotations) {
|
for (AnnotationNode annotation : regularAnnotations) {
|
||||||
builder.addAnnotation(FieldBuilder.parseAnnotation(annotation));
|
builder.addAnnotation(FieldBuilder.parseAnnotation(annotation));
|
||||||
}
|
}
|
||||||
|
@ -177,6 +192,7 @@ public class MethodBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeName typeName;
|
TypeName typeName;
|
||||||
|
|
||||||
if (signature != null) {
|
if (signature != null) {
|
||||||
typeName = signature.result();
|
typeName = signature.result();
|
||||||
} else {
|
} else {
|
||||||
|
@ -185,6 +201,7 @@ public class MethodBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.returns(typeName);
|
builder.returns(typeName);
|
||||||
|
|
||||||
if (typeName != TypeName.VOID && !builder.modifiers.contains(Modifier.ABSTRACT)) {
|
if (typeName != TypeName.VOID && !builder.modifiers.contains(Modifier.ABSTRACT)) {
|
||||||
builder.addStatement("throw new RuntimeException()");
|
builder.addStatement("throw new RuntimeException()");
|
||||||
} else if (methodNode.annotationDefault != null) {
|
} else if (methodNode.annotationDefault != null) {
|
||||||
|
@ -202,8 +219,10 @@ public class MethodBuilder {
|
||||||
// generate receiver param for type annos
|
// generate receiver param for type annos
|
||||||
|
|
||||||
TypeAnnotationBank receiverAnnos = typeAnnotations.getBank(TypeReference.newTypeReference(TypeReference.METHOD_RECEIVER));
|
TypeAnnotationBank receiverAnnos = typeAnnotations.getBank(TypeReference.newTypeReference(TypeReference.METHOD_RECEIVER));
|
||||||
|
|
||||||
if (!receiverAnnos.isEmpty()) {
|
if (!receiverAnnos.isEmpty()) {
|
||||||
ParameterSpec.Builder receiverBuilder;
|
ParameterSpec.Builder receiverBuilder;
|
||||||
|
|
||||||
// only instance inner class ctor can have receivers
|
// only instance inner class ctor can have receivers
|
||||||
if (methodNode.name.equals("<init>")) {
|
if (methodNode.name.equals("<init>")) {
|
||||||
TypeName annotatedReceiver = AnnotationAwareSignatures.parseSignature("L" + receiverSignature.substring(0, receiverSignature.lastIndexOf('.')) + ";", receiverAnnos, environment);
|
TypeName annotatedReceiver = AnnotationAwareSignatures.parseSignature("L" + receiverSignature.substring(0, receiverSignature.lastIndexOf('.')) + ";", receiverAnnos, environment);
|
||||||
|
@ -217,6 +236,7 @@ public class MethodBuilder {
|
||||||
TypeName annotatedReceiver = AnnotationAwareSignatures.parseSignature("L" + receiverSignature + ";", receiverAnnos, environment);
|
TypeName annotatedReceiver = AnnotationAwareSignatures.parseSignature("L" + receiverSignature + ";", receiverAnnos, environment);
|
||||||
receiverBuilder = ParameterSpec.builder(annotatedReceiver, "this");
|
receiverBuilder = ParameterSpec.builder(annotatedReceiver, "this");
|
||||||
}
|
}
|
||||||
|
|
||||||
// receiver param cannot have its jd/param anno except type use anno
|
// receiver param cannot have its jd/param anno except type use anno
|
||||||
builder.addParameter(receiverBuilder.build());
|
builder.addParameter(receiverBuilder.build());
|
||||||
}
|
}
|
||||||
|
@ -224,12 +244,15 @@ public class MethodBuilder {
|
||||||
List<AnnotationNode>[] visibleParameterAnnotations = methodNode.visibleParameterAnnotations;
|
List<AnnotationNode>[] visibleParameterAnnotations = methodNode.visibleParameterAnnotations;
|
||||||
List<AnnotationNode>[] invisibleParameterAnnotations = methodNode.invisibleParameterAnnotations;
|
List<AnnotationNode>[] invisibleParameterAnnotations = methodNode.invisibleParameterAnnotations;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for (ParamType paramType : paramTypes) {
|
for (ParamType paramType : paramTypes) {
|
||||||
paramType.fillName(usedParamNames);
|
paramType.fillName(usedParamNames);
|
||||||
ParameterSpec.Builder paramBuilder = ParameterSpec.builder(paramType.type, paramType.name, paramType.modifiers);
|
ParameterSpec.Builder paramBuilder = ParameterSpec.builder(paramType.type, paramType.name, paramType.modifiers);
|
||||||
|
|
||||||
if (paramType.comment != null) {
|
if (paramType.comment != null) {
|
||||||
paramBuilder.addJavadoc(paramType.comment + "\n");
|
paramBuilder.addJavadoc(paramType.comment + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
addDirectAnnotations(paramBuilder, visibleParameterAnnotations, index);
|
addDirectAnnotations(paramBuilder, visibleParameterAnnotations, index);
|
||||||
addDirectAnnotations(paramBuilder, invisibleParameterAnnotations, index);
|
addDirectAnnotations(paramBuilder, invisibleParameterAnnotations, index);
|
||||||
builder.addParameter(paramBuilder.build());
|
builder.addParameter(paramBuilder.build());
|
||||||
|
@ -246,9 +269,11 @@ public class MethodBuilder {
|
||||||
if (desc.charAt(index) != '(') {
|
if (desc.charAt(index) != '(') {
|
||||||
throw invalidMethodDesc(desc, index);
|
throw invalidMethodDesc(desc, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++; // consume '('
|
index++; // consume '('
|
||||||
|
|
||||||
Iterator<TypeName> signatureParamIterator = signature == null ? Collections.emptyIterator() : signature.parameters().iterator();
|
Iterator<TypeName> signatureParamIterator = signature == null ? Collections.emptyIterator() : signature.parameters().iterator();
|
||||||
|
|
||||||
while (desc.charAt(index) != ')') {
|
while (desc.charAt(index) != ')') {
|
||||||
int oldIndex = index;
|
int oldIndex = index;
|
||||||
Map.Entry<Integer, TypeName> parsedParam = FieldBuilder.parseType(desc, index);
|
Map.Entry<Integer, TypeName> parsedParam = FieldBuilder.parseType(desc, index);
|
||||||
|
@ -257,19 +282,25 @@ public class MethodBuilder {
|
||||||
|
|
||||||
if (paramIndex >= formalParamStartIndex) { // skip guessed synthetic/implicit params
|
if (paramIndex >= formalParamStartIndex) { // skip guessed synthetic/implicit params
|
||||||
TypeName parsedType;
|
TypeName parsedType;
|
||||||
|
|
||||||
if (signatureParamIterator.hasNext()) {
|
if (signatureParamIterator.hasNext()) {
|
||||||
parsedType = signatureParamIterator.next();
|
parsedType = signatureParamIterator.next();
|
||||||
} else {
|
} else {
|
||||||
parsedType = AnnotationAwareDescriptors.parseDesc(desc.substring(oldIndex, index), typeAnnotations.getBank(TypeReference.newFormalParameterReference(paramIndex - formalParamStartIndex)), environment);
|
parsedType = AnnotationAwareDescriptors.parseDesc(desc.substring(oldIndex, index), typeAnnotations.getBank(TypeReference.newFormalParameterReference(paramIndex - formalParamStartIndex)), environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
paramTypes.add(new ParamType(mappings.getParamNameAndDoc(environment, classNode.name, methodNode.name, methodNode.desc, slot), parsedType, usedParamNames, slot));
|
paramTypes.add(new ParamType(mappings.getParamNameAndDoc(environment, classNode.name, methodNode.name, methodNode.desc, slot), parsedType, usedParamNames, slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
slot++;
|
slot++;
|
||||||
|
|
||||||
if (nonAnnotatedParsedType.equals(TypeName.DOUBLE) || nonAnnotatedParsedType.equals(TypeName.LONG)) {
|
if (nonAnnotatedParsedType.equals(TypeName.DOUBLE) || nonAnnotatedParsedType.equals(TypeName.LONG)) {
|
||||||
slot++;
|
slot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
paramIndex++;
|
paramIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bruh, we don't care about return type
|
/* bruh, we don't care about return type
|
||||||
index++; // consume ')'
|
index++; // consume ')'
|
||||||
Map.Entry<Integer, TypeName> parsedReturn = FieldBuilder.parseType(desc, index);
|
Map.Entry<Integer, TypeName> parsedReturn = FieldBuilder.parseType(desc, index);
|
||||||
|
@ -283,11 +314,15 @@ public class MethodBuilder {
|
||||||
for (TypeName each : signature.thrown()) {
|
for (TypeName each : signature.thrown()) {
|
||||||
builder.addException(each);
|
builder.addException(each);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> exceptions = methodNode.exceptions;
|
List<String> exceptions = methodNode.exceptions;
|
||||||
|
|
||||||
if (exceptions != null) {
|
if (exceptions != null) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
for (String internalName : exceptions) {
|
for (String internalName : exceptions) {
|
||||||
builder.addException(AnnotationAwareDescriptors.parseType(internalName, typeAnnotations.getBank(TypeReference.newExceptionReference(index)), environment));
|
builder.addException(AnnotationAwareDescriptors.parseType(internalName, typeAnnotations.getBank(TypeReference.newExceptionReference(index)), environment));
|
||||||
index++;
|
index++;
|
||||||
|
@ -309,8 +344,9 @@ public class MethodBuilder {
|
||||||
private final Modifier[] modifiers;
|
private final Modifier[] modifiers;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
public ParamType(Map.Entry<String, String> nameAndDoc, TypeName type, Set<String> usedNames, int slot) {
|
ParamType(Map.Entry<String, String> nameAndDoc, TypeName type, Set<String> usedNames, int slot) {
|
||||||
this.name = nameAndDoc != null ? nameAndDoc.getKey() : null;
|
this.name = nameAndDoc != null ? nameAndDoc.getKey() : null;
|
||||||
|
|
||||||
if (this.name != null) {
|
if (this.name != null) {
|
||||||
if (usedNames.contains(this.name)) {
|
if (usedNames.contains(this.name)) {
|
||||||
System.err.printf("Overridden parameter name detected in %s %s %s slot %d, resetting%n", classNode.name, methodNode.name, methodNode.desc, slot);
|
System.err.printf("Overridden parameter name detected in %s %s %s slot %d, resetting%n", classNode.name, methodNode.name, methodNode.desc, slot);
|
||||||
|
@ -319,6 +355,7 @@ public class MethodBuilder {
|
||||||
usedNames.add(this.name);
|
usedNames.add(this.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.comment = nameAndDoc == null ? null : nameAndDoc.getValue();
|
this.comment = nameAndDoc == null ? null : nameAndDoc.getValue();
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.modifiers = new ModifierBuilder(0)
|
this.modifiers = new ModifierBuilder(0)
|
||||||
|
@ -329,6 +366,7 @@ public class MethodBuilder {
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = reserveValidName(suggestName(type), usedNames);
|
name = reserveValidName(suggestName(type), usedNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,17 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet;
|
|
||||||
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
package net.fabricmc.filament.mappingpoet;
|
||||||
|
|
||||||
import javax.lang.model.element.Modifier;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ModifierBuilder {
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
|
||||||
|
public class ModifierBuilder {
|
||||||
private final int access;
|
private final int access;
|
||||||
private boolean needsUnseal;
|
private boolean needsUnseal;
|
||||||
|
|
||||||
|
@ -48,7 +49,6 @@ public class ModifierBuilder {
|
||||||
needsUnseal = true;
|
needsUnseal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ public class ModifierBuilder {
|
||||||
if (java.lang.reflect.Modifier.isFinal(access)) {
|
if (java.lang.reflect.Modifier.isFinal(access)) {
|
||||||
modifiers.add(Modifier.FINAL);
|
modifiers.add(Modifier.FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return modifiers.toArray(new Modifier[]{});
|
return modifiers.toArray(new Modifier[]{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,9 +74,11 @@ public class ModifierBuilder {
|
||||||
if (java.lang.reflect.Modifier.isAbstract(access) && type != Type.ENUM) {
|
if (java.lang.reflect.Modifier.isAbstract(access) && type != Type.ENUM) {
|
||||||
modifiers.add(Modifier.ABSTRACT);
|
modifiers.add(Modifier.ABSTRACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isStatic(access)) {
|
if (java.lang.reflect.Modifier.isStatic(access)) {
|
||||||
modifiers.add(Modifier.STATIC);
|
modifiers.add(Modifier.STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!java.lang.reflect.Modifier.isAbstract(access) && !java.lang.reflect.Modifier.isStatic(access) && type == Type.METHOD) {
|
if (!java.lang.reflect.Modifier.isAbstract(access) && !java.lang.reflect.Modifier.isStatic(access) && type == Type.METHOD) {
|
||||||
modifiers.add(Modifier.DEFAULT);
|
modifiers.add(Modifier.DEFAULT);
|
||||||
}
|
}
|
||||||
|
@ -83,18 +86,23 @@ public class ModifierBuilder {
|
||||||
if (java.lang.reflect.Modifier.isFinal(access) && type != Type.ENUM && type != Type.RECORD) {
|
if (java.lang.reflect.Modifier.isFinal(access) && type != Type.ENUM && type != Type.RECORD) {
|
||||||
modifiers.add(Modifier.FINAL);
|
modifiers.add(Modifier.FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isTransient(access) && type == Type.FIELD) {
|
if (java.lang.reflect.Modifier.isTransient(access) && type == Type.FIELD) {
|
||||||
modifiers.add(Modifier.TRANSIENT);
|
modifiers.add(Modifier.TRANSIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isVolatile(access) && type == Type.FIELD) {
|
if (java.lang.reflect.Modifier.isVolatile(access) && type == Type.FIELD) {
|
||||||
modifiers.add(Modifier.VOLATILE);
|
modifiers.add(Modifier.VOLATILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isSynchronized(access) && type == Type.METHOD) {
|
if (java.lang.reflect.Modifier.isSynchronized(access) && type == Type.METHOD) {
|
||||||
modifiers.add(Modifier.SYNCHRONIZED);
|
modifiers.add(Modifier.SYNCHRONIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isNative(access) && type == Type.METHOD) {
|
if (java.lang.reflect.Modifier.isNative(access) && type == Type.METHOD) {
|
||||||
modifiers.add(Modifier.NATIVE);
|
modifiers.add(Modifier.NATIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isStrict(access)) {
|
if (java.lang.reflect.Modifier.isStrict(access)) {
|
||||||
modifiers.add(Modifier.STRICTFP); // obsolete as of Java 17
|
modifiers.add(Modifier.STRICTFP); // obsolete as of Java 17
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet;
|
||||||
|
|
||||||
import java.util.AbstractMap;
|
import java.util.AbstractMap;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -30,27 +31,30 @@ import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeVariableName;
|
import com.squareup.javapoet.TypeVariableName;
|
||||||
import com.squareup.javapoet.WildcardTypeName;
|
import com.squareup.javapoet.WildcardTypeName;
|
||||||
|
|
||||||
import net.fabricmc.mappingpoet.signature.ClassSignature;
|
import net.fabricmc.filament.mappingpoet.signature.ClassSignature;
|
||||||
import net.fabricmc.mappingpoet.signature.MethodSignature;
|
import net.fabricmc.filament.mappingpoet.signature.MethodSignature;
|
||||||
|
|
||||||
public final class Signatures {
|
public final class Signatures {
|
||||||
|
|
||||||
public static ClassSignature parseClassSignature(final String signature) {
|
public static ClassSignature parseClassSignature(final String signature) {
|
||||||
// <A:Labc.Def:Ljava.util.Iterable<Ljava/lang.Object;>;B:Ljava/lang/Object>Ljava/lang/Object; etc etc
|
// <A:Labc.Def:Ljava.util.Iterable<Ljava/lang.Object;>;B:Ljava/lang/Object>Ljava/lang/Object; etc etc
|
||||||
int index = 0;
|
int index = 0;
|
||||||
char ch;
|
char ch;
|
||||||
List<TypeVariableName> generics = Collections.emptyList();
|
List<TypeVariableName> generics = Collections.emptyList();
|
||||||
|
|
||||||
if (signature.charAt(0) == '<') {
|
if (signature.charAt(0) == '<') {
|
||||||
// parse generic decl
|
// parse generic decl
|
||||||
index++; // consume '<'
|
index++; // consume '<'
|
||||||
|
|
||||||
// parse type params e.g. <A, B>
|
// parse type params e.g. <A, B>
|
||||||
generics = new LinkedList<>();
|
generics = new LinkedList<>();
|
||||||
|
|
||||||
while ((ch = signature.charAt(index)) != '>') {
|
while ((ch = signature.charAt(index)) != '>') {
|
||||||
int genericNameStart = index;
|
int genericNameStart = index;
|
||||||
|
|
||||||
if (ch == ':') {
|
if (ch == ':') {
|
||||||
throw errorAt(signature, index);
|
throw errorAt(signature, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
index++;
|
index++;
|
||||||
} while (signature.charAt(index) != ':');
|
} while (signature.charAt(index) != ':');
|
||||||
|
@ -59,14 +63,17 @@ public final class Signatures {
|
||||||
|
|
||||||
List<TypeName> bounds = new LinkedList<>();
|
List<TypeName> bounds = new LinkedList<>();
|
||||||
boolean classBound = true;
|
boolean classBound = true;
|
||||||
|
|
||||||
while (signature.charAt(index) == ':') {
|
while (signature.charAt(index) == ':') {
|
||||||
// parse bounds
|
// parse bounds
|
||||||
index++; // consume ':'
|
index++; // consume ':'
|
||||||
|
|
||||||
if (classBound && signature.charAt(index) == ':') {
|
if (classBound && signature.charAt(index) == ':') {
|
||||||
// No class bound, only interface bounds, so '::'
|
// No class bound, only interface bounds, so '::'
|
||||||
classBound = false;
|
classBound = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
classBound = false;
|
classBound = false;
|
||||||
Map.Entry<Integer, TypeName> bound = parseParameterizedType(signature, index);
|
Map.Entry<Integer, TypeName> bound = parseParameterizedType(signature, index);
|
||||||
index = bound.getKey();
|
index = bound.getKey();
|
||||||
|
@ -80,6 +87,7 @@ public final class Signatures {
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedList<TypeName> supers = new LinkedList<>();
|
LinkedList<TypeName> supers = new LinkedList<>();
|
||||||
|
|
||||||
while (index < signature.length()) {
|
while (index < signature.length()) {
|
||||||
Map.Entry<Integer, TypeName> bound = parseParameterizedType(signature, index);
|
Map.Entry<Integer, TypeName> bound = parseParameterizedType(signature, index);
|
||||||
index = bound.getKey();
|
index = bound.getKey();
|
||||||
|
@ -93,17 +101,21 @@ public final class Signatures {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
char ch;
|
char ch;
|
||||||
List<TypeVariableName> generics = Collections.emptyList();
|
List<TypeVariableName> generics = Collections.emptyList();
|
||||||
|
|
||||||
if (signature.charAt(0) == '<') {
|
if (signature.charAt(0) == '<') {
|
||||||
// parse generic decl
|
// parse generic decl
|
||||||
index++; // consume '<'
|
index++; // consume '<'
|
||||||
|
|
||||||
// parse type params e.g. <A, B>
|
// parse type params e.g. <A, B>
|
||||||
generics = new LinkedList<>();
|
generics = new LinkedList<>();
|
||||||
|
|
||||||
while ((ch = signature.charAt(index)) != '>') {
|
while ((ch = signature.charAt(index)) != '>') {
|
||||||
int genericNameStart = index;
|
int genericNameStart = index;
|
||||||
|
|
||||||
if (ch == ':') {
|
if (ch == ':') {
|
||||||
throw errorAt(signature, index);
|
throw errorAt(signature, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
index++;
|
index++;
|
||||||
} while (signature.charAt(index) != ':');
|
} while (signature.charAt(index) != ':');
|
||||||
|
@ -112,14 +124,17 @@ public final class Signatures {
|
||||||
|
|
||||||
List<TypeName> bounds = new LinkedList<>();
|
List<TypeName> bounds = new LinkedList<>();
|
||||||
boolean classBound = true;
|
boolean classBound = true;
|
||||||
|
|
||||||
while (signature.charAt(index) == ':') {
|
while (signature.charAt(index) == ':') {
|
||||||
// parse bounds
|
// parse bounds
|
||||||
index++; // consume ':'
|
index++; // consume ':'
|
||||||
|
|
||||||
if (classBound && signature.charAt(index) == ':') {
|
if (classBound && signature.charAt(index) == ':') {
|
||||||
// No class bound, only interface bounds, so '::'
|
// No class bound, only interface bounds, so '::'
|
||||||
classBound = false;
|
classBound = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
classBound = false;
|
classBound = false;
|
||||||
Map.Entry<Integer, TypeName> bound = parseParameterizedType(signature, index);
|
Map.Entry<Integer, TypeName> bound = parseParameterizedType(signature, index);
|
||||||
index = bound.getKey();
|
index = bound.getKey();
|
||||||
|
@ -135,9 +150,11 @@ public final class Signatures {
|
||||||
if (signature.charAt(index) != '(') {
|
if (signature.charAt(index) != '(') {
|
||||||
throw errorAt(signature, index);
|
throw errorAt(signature, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++; // consume '('
|
index++; // consume '('
|
||||||
|
|
||||||
LinkedList<TypeName> params = new LinkedList<>();
|
LinkedList<TypeName> params = new LinkedList<>();
|
||||||
|
|
||||||
while (signature.charAt(index) != ')') {
|
while (signature.charAt(index) != ')') {
|
||||||
Map.Entry<Integer, TypeName> param = parseParameterizedType(signature, index);
|
Map.Entry<Integer, TypeName> param = parseParameterizedType(signature, index);
|
||||||
index = param.getKey();
|
index = param.getKey();
|
||||||
|
@ -147,6 +164,7 @@ public final class Signatures {
|
||||||
index++; // consume ')'
|
index++; // consume ')'
|
||||||
|
|
||||||
TypeName returnType;
|
TypeName returnType;
|
||||||
|
|
||||||
if (signature.charAt(index) == 'V') {
|
if (signature.charAt(index) == 'V') {
|
||||||
returnType = TypeName.VOID;
|
returnType = TypeName.VOID;
|
||||||
index++;
|
index++;
|
||||||
|
@ -157,6 +175,7 @@ public final class Signatures {
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkedList<TypeName> thrown = new LinkedList<>();
|
LinkedList<TypeName> thrown = new LinkedList<>();
|
||||||
|
|
||||||
while (index < signature.length() && signature.charAt(index) == '^') {
|
while (index < signature.length() && signature.charAt(index) == '^') {
|
||||||
index++; // consume '^'
|
index++; // consume '^'
|
||||||
Map.Entry<Integer, TypeName> parsedThrown = parseParameterizedType(signature, index);
|
Map.Entry<Integer, TypeName> parsedThrown = parseParameterizedType(signature, index);
|
||||||
|
@ -175,6 +194,7 @@ public final class Signatures {
|
||||||
GenericStack stack = new GenericStack();
|
GenericStack stack = new GenericStack();
|
||||||
|
|
||||||
int index = startOffset;
|
int index = startOffset;
|
||||||
|
|
||||||
// the loop parses a type and try to quit levels if possible
|
// the loop parses a type and try to quit levels if possible
|
||||||
do {
|
do {
|
||||||
char ch = signature.charAt(index);
|
char ch = signature.charAt(index);
|
||||||
|
@ -208,6 +228,7 @@ public final class Signatures {
|
||||||
|
|
||||||
if (parseExactType) {
|
if (parseExactType) {
|
||||||
int arrayLevel = 0;
|
int arrayLevel = 0;
|
||||||
|
|
||||||
while ((ch = signature.charAt(index)) == '[') {
|
while ((ch = signature.charAt(index)) == '[') {
|
||||||
index++;
|
index++;
|
||||||
arrayLevel++;
|
arrayLevel++;
|
||||||
|
@ -230,9 +251,11 @@ public final class Signatures {
|
||||||
case 'T': {
|
case 'T': {
|
||||||
// "TE;" for <E>
|
// "TE;" for <E>
|
||||||
int nameStart = index;
|
int nameStart = index;
|
||||||
|
|
||||||
while (signature.charAt(index) != ';') {
|
while (signature.charAt(index) != ';') {
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
String typeVarName = signature.substring(nameStart, index);
|
String typeVarName = signature.substring(nameStart, index);
|
||||||
stack.add(TypeVariableName.get(typeVarName), arrayLevel, bounded, extendsBound);
|
stack.add(TypeVariableName.get(typeVarName), arrayLevel, bounded, extendsBound);
|
||||||
index++; // read ending ";"
|
index++; // read ending ";"
|
||||||
|
@ -245,6 +268,7 @@ public final class Signatures {
|
||||||
int nameStart = index;
|
int nameStart = index;
|
||||||
ClassName currentClass = null;
|
ClassName currentClass = null;
|
||||||
int nextSimpleNamePrev = -1;
|
int nextSimpleNamePrev = -1;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ch = signature.charAt(index);
|
ch = signature.charAt(index);
|
||||||
|
|
||||||
|
@ -252,6 +276,7 @@ public final class Signatures {
|
||||||
if (currentClass != null) {
|
if (currentClass != null) {
|
||||||
throw errorAt(signature, index);
|
throw errorAt(signature, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextSimpleNamePrev = index;
|
nextSimpleNamePrev = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,6 +289,7 @@ public final class Signatures {
|
||||||
String simpleName = signature.substring(nextSimpleNamePrev + 1, index);
|
String simpleName = signature.substring(nextSimpleNamePrev + 1, index);
|
||||||
currentClass = currentClass.nestedClass(simpleName);
|
currentClass = currentClass.nestedClass(simpleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextSimpleNamePrev = index;
|
nextSimpleNamePrev = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,6 +297,7 @@ public final class Signatures {
|
||||||
} while (ch != '<' && ch != ';');
|
} while (ch != '<' && ch != ';');
|
||||||
|
|
||||||
assert currentClass != null;
|
assert currentClass != null;
|
||||||
|
|
||||||
if (ch == ';') {
|
if (ch == ';') {
|
||||||
stack.add(currentClass, arrayLevel, bounded, extendsBound);
|
stack.add(currentClass, arrayLevel, bounded, extendsBound);
|
||||||
}
|
}
|
||||||
|
@ -278,6 +305,7 @@ public final class Signatures {
|
||||||
if (ch == '<') {
|
if (ch == '<') {
|
||||||
stack.push(Frame.ofClass(currentClass), arrayLevel, bounded, extendsBound);
|
stack.push(Frame.ofClass(currentClass), arrayLevel, bounded, extendsBound);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -288,6 +316,7 @@ public final class Signatures {
|
||||||
|
|
||||||
// quit generics
|
// quit generics
|
||||||
quitLoop:
|
quitLoop:
|
||||||
|
|
||||||
while (stack.canQuit() && signature.charAt(index) == '>') {
|
while (stack.canQuit() && signature.charAt(index) == '>') {
|
||||||
// pop
|
// pop
|
||||||
stack.popFrame();
|
stack.popFrame();
|
||||||
|
@ -298,6 +327,7 @@ public final class Signatures {
|
||||||
if (ch != '.') {
|
if (ch != '.') {
|
||||||
throw errorAt(signature, index);
|
throw errorAt(signature, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
int innerNameStart = index;
|
int innerNameStart = index;
|
||||||
final int checkIndex = index;
|
final int checkIndex = index;
|
||||||
|
@ -309,10 +339,13 @@ public final class Signatures {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ch = signature.charAt(index);
|
ch = signature.charAt(index);
|
||||||
|
|
||||||
if (ch == '.' || ch == ';' || ch == '<') {
|
if (ch == '.' || ch == ';' || ch == '<') {
|
||||||
String simpleName = signature.substring(innerNameStart, index);
|
String simpleName = signature.substring(innerNameStart, index);
|
||||||
|
|
||||||
if (ch == '.' || ch == ';') {
|
if (ch == '.' || ch == ';') {
|
||||||
stack.tweakLast(name -> ((ParameterizedTypeName) name).nestedClass(simpleName));
|
stack.tweakLast(name -> ((ParameterizedTypeName) name).nestedClass(simpleName));
|
||||||
|
|
||||||
if (ch == ';') {
|
if (ch == ';') {
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
|
@ -329,9 +362,7 @@ public final class Signatures {
|
||||||
} else {
|
} else {
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (stack.canQuit());
|
} while (stack.canQuit());
|
||||||
|
|
||||||
assert stack.deque.size() == 1;
|
assert stack.deque.size() == 1;
|
||||||
|
@ -345,9 +376,11 @@ public final class Signatures {
|
||||||
|
|
||||||
public static TypeName wrap(TypeName component, int level, boolean bounded, boolean extendsBound) {
|
public static TypeName wrap(TypeName component, int level, boolean bounded, boolean extendsBound) {
|
||||||
TypeName ret = component;
|
TypeName ret = component;
|
||||||
|
|
||||||
for (int i = 0; i < level; i++) {
|
for (int i = 0; i < level; i++) {
|
||||||
ret = ArrayTypeName.of(ret);
|
ret = ArrayTypeName.of(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bounded ? extendsBound ? WildcardTypeName.subtypeOf(ret) : WildcardTypeName.supertypeOf(ret) : ret;
|
return bounded ? extendsBound ? WildcardTypeName.subtypeOf(ret) : WildcardTypeName.supertypeOf(ret) : ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +405,7 @@ public final class Signatures {
|
||||||
case 'Z':
|
case 'Z':
|
||||||
return TypeName.BOOLEAN;
|
return TypeName.BOOLEAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("Invalid primitive " + c);
|
throw new IllegalArgumentException("Invalid primitive " + c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,6 +424,7 @@ public final class Signatures {
|
||||||
if (parameters.size() != 1) {
|
if (parameters.size() != 1) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return parameters.get(0);
|
return parameters.get(0);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.jd;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.jd;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -30,7 +31,6 @@ import jdk.javadoc.doclet.Taglet;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class MappingTaglet implements Taglet {
|
public final class MappingTaglet implements Taglet {
|
||||||
|
|
||||||
public MappingTaglet() {
|
public MappingTaglet() {
|
||||||
// Required by javadoc
|
// Required by javadoc
|
||||||
}
|
}
|
||||||
|
@ -59,9 +59,11 @@ public final class MappingTaglet implements Taglet {
|
||||||
builder.append("<thead>\n");
|
builder.append("<thead>\n");
|
||||||
builder.append("<th>Namespace</th>\n");
|
builder.append("<th>Namespace</th>\n");
|
||||||
builder.append("<th>Name</th>\n");
|
builder.append("<th>Name</th>\n");
|
||||||
|
|
||||||
if (!typeDecl) {
|
if (!typeDecl) {
|
||||||
builder.append("<th>Mixin selector</th>\n");
|
builder.append("<th>Mixin selector</th>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append("</thead>\n");
|
builder.append("</thead>\n");
|
||||||
builder.append("<tbody>\n");
|
builder.append("<tbody>\n");
|
||||||
|
|
||||||
|
@ -71,9 +73,11 @@ public final class MappingTaglet implements Taglet {
|
||||||
builder.append("<tr>\n");
|
builder.append("<tr>\n");
|
||||||
builder.append(String.format("<td>%s</td>\n", escaped(ans[0])));
|
builder.append(String.format("<td>%s</td>\n", escaped(ans[0])));
|
||||||
builder.append(String.format("<td><span class=\"copyable\"><code>%s</code></span></td>\n", escaped(ans[1])));
|
builder.append(String.format("<td><span class=\"copyable\"><code>%s</code></span></td>\n", escaped(ans[1])));
|
||||||
|
|
||||||
if (!typeDecl) {
|
if (!typeDecl) {
|
||||||
builder.append(String.format("<td><span class=\"copyable\"><code>%s</code></span></td>\n", escaped(ans[2])));
|
builder.append(String.format("<td><span class=\"copyable\"><code>%s</code></span></td>\n", escaped(ans[2])));
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append("</tr>\n");
|
builder.append("</tr>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,14 +90,17 @@ public final class MappingTaglet implements Taglet {
|
||||||
private static String escaped(String original) {
|
private static String escaped(String original) {
|
||||||
StringBuilder builder = new StringBuilder(original.length());
|
StringBuilder builder = new StringBuilder(original.length());
|
||||||
final int len = original.length();
|
final int len = original.length();
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
char c = original.charAt(i);
|
char c = original.charAt(i);
|
||||||
|
|
||||||
if (c > 127 || c == '"' || c == '\'' || c == '<' || c == '>' || c == '&') {
|
if (c > 127 || c == '"' || c == '\'' || c == '<' || c == '>' || c == '&') {
|
||||||
builder.append("&#").append((int) c).append(";");
|
builder.append("&#").append((int) c).append(";");
|
||||||
} else {
|
} else {
|
||||||
builder.append(c);
|
builder.append(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
import java.util.AbstractMap;
|
import java.util.AbstractMap;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
|
@ -31,10 +32,9 @@ import com.squareup.javapoet.TypeName;
|
||||||
import org.objectweb.asm.TypePath;
|
import org.objectweb.asm.TypePath;
|
||||||
import org.objectweb.asm.TypeReference;
|
import org.objectweb.asm.TypeReference;
|
||||||
|
|
||||||
import net.fabricmc.mappingpoet.Signatures;
|
import net.fabricmc.filament.mappingpoet.Signatures;
|
||||||
|
|
||||||
public final class AnnotationAwareDescriptors {
|
public final class AnnotationAwareDescriptors {
|
||||||
|
|
||||||
private AnnotationAwareDescriptors() {
|
private AnnotationAwareDescriptors() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ public final class AnnotationAwareDescriptors {
|
||||||
ClassName superName = parseType(rawSuper, mapping.getBank(TypeReference.newSuperTypeReference(-1)), context);
|
ClassName superName = parseType(rawSuper, mapping.getBank(TypeReference.newSuperTypeReference(-1)), context);
|
||||||
|
|
||||||
List<TypeName> interfaces = new ArrayList<>(rawInterfaces.size());
|
List<TypeName> interfaces = new ArrayList<>(rawInterfaces.size());
|
||||||
|
|
||||||
for (ListIterator<String> itr = rawInterfaces.listIterator(); itr.hasNext(); ) {
|
for (ListIterator<String> itr = rawInterfaces.listIterator(); itr.hasNext(); ) {
|
||||||
int i = itr.nextIndex();
|
int i = itr.nextIndex();
|
||||||
String item = itr.next();
|
String item = itr.next();
|
||||||
|
@ -59,12 +60,14 @@ public final class AnnotationAwareDescriptors {
|
||||||
Deque<List<AnnotationSpec>> arrayAnnotations = new ArrayDeque<>();
|
Deque<List<AnnotationSpec>> arrayAnnotations = new ArrayDeque<>();
|
||||||
int len = desc.length();
|
int len = desc.length();
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
for (index = 0; (index < len) && (desc.charAt(index) == '['); index++) {
|
for (index = 0; (index < len) && (desc.charAt(index) == '['); index++) {
|
||||||
arrayAnnotations.push(bank.getCurrentAnnotations());
|
arrayAnnotations.push(bank.getCurrentAnnotations());
|
||||||
bank = bank.advance(TypePath.ARRAY_ELEMENT, 0);
|
bank = bank.advance(TypePath.ARRAY_ELEMENT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeName current;
|
TypeName current;
|
||||||
|
|
||||||
if (len - index == 1) {
|
if (len - index == 1) {
|
||||||
current = annotate(Signatures.getPrimitive(desc.charAt(index)), bank);
|
current = annotate(Signatures.getPrimitive(desc.charAt(index)), bank);
|
||||||
} else {
|
} else {
|
||||||
|
@ -72,9 +75,11 @@ public final class AnnotationAwareDescriptors {
|
||||||
assert desc.charAt(index) == 'L' && desc.charAt(len - 1) == ';';
|
assert desc.charAt(index) == 'L' && desc.charAt(len - 1) == ';';
|
||||||
current = parseType(desc.substring(index + 1, len - 1), bank, context);
|
current = parseType(desc.substring(index + 1, len - 1), bank, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!arrayAnnotations.isEmpty()) {
|
while (!arrayAnnotations.isEmpty()) {
|
||||||
current = ArrayTypeName.of(current);
|
current = ArrayTypeName.of(current);
|
||||||
List<AnnotationSpec> specs = arrayAnnotations.pop();
|
List<AnnotationSpec> specs = arrayAnnotations.pop();
|
||||||
|
|
||||||
if (!specs.isEmpty()) {
|
if (!specs.isEmpty()) {
|
||||||
current = current.annotated(specs);
|
current = current.annotated(specs);
|
||||||
}
|
}
|
||||||
|
@ -101,10 +106,12 @@ public final class AnnotationAwareDescriptors {
|
||||||
if (internalName.startsWith("L") && internalName.endsWith(";")) {
|
if (internalName.startsWith("L") && internalName.endsWith(";")) {
|
||||||
throw new AssertionError(internalName);
|
throw new AssertionError(internalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int slice = internalName.lastIndexOf('/');
|
int slice = internalName.lastIndexOf('/');
|
||||||
String packageSt = slice < 0 ? "" : internalName.substring(0, slice).replace('/', '.');
|
String packageSt = slice < 0 ? "" : internalName.substring(0, slice).replace('/', '.');
|
||||||
|
|
||||||
int moneySign = internalName.indexOf('$', slice + 1);
|
int moneySign = internalName.indexOf('$', slice + 1);
|
||||||
|
|
||||||
if (moneySign == -1) {
|
if (moneySign == -1) {
|
||||||
return new AbstractMap.SimpleImmutableEntry<>(ClassName.get(packageSt, internalName.substring(slice + 1)), bank);
|
return new AbstractMap.SimpleImmutableEntry<>(ClassName.get(packageSt, internalName.substring(slice + 1)), bank);
|
||||||
}
|
}
|
||||||
|
@ -113,8 +120,10 @@ public final class AnnotationAwareDescriptors {
|
||||||
|
|
||||||
final int len = internalName.length();
|
final int len = internalName.length();
|
||||||
boolean enteredInner = false;
|
boolean enteredInner = false;
|
||||||
|
|
||||||
for (int i = moneySign; i < len; ) {
|
for (int i = moneySign; i < len; ) {
|
||||||
int t = internalName.indexOf('$', i + 1);
|
int t = internalName.indexOf('$', i + 1);
|
||||||
|
|
||||||
if (t < 0) {
|
if (t < 0) {
|
||||||
t = len;
|
t = len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,14 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import org.objectweb.asm.TypeReference;
|
import org.objectweb.asm.TypeReference;
|
||||||
import org.objectweb.asm.signature.SignatureReader;
|
import org.objectweb.asm.signature.SignatureReader;
|
||||||
|
|
||||||
public final class AnnotationAwareSignatures {
|
public final class AnnotationAwareSignatures {
|
||||||
|
|
||||||
private AnnotationAwareSignatures() {
|
private AnnotationAwareSignatures() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -22,6 +23,5 @@ import com.squareup.javapoet.TypeVariableName;
|
||||||
|
|
||||||
// no more a class signature but general super info about class
|
// no more a class signature but general super info about class
|
||||||
public record ClassSignature(List<TypeVariableName> generics, TypeName superclass,
|
public record ClassSignature(List<TypeVariableName> generics, TypeName superclass,
|
||||||
List<TypeName> superinterfaces) {
|
List<TypeName> superinterfaces) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A context to retrieve if a class is an instance inner class. Useful for
|
* A context to retrieve if a class is an instance inner class. Useful for
|
||||||
|
@ -22,7 +23,6 @@ package net.fabricmc.mappingpoet.signature;
|
||||||
* an example in JVM Specification 15.</a>
|
* an example in JVM Specification 15.</a>
|
||||||
*/
|
*/
|
||||||
public interface ClassStaticContext {
|
public interface ClassStaticContext {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if this class is an instance inner class.
|
* Returns if this class is an instance inner class.
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -23,5 +24,4 @@ import com.squareup.javapoet.TypeVariableName;
|
||||||
public record MethodSignature(List<TypeVariableName> generics,
|
public record MethodSignature(List<TypeVariableName> generics,
|
||||||
List<TypeName> parameters, TypeName result,
|
List<TypeName> parameters, TypeName result,
|
||||||
List<TypeName> thrown) {
|
List<TypeName> thrown) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@ -24,7 +25,6 @@ import org.objectweb.asm.TypeReference;
|
||||||
import org.objectweb.asm.signature.SignatureVisitor;
|
import org.objectweb.asm.signature.SignatureVisitor;
|
||||||
|
|
||||||
public final class PoetClassMethodSignatureVisitor extends SignatureVisitor {
|
public final class PoetClassMethodSignatureVisitor extends SignatureVisitor {
|
||||||
|
|
||||||
private final TypeAnnotationMapping mapping;
|
private final TypeAnnotationMapping mapping;
|
||||||
private final ClassStaticContext context;
|
private final ClassStaticContext context;
|
||||||
private final boolean forClass;
|
private final boolean forClass;
|
||||||
|
@ -91,8 +91,8 @@ public final class PoetClassMethodSignatureVisitor extends SignatureVisitor {
|
||||||
private SignatureVisitor visitLowerBound() {
|
private SignatureVisitor visitLowerBound() {
|
||||||
collectLowerBound();
|
collectLowerBound();
|
||||||
|
|
||||||
TypeAnnotationBank bank = mapping.getBank(TypeReference.newTypeParameterBoundReference(forClass ?
|
TypeAnnotationBank bank = mapping.getBank(TypeReference.newTypeParameterBoundReference(forClass
|
||||||
TypeReference.CLASS_TYPE_PARAMETER_BOUND : TypeReference.METHOD_TYPE_PARAMETER_BOUND, generics.size(),
|
? TypeReference.CLASS_TYPE_PARAMETER_BOUND : TypeReference.METHOD_TYPE_PARAMETER_BOUND, generics.size(),
|
||||||
currentGenericBounds.size()));
|
currentGenericBounds.size()));
|
||||||
return pendingLowerBound = new PoetTypeSignatureWriter(bank, context);
|
return pendingLowerBound = new PoetTypeSignatureWriter(bank, context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -29,7 +30,7 @@ import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.TypePath;
|
import org.objectweb.asm.TypePath;
|
||||||
import org.objectweb.asm.signature.SignatureVisitor;
|
import org.objectweb.asm.signature.SignatureVisitor;
|
||||||
|
|
||||||
import net.fabricmc.mappingpoet.Signatures;
|
import net.fabricmc.filament.mappingpoet.Signatures;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type signature to javapoet visitor.
|
* A type signature to javapoet visitor.
|
||||||
|
@ -39,7 +40,6 @@ import net.fabricmc.mappingpoet.Signatures;
|
||||||
* can be defined.</p>
|
* can be defined.</p>
|
||||||
*/
|
*/
|
||||||
public final class PoetTypeSignatureWriter extends SignatureVisitor {
|
public final class PoetTypeSignatureWriter extends SignatureVisitor {
|
||||||
|
|
||||||
private final ClassStaticContext context;
|
private final ClassStaticContext context;
|
||||||
private final ArrayList<TypeName> params = new ArrayList<>();
|
private final ArrayList<TypeName> params = new ArrayList<>();
|
||||||
private /* NonNull */ TypeAnnotationBank storage; // mutable
|
private /* NonNull */ TypeAnnotationBank storage; // mutable
|
||||||
|
@ -132,6 +132,7 @@ public final class PoetTypeSignatureWriter extends SignatureVisitor {
|
||||||
} else {
|
} else {
|
||||||
currentType = ((ClassName) currentType).nestedClass(nestedClassName);
|
currentType = ((ClassName) currentType).nestedClass(nestedClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
nestedClassName = null;
|
nestedClassName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,10 +151,10 @@ public final class PoetTypeSignatureWriter extends SignatureVisitor {
|
||||||
if (activeTypeArgument != null) {
|
if (activeTypeArgument != null) {
|
||||||
TypeName hold = activeTypeArgument.compute();
|
TypeName hold = activeTypeArgument.compute();
|
||||||
TypeName used = switch (activeTypeArgumentKind) {
|
TypeName used = switch (activeTypeArgumentKind) {
|
||||||
case SignatureVisitor.EXTENDS -> WildcardTypeName.subtypeOf(hold);
|
case SignatureVisitor.EXTENDS -> WildcardTypeName.subtypeOf(hold);
|
||||||
case SignatureVisitor.SUPER -> WildcardTypeName.supertypeOf(hold);
|
case SignatureVisitor.SUPER -> WildcardTypeName.supertypeOf(hold);
|
||||||
case SignatureVisitor.INSTANCEOF -> hold;
|
case SignatureVisitor.INSTANCEOF -> hold;
|
||||||
default -> throw new IllegalStateException(String.format("Illegal type argument wildcard %s", activeTypeArgumentKind));
|
default -> throw new IllegalStateException(String.format("Illegal type argument wildcard %s", activeTypeArgumentKind));
|
||||||
};
|
};
|
||||||
|
|
||||||
used = AnnotationAwareDescriptors.annotate(used, storage.advance(TypePath.TYPE_ARGUMENT, params.size()));
|
used = AnnotationAwareDescriptors.annotate(used, storage.advance(TypePath.TYPE_ARGUMENT, params.size()));
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
import org.objectweb.asm.TypeReference;
|
import org.objectweb.asm.TypeReference;
|
||||||
|
|
||||||
|
@ -21,7 +22,6 @@ import org.objectweb.asm.TypeReference;
|
||||||
* The collection of type annotations from a bytecode structure that stores type annotations.
|
* The collection of type annotations from a bytecode structure that stores type annotations.
|
||||||
*/
|
*/
|
||||||
public interface TypeAnnotationMapping {
|
public interface TypeAnnotationMapping {
|
||||||
|
|
||||||
TypeAnnotationMapping EMPTY = reference -> TypeAnnotationBank.EMPTY;
|
TypeAnnotationMapping EMPTY = reference -> TypeAnnotationBank.EMPTY;
|
||||||
|
|
||||||
// implNote: TypeReference is not a pojo! No equals or hash!
|
// implNote: TypeReference is not a pojo! No equals or hash!
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package net.fabricmc.mappingpoet.signature;
|
|
||||||
|
package net.fabricmc.filament.mappingpoet.signature;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -25,10 +26,9 @@ import org.objectweb.asm.TypePath;
|
||||||
import org.objectweb.asm.TypeReference;
|
import org.objectweb.asm.TypeReference;
|
||||||
import org.objectweb.asm.tree.TypeAnnotationNode;
|
import org.objectweb.asm.tree.TypeAnnotationNode;
|
||||||
|
|
||||||
import net.fabricmc.mappingpoet.FieldBuilder;
|
import net.fabricmc.filament.mappingpoet.FieldBuilder;
|
||||||
|
|
||||||
public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeAnnotationBank {
|
public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeAnnotationBank {
|
||||||
|
|
||||||
private final int[] targets; // target type and info, only exist in mapping version
|
private final int[] targets; // target type and info, only exist in mapping version
|
||||||
private final String[] paths;
|
private final String[] paths;
|
||||||
private final AnnotationSpec[] contents;
|
private final AnnotationSpec[] contents;
|
||||||
|
@ -51,15 +51,18 @@ public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeA
|
||||||
|
|
||||||
static int comparePath(TypePath left, TypePath right) {
|
static int comparePath(TypePath left, TypePath right) {
|
||||||
int len = Math.min(left.getLength(), right.getLength());
|
int len = Math.min(left.getLength(), right.getLength());
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
int leftStep = left.getStep(i);
|
int leftStep = left.getStep(i);
|
||||||
int rightStep = right.getStep(i);
|
int rightStep = right.getStep(i);
|
||||||
|
|
||||||
if (leftStep != rightStep) {
|
if (leftStep != rightStep) {
|
||||||
return Integer.compare(leftStep, rightStep);
|
return Integer.compare(leftStep, rightStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
int leftStepArg = left.getStepArgument(i);
|
int leftStepArg = left.getStepArgument(i);
|
||||||
int rightStepArg = right.getStepArgument(i);
|
int rightStepArg = right.getStepArgument(i);
|
||||||
|
|
||||||
if (leftStepArg != rightStepArg) {
|
if (leftStepArg != rightStepArg) {
|
||||||
return Integer.compare(leftStepArg, rightStepArg);
|
return Integer.compare(leftStepArg, rightStepArg);
|
||||||
}
|
}
|
||||||
|
@ -97,14 +100,15 @@ public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeA
|
||||||
|
|
||||||
String hiCheck = check.substring(0, check.length() - 1).concat(Character.toString((char) (check.charAt(check.length() - 1) + 1)));
|
String hiCheck = check.substring(0, check.length() - 1).concat(Character.toString((char) (check.charAt(check.length() - 1) + 1)));
|
||||||
|
|
||||||
|
|
||||||
int low = Arrays.binarySearch(paths, startIndex, endIndex, check);
|
int low = Arrays.binarySearch(paths, startIndex, endIndex, check);
|
||||||
|
|
||||||
if (low < 0) {
|
if (low < 0) {
|
||||||
low = -(low + 1);
|
low = -(low + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// exclusive hi
|
// exclusive hi
|
||||||
int hi = Arrays.binarySearch(paths, startIndex, endIndex, hiCheck);
|
int hi = Arrays.binarySearch(paths, startIndex, endIndex, hiCheck);
|
||||||
|
|
||||||
if (hi < 0) {
|
if (hi < 0) {
|
||||||
hi = -(hi + 1);
|
hi = -(hi + 1);
|
||||||
}
|
}
|
||||||
|
@ -119,6 +123,7 @@ public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeA
|
||||||
}
|
}
|
||||||
|
|
||||||
int hi = Arrays.binarySearch(paths, startIndex, endIndex, currentPath + '\u0000');
|
int hi = Arrays.binarySearch(paths, startIndex, endIndex, currentPath + '\u0000');
|
||||||
|
|
||||||
if (hi < 0) {
|
if (hi < 0) {
|
||||||
hi = -(hi + 1);
|
hi = -(hi + 1);
|
||||||
}
|
}
|
||||||
|
@ -140,12 +145,14 @@ public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeA
|
||||||
int target = reference.getValue();
|
int target = reference.getValue();
|
||||||
// inclusive low
|
// inclusive low
|
||||||
int low = Arrays.binarySearch(targets, startIndex, endIndex, target);
|
int low = Arrays.binarySearch(targets, startIndex, endIndex, target);
|
||||||
|
|
||||||
if (low < 0) {
|
if (low < 0) {
|
||||||
low = -(low + 1);
|
low = -(low + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// exclusive hi
|
// exclusive hi
|
||||||
int hi = Arrays.binarySearch(targets, startIndex, endIndex, target + 1);
|
int hi = Arrays.binarySearch(targets, startIndex, endIndex, target + 1);
|
||||||
|
|
||||||
if (hi < 0) {
|
if (hi < 0) {
|
||||||
hi = -(hi + 1);
|
hi = -(hi + 1);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +161,6 @@ public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeA
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
final List<Entry> entries = new ArrayList<>();
|
final List<Entry> entries = new ArrayList<>();
|
||||||
|
|
||||||
Builder() {
|
Builder() {
|
||||||
|
@ -169,9 +175,11 @@ public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeA
|
||||||
if (nodes == null) {
|
if (nodes == null) {
|
||||||
return this; // thanks asm
|
return this; // thanks asm
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TypeAnnotationNode node : nodes) {
|
for (TypeAnnotationNode node : nodes) {
|
||||||
entries.add(new Entry(node.typeRef, node.typePath == null ? "" : node.typePath.toString(), FieldBuilder.parseAnnotation(node)));
|
entries.add(new Entry(node.typeRef, node.typePath == null ? "" : node.typePath.toString(), FieldBuilder.parseAnnotation(node)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +192,7 @@ public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeA
|
||||||
AnnotationSpec[] contents = new AnnotationSpec[len];
|
AnnotationSpec[] contents = new AnnotationSpec[len];
|
||||||
|
|
||||||
Iterator<Entry> itr = this.entries.iterator();
|
Iterator<Entry> itr = this.entries.iterator();
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
Entry entry = itr.next();
|
Entry entry = itr.next();
|
||||||
targets[i] = entry.target;
|
targets[i] = entry.target;
|
||||||
|
@ -212,6 +221,5 @@ public final class TypeAnnotationStorage implements TypeAnnotationMapping, TypeA
|
||||||
return path.compareTo(o.path);
|
return path.compareTo(o.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue