static { List<String> names = new ArrayList<String>(); for (Method method : GroovyObject.class.getMethods()) { names.add(method.getName()); } GROOVYOBJECT_METHOD_NAMESS = new HashSet<String>(names); }
private void replaceObfuscatedMethodNames(AsmagicDiffVisitor dv) { for (MethodNode mn : dv.newMethods) { if (mn.visibleAnnotations != null) { for (Object oan : mn.visibleAnnotations) { AnnotationNode an = (AnnotationNode) oan; if (an.desc.contains("AsmagicMethodReplace")) { List<Object> vals = an.values; String alias = null; if (vals != null || vals.size() > 1) { alias = (String) vals.get(1); dv.methodsToReplace.put(alias, 1); mn.name = alias; } } } } } }
/** * It is assumed that ALL CLASSES regardless of nesting, have unique names In addition, it is * assumed that there is not multi-level nesting A SOURCE STRUCTURE OBJECT CAN ONLY HANDLE ONE * LEVEL OF CLASS NESTING * * @param targetClass * @param depth * @throws IOException */ private void findNestedInnerClasses(ClassNode2 targetClass, int depth) throws IOException { // saves the depth of a particular inner class depth++; // get the inner classes of a class List<InnerClassNode2> innerClassNodes = targetClass.innerClasses; // returns if there are no inner classes if (innerClassNodes == null) { return; } else { // if there are inner classes, each inner class is converted to a ClassStructure // object and stored in an ArrayList for (int i = 0; i < innerClassNodes.size(); i++) { classStructures.add(new ClassStructure(innerClassNodes.get(i).name, depth)); } } }
/** * constructor allowing this transformer to be provided with access to the JVM's instrumentation * implementation * * @param inst the instrumentation object used to interface to the JVM * @param scriptPaths list of file paths for each input script * @param scriptTexts the text of each input script * @param isRedefine true if class redefinition is allowed false if not * @throws Exception if a script is in error */ public Transformer( Instrumentation inst, List<String> scriptPaths, List<String> scriptTexts, boolean isRedefine) throws Exception { this.inst = inst; this.isRedefine = isRedefine; scriptRepository = new ScriptRepository(skipOverrideRules); loadCache = new LoadCache(inst); helperManager = new HelperManager(inst); Iterator<String> scriptsIter = scriptTexts.iterator(); Iterator<String> filesIter = scriptPaths.iterator(); while (scriptsIter.hasNext()) { String scriptText = scriptsIter.next(); String file = filesIter.next(); List<RuleScript> ruleScripts = scriptRepository.processScripts(scriptText, file); for (RuleScript ruleScript : ruleScripts) { String name = ruleScript.getName(); RuleScript previous = scriptRepository.scriptForRuleName(name); if (previous == null) { scriptRepository.addScript(ruleScript); } else { StringBuffer buffer = new StringBuffer(); buffer.append("Transformer : duplicate script name "); buffer.append(name); buffer.append("in file "); buffer.append(ruleScript.getFile()); buffer.append(" line "); buffer.append(ruleScript.getLine()); buffer.append("\n previously defined in file "); buffer.append(previous.getFile()); buffer.append(" line "); buffer.append(previous.getLine()); Exception ex = new Exception(buffer.toString()); throw ex; } } } }
private static List<Method> getInheritedMethods(Class baseClass, List<Method> methods) { Collections.addAll(methods, baseClass.getMethods()); Class currentClass = baseClass; while (currentClass != null) { Method[] protectedMethods = currentClass.getDeclaredMethods(); for (Method method : protectedMethods) { if (method.getName().indexOf('$') != -1) continue; if (Modifier.isProtected(method.getModifiers()) && !containsEquivalentMethod(methods, method)) methods.add(method); } currentClass = currentClass.getSuperclass(); } return methods; }
/** * Construct a proxy generator. This generator is used when we need to create a proxy object for a * class or an interface given a map of closures. * * @param closureMap the delegates implementations * @param superClass corresponding to the superclass class visitor * @param interfaces extra interfaces the proxy should implement * @param proxyLoader the class loader which should be used to load the generated proxy * @param delegateClass if not null, generate a delegate field with the corresponding class * @param emptyBody if set to true, the unimplemented abstract methods will receive an empty body * instead of throwing an {@link UnsupportedOperationException}. */ public ProxyGeneratorAdapter( final Map<Object, Object> closureMap, final Class superClass, final Class[] interfaces, final ClassLoader proxyLoader, final boolean emptyBody, final Class delegateClass) { super(new ClassWriter(0)); this.visitedMethods = new LinkedHashSet<Object>(); this.delegatedClosures = closureMap.isEmpty() ? EMPTY_DELEGATECLOSURE_MAP : new HashMap<String, Boolean>(); boolean wildcard = false; for (Map.Entry<Object, Object> entry : closureMap.entrySet()) { String name = entry.getKey().toString(); if ("*".equals(name)) { wildcard = true; } this.delegatedClosures.put(name, Boolean.FALSE); } this.hasWildcard = wildcard; // if we have to delegate to another object, generate the appropriate delegate field // and collect the name of the methods for which delegation is active this.generateDelegateField = delegateClass != null; this.objectDelegateMethods = generateDelegateField ? createDelegateMethodList(delegateClass, interfaces) : EMPTY_STRING_SET; this.delegateClass = delegateClass; // a proxy is supposed to be a concrete class, so it cannot extend an interface. // If the provided superclass is an interface, then we replace the superclass with Object // and add this interface to the list of implemented interfaces boolean isSuperClassAnInterface = superClass.isInterface(); this.superClass = isSuperClassAnInterface ? Object.class : superClass; // create the base list of classes which have possible methods to be overloaded this.classList = new LinkedList<Class>(); this.classList.add(superClass); if (generateDelegateField) { classList.add(delegateClass); } if (interfaces != null) { Collections.addAll(this.classList, interfaces); } this.proxyName = proxyName(); this.loader = proxyLoader != null ? new InnerLoader(proxyLoader) : findClassLoader(superClass); this.emptyBody = emptyBody; // generate bytecode ClassWriter writer = (ClassWriter) cv; ClassReader cr = createClassVisitor(Object.class); cr.accept(this, 0); byte[] b = writer.toByteArray(); // CheckClassAdapter.verify(new ClassReader(b), true, new PrintWriter(System.err)); cachedClass = loader.defineClass(proxyName.replace('/', '.'), b); // cache no-arg constructor Class[] args = generateDelegateField ? new Class[] {Map.class, delegateClass} : new Class[] {Map.class}; Constructor constructor; try { constructor = cachedClass.getConstructor(args); } catch (NoSuchMethodException e) { constructor = null; } cachedNoArgConstructor = constructor; }