private List<Instruction> transformInvoke(InvokeInstruction insn) { if (insn.getType() != InvocationType.VIRTUAL) { return null; } MethodReference method = insn.getMethod(); if (method.getClassName().equals(ResourceArray.class.getName()) || method.getClassName().equals(ResourceMap.class.getName())) { if (method.getName().equals("keys")) { return transformKeys(insn); } InvokeInstruction accessInsn = new InvokeInstruction(); accessInsn.setType(InvocationType.SPECIAL); ValueType[] types = new ValueType[method.getDescriptor().parameterCount() + 2]; types[0] = ValueType.object("java.lang.Object"); System.arraycopy( method.getDescriptor().getSignature(), 0, types, 1, method.getDescriptor().parameterCount() + 1); accessInsn.setMethod( new MethodReference(ResourceAccessor.class.getName(), method.getName(), types)); accessInsn.getArguments().add(insn.getInstance()); accessInsn.getArguments().addAll(insn.getArguments()); accessInsn.setReceiver(insn.getReceiver()); return Arrays.asList(accessInsn); } ClassReader iface = innerSource.get(method.getClassName()); if (iface == null || !innerSource.isSuperType(Resource.class.getName(), iface.getName()).orElse(false)) { return null; } if (method.getName().startsWith("get")) { if (method.getName().length() > 3) { return transformGetterInvocation(insn, getPropertyName(method.getName().substring(3))); } } else if (method.getName().startsWith("is")) { if (method.getName().length() > 2) { return transformGetterInvocation(insn, getPropertyName(method.getName().substring(2))); } } else if (method.getName().startsWith("set")) { if (method.getName().length() > 3) { return transformSetterInvocation(insn, getPropertyName(method.getName().substring(3))); } } return null; }
@Override public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { ClassReader cls = context.getClassSource().get(methodRef.getClassName()); MethodReader method = cls.getMethod(methodRef.getDescriptor()); AnnotationReader providerAnnot = method.getAnnotations().get(MetadataProvider.class.getName()); AnnotationReader refAnnot = method.getAnnotations().get(MetadataProviderRef.class.getName()); methodRef = MethodReference.parse(refAnnot.getValue("value").getString()); // Find and instantiate metadata generator ValueType generatorType = providerAnnot.getValue("value").getJavaClass(); String generatorClassName = ((ValueType.Object) generatorType).getClassName(); Class<?> generatorClass; try { generatorClass = Class.forName(generatorClassName, true, context.getClassLoader()); } catch (ClassNotFoundException e) { context .getDiagnostics() .error( new CallLocation(methodRef), "Can't find metadata provider class {{c0}}", generatorClassName); return; } Constructor<?> cons; try { cons = generatorClass.getConstructor(); } catch (NoSuchMethodException e) { context .getDiagnostics() .error( new CallLocation(methodRef), "Metadata generator {{c0}} does not have " + "a public no-arg constructor", generatorClassName); return; } MetadataGenerator generator; try { generator = (MetadataGenerator) cons.newInstance(); } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { context .getDiagnostics() .error( new CallLocation(methodRef), "Error instantiating metadata " + "generator {{c0}}", generatorClassName); return; } DefaultMetadataGeneratorContext metadataContext = new DefaultMetadataGeneratorContext( context.getClassSource(), context.getClassLoader(), context.getProperties(), context); // Generate resource loader Resource resource = generator.generateMetadata(metadataContext, methodRef); writer.append("return "); ResourceWriterHelper.write(writer, resource); writer.append(';').softNewLine(); }
public static MethodHandle interfaceCaller(MethodReference method) { return interfaceCaller(method.getClassName(), method.getDescriptor()); }
public static MethodHandle constructorCaller(MethodReference method) { return constructorCaller(method.getClassName(), method.getDescriptor()); }
public static MethodHandle specialCaller(MethodReference method) { return specialCaller(method.getClassName(), method.getDescriptor()); }