/** * Get a {@link ConstructorRef} to the specified constructor. Typical use: * <p> * <pre> constructor("java.util.ArrayList", int.class).newInstance(32) </pre> * * @param fqn The qualified name of the class to construct * @param params A list of parameter types for the constructor * * @return A reference to the constructor or null if not found */ public static ConstructorRef constructor( String fqn, Class<?>... params ) { return constructor( type( fqn ), params ); }
private static MethodRef matchFirstMethod( Class<?> cls, String name, Class[] params ) { if( name.indexOf( '|' ) >= 0 ) { for( StringTokenizer tokenizer = new StringTokenizer( name, "|" ); tokenizer.hasMoreTokens(); ) { String token = tokenizer.nextToken(); MethodRef method = method( cls, token, params ); if( method != null ) { return method; } } } return null; }
private static Class defineClass( ClassLoader cl, String fqn ) throws IOException { InputStream stream = cl.getResourceAsStream( fqn ); byte[] bytes = StreamUtil.getContent( stream ); ClassLoader parent = (ClassLoader)Array.get( ReflectUtil.field( cl, "myParents" ).get(), 0 ); return (Class)ReflectUtil.method( parent, "defineClass", byte[].class, int.class, int.class ).invoke( bytes, 0, bytes.length ); }
/** * Get a {@link FieldRef} to the specified field. Typical use: * <p> * <pre> field("java.time.LocalTime", "hour").get(); </pre> * * @param fqn The qualified name of the class having the field * @param name The name of the field or a '|' separated list of names, where the first found is used * * @return A reference to the specified field or null if not found */ public static FieldRef field( String fqn, String name ) { return field( type( fqn ), name ); }
/** * Get a {@link MethodRef} to the specified method. Typical use: * <p> * <pre> method("java.time.LocalTime", "of", int.class, int.class).invokeStatic(5, 30) </pre> * * @param fqn The qualified name of the class containing the method * @param name The name of the method or a '|' separated list of names, where the first found is used * @param params The types of the method's parameters * * @return A reference to the specified method or null if not found */ public static MethodRef method( String fqn, String name, Class... params ) { return method( type( fqn ), name, params ); }
private void wrapReaders() { Map/*<ModuleReference, ModuleReader>*/ moduleToReader = (Map)ReflectUtil.field( _loader, "moduleToReader" ).get(); for( Object mr: moduleToReader.keySet() ) { //noinspection unchecked Optional<URI> location = (Optional<URI>)ReflectUtil.method( mr, "location" ).invoke(); URI uri = location.orElse( null ); if( uri == null ) { continue; } //## note: "jmod" files are not supported here because they are currently (2018) supported exclusively at compiler/linker time String scheme = uri.getScheme(); if( scheme.equalsIgnoreCase( "file" ) || scheme.equalsIgnoreCase( "jar" ) ) { Object reader = moduleToReader.get( mr ); Class<?> moduleReaderClass = ReflectUtil.type( "java.lang.module.ModuleReader" ); ManModuleReader wrapper = new ManModuleReader( reader, ReflectUtil.field( _loader, "ucp" ).get() ); Object/*ModuleReader*/ proxy = Proxy.newProxyInstance( moduleReaderClass.getClassLoader(), new Class<?>[]{moduleReaderClass}, new ManModuleReaderInvocationHandler( wrapper ) ); //noinspection unchecked moduleToReader.put( mr, proxy ); } } }
Symbol moduleToOpen = (Symbol)ReflectUtil.method( Symtab.instance( context ), "getModule", Name.class ) .invoke( Names.instance( context ).fromString( moduleName ) ); Set<Symbol> rootModules = (Set<Symbol>)ReflectUtil.field( ReflectUtil.method( ReflectUtil.type( "com.sun.tools.javac.comp.Modules" ), "instance", Context.class ).invokeStatic( context ), "allModules" ).get(); List<Object> requires = (List<Object>)ReflectUtil.field( rootModule, "requires" ).get(); List<Object> newRequires = new ArrayList( requires ); Object addedRequires = ReflectUtil.constructor( "com.sun.tools.javac.code.Directive$RequiresDirective", ReflectUtil.type( "com.sun.tools.javac.code.Symbol$ModuleSymbol" ) ).newInstance( moduleToOpen ); newRequires.add( addedRequires ); requires = com.sun.tools.javac.util.List.from( newRequires ); ReflectUtil.field( rootModule, "requires" ).set( requires ); List<Object> exports = new ArrayList<>( (Collection)ReflectUtil.field( moduleToOpen, "exports" ).get() ); for( Symbol pkg : (Iterable<Symbol>)ReflectUtil.field( moduleToOpen, "enclosedPackages" ).get() ) Object exp = ReflectUtil.constructor( "com.sun.tools.javac.code.Directive$ExportsDirective", Symbol.PackageSymbol.class, com.sun.tools.javac.util.List.class ).newInstance( pkg, com.sun.tools.javac.util.List.of( rootModule ) ); exports.add( exp ); ((Map)ReflectUtil.field( rootModule, "visiblePackages" ).get()).put( ((Symbol.PackageSymbol)pkg).fullname, pkg ); ReflectUtil.field( moduleToOpen, "exports" ).set( com.sun.tools.javac.util.List.from( exports ) ); Set readModules = (Set)ReflectUtil.field( moduleToOpen, "readModules" ).get(); readModules.add( rootModule ); ReflectUtil.field( moduleToOpen, "readModules" ).set( readModules );
public static Object getFieldStatic_Object( Class receiver, String name ) { //noinspection ConstantConditions return ReflectUtil.field( receiver, name ).getStatic(); }
private TypeAnnotationPosition getTypeAnnotationPosition( List<TypeAnnotationPosition.TypePathEntry> attrLocationCopy ) { TypeAnnotationPosition posCopy; //noinspection ConstantConditions if( isJava8() ) { posCopy = (TypeAnnotationPosition)ReflectUtil.constructor( "com.sun.tools.javac.code.TypeAnnotationPosition" ).newInstance(); ReflectUtil.field( posCopy, "location" ).set( attrLocationCopy ); } else { posCopy = (TypeAnnotationPosition)ReflectUtil .method( TypeAnnotationPosition.class, "methodReceiver", List.class ).invokeStatic( attrLocationCopy ); } return posCopy; }
public static Object construct( Class type, Class[] paramTypes, Object[] args ) { //noinspection ConstantConditions return ReflectUtil.constructor( type, paramTypes ).newInstance( args ); } }
return ReflectUtil.method( iface, "proxy", Bindings.class ).invokeStatic( root ); ReflectUtil.setAccessible( proxyClassCtor ); return proxyClassCtor.newInstance( root );
MethodRef match = matchFirstMethod( cls, name, params ); if( match != null ) MethodRef mr = getMethodFromCache( cls, name, params ); if( mr != null ) return addMethodToCache( cls, method ); if( superclass != null ) mr = method( superclass, name, params ); if( mr != null ) mr = method( iface, name, params ); if( mr != null ) addMethodToCache( cls, mr._method ); return mr;
ConstructorRef mr = getConstructorFromCache( cls, params ); if( mr != null ) return addConstructorToCache( cls, constructor ); if( superclass != null ) mr = constructor( superclass, params ); if( mr != null ) mr = constructor( iface, params ); if( mr != null ) addConstructorToCache( cls, mr._constructor ); return mr;
FieldRef match = matchFirstField( cls, name ); if( match != null ) FieldRef fr = getFieldFromCache( cls, name ); if( fr != null ) return addFieldToCache( cls, field ); if( superclass != null ) fr = field( superclass, name ); if( fr != null ) addFieldToCache( cls, fr._field ); return fr; fr = field( iface, name ); if( fr != null ) addFieldToCache( cls, fr._field ); return fr;
private static FieldRef addFieldToCache( Class cls, Field f ) { setAccessible( f ); addRawFieldToCache( cls, f ); return new FieldRef( f ); }
private static MethodRef addMethodToCache( Class cls, Method m ) { setAccessible( m ); addRawMethodToCache( cls, m ); return new MethodRef( m ); }
private static ConstructorRef addConstructorToCache( Class cls, Constructor m ) { setAccessible( m ); addRawConstructorToCache( cls, m ); return new ConstructorRef( m ); }
/** * Searches the class loader of this class for the specified name, if not found searches * the current thread's context class loader. * * @param fqn The qualified name of the type e.g., {@code "java.lang.String"} * * @return The {@code Class} corresponding with {@code fqn} or null if not found */ public static Class<?> type( String fqn ) { try { //openPackage( fqn, null ); return Class.forName( fqn ); } catch( ClassNotFoundException e ) { return type( fqn, Thread.currentThread().getContextClassLoader() ); } }
public static void setAccessible( Constructor c ) { try { c.setAccessible( true ); } catch( Exception e ) { setAccessible( (Member)c ); } }
private void reassignEarlyHolders( Context context ) { ReflectUtil.field( _attr, "rs" ).set( this ); ReflectUtil.field( DeferredAttr.instance( context ), "rs" ).set( this ); ReflectUtil.field( Check.instance( context ), "rs" ).set( this ); ReflectUtil.field( Infer.instance( context ), "rs" ).set( this ); ReflectUtil.field( Flow.instance( context ), "rs" ).set( this ); ReflectUtil.field( LambdaToMethod.instance( context ), "rs" ).set( this ); ReflectUtil.field( Lower.instance( context ), "rs" ).set( this ); ReflectUtil.field( Gen.instance( context ), "rs" ).set( this ); ReflectUtil.field( ReflectUtil.method( ReflectUtil.type( "com.sun.tools.javac.jvm.StringConcat" ), "instance", Context.class ) .invokeStatic( context ), "rs" ) .set( this ); ReflectUtil.field( JavacTrees.instance( context ), "resolve" ).set( this ); ReflectUtil.field( Annotate.instance( context ), "resolve" ).set( this ); ReflectUtil.field( TransTypes.instance( context ), "resolve" ).set( this ); ReflectUtil.field( JavacElements.instance( context ), "resolve" ).set( this ); }