/** * Reads the next {@link BaseType} from source. * * @return The type * @throws IllegalStateException If the descriptor is invalid */ public BaseType readBaseType() { return BaseType.getFromKey(this.advance()); }
/** * Reads the next {@link ArrayType} from source. * * @return The type * @throws IllegalStateException If the descriptor is invalid */ public ArrayType readArrayType() { int count = 0; while (this.hasNext() && this.peek() == '[') { this.advance(); count++; } return new ArrayType(count, this.readFieldType()); }
/** * Gets the appropriate {@link Type} for the given type. * * @param type The type * @return The type */ static Type of(final String type) { return new TypeReader(type).readType(); }
private static FieldType handleNonePrefix(final FieldType type) { if (type instanceof ArrayType) { final ArrayType arr = (ArrayType) type; return new ArrayType(arr.getDimCount(), handleNonePrefix(arr.getComponent())); } if (type instanceof ObjectType) { final ObjectType obj = (ObjectType) type; return new ObjectType(handleNonePrefix(obj.getClassName())); } return type; }
/** * Reads the next {@link MethodDescriptor} from source. * * @return The type * @throws IllegalStateException If the descriptor is invalid */ public MethodDescriptor read() { final List<FieldType> params = new ArrayList<>(); if (this.peek() != '(') throw new IllegalStateException("Invalid descriptor provided!"); this.advance(); while (this.hasNext() && this.peek() != ')') { params.add(this.readFieldType()); } if (this.peek() != ')') throw new IllegalStateException("Invalid descriptor provided!"); this.advance(); return new MethodDescriptor(params, this.readType()); }
/** * Reads the next {@link FieldType} from source. * * @return The type * @throws IllegalStateException If the descriptor is invalid */ public FieldType readFieldType() { // Array Type if (this.peek() == '[') { return this.readArrayType(); } // Base Type if (BaseType.isValidBase(this.peek())) { return this.readBaseType(); } // Object Type if (this.peek() == 'L') { return this.readObjectType(); } throw new IllegalStateException("Invalid descriptor provided!"); }
/** * Reads the next {@link ObjectType} from source. * * @return The type * @throws IllegalStateException If the descriptor is invalid */ public ObjectType readObjectType() { final int start = this.current; this.advance(); while (this.hasNext() && this.peek() != ';') { this.advance(); } if (this.peek() != ';') throw new IllegalStateException("Incomplete descriptor provided!"); this.advance(); return new ObjectType(this.source.substring(start + 1, this.current - 1)); }
/** * Creates a new field signature with the given name and * decoded type descriptor. * * @param name The name of the field * @param type The raw type of the field * @return The new field signature */ public static FieldSignature of(String name, String type) { return new FieldSignature(name, FieldType.of(type)); }
/** * Reads the next {@link PrimitiveType} from source. * * @return The type * @throws IllegalStateException If the descriptor is invalid */ public PrimitiveType readPrimitiveType() { // Void Type if (this.peek() == 'V') { this.advance(); return VoidType.INSTANCE; } // Base Type if (BaseType.isValidBase(this.peek())) { return this.readBaseType(); } throw new IllegalStateException("Invalid descriptor provided!"); }
/** * Gets the de-obfuscated raw view of the type. * * @param type The type to de-obfuscate * @return The de-obfuscated raw view * @since 0.4.0 */ default String deobfuscate(final Type type) { if (type instanceof ArrayType) { final ArrayType arr = (ArrayType) type; return arr.getDims() + this.deobfuscate(arr.getComponent()); } else if (type instanceof ObjectType) { final ObjectType obj = (ObjectType) type; final Optional<? extends ClassMapping<?>> typeMapping = this.getClassMapping(obj.getClassName()); return "L" + typeMapping.map(Mapping::getFullDeobfuscatedName).orElse(obj.getClassName()) + ";"; } return type.toString(); }
/** * Reads the next {@link Type} from source. * * @return The type * @throws IllegalStateException If the descriptor is invalid */ public Type readType() { // Void Type if (this.peek() == 'V') { this.advance(); return VoidType.INSTANCE; } // Field Type return this.readFieldType(); }
/** * Creates a method signature, with the given method name and raw descriptor. * * @param name The method name * @param descriptor The method's raw descriptor * @return The new method signature */ public static MethodSignature of(final String name, final String descriptor) { return new MethodSignature(name, MethodDescriptor.of(descriptor)); }
/** * Compiles a {@link MethodDescriptor} for the given raw descriptor. * * @param descriptor The raw method descriptor * @return The descriptor */ public static MethodDescriptor of(final String descriptor) { return new MethodDescriptorReader(descriptor).read(); }
/** * Gets the appropriate {@link FieldType} for the given type. * * @param type The field type * @return The field type */ static FieldType of(final String type) { return new TypeReader(type).readFieldType(); }
/** * Gets the appropriate {@link Type} for the given class. * * @param klass The class * @return The type */ static Type of(final Class<?> klass) { if (klass.isPrimitive() && klass == Void.TYPE) { return VoidType.INSTANCE; } return FieldType.of(klass); }
/** * Gets the {@link PrimitiveType} for the given type key. * * @param key The type key * @return The primitive type * @throws IllegalStateException If the descriptor is invalid */ static PrimitiveType getFromKey(char key) { if (key == 'V') { return VoidType.INSTANCE; } if (BaseType.isValidBase(key)) { return BaseType.getFromKey(key); } throw new IllegalStateException("Invalid primitive type: " + key); }
/** * Establishes whether the given key, is a valid base * key. * * @param key The key * @return {@code true} if the key represents a base type; * {@code false} otherwise */ public static boolean isValidBase(final char key) { return Arrays.stream(values()) .anyMatch(type -> type.key == key); }
/** * Gets the obfuscated descriptor of the method. * * @return The obfuscated descriptor * @see MethodSignature#getDescriptor() * @see MethodDescriptor#toString() */ default String getObfuscatedDescriptor() { return this.getDescriptor().toString(); }
private static FieldType handleNonePrefix(final FieldType type) { if (type instanceof ArrayType) { final ArrayType arr = (ArrayType) type; return new ArrayType(arr.getDimCount(), handleNonePrefix(arr.getComponent())); } if (type instanceof ObjectType) { final ObjectType obj = (ObjectType) type; return new ObjectType(handleNonePrefix(obj.getClassName())); } return type; }
/** * Gets, or creates should it not exist, a field mapping of the * given signature. * * @param obfuscatedName The obfuscated name of the field mapping * @param obfuscatedDescriptor The obfuscated descriptor of the field mapping * @return The field mapping * @since 0.4.0 */ default FieldMapping getOrCreateFieldMapping(final String obfuscatedName, final String obfuscatedDescriptor) { return this.getOrCreateFieldMapping(new FieldSignature(obfuscatedName, FieldType.of(obfuscatedDescriptor))); }