protected Class createClass(byte[] code, ClassNode classNode) { BytecodeProcessor bytecodePostprocessor = unit.getConfiguration().getBytecodePostprocessor(); byte[] fcode = code; if (bytecodePostprocessor != null) { fcode = bytecodePostprocessor.processBytecode(classNode.getName(), fcode); } GroovyClassLoader cl = getDefiningClassLoader(); Class theClass = cl.defineClass( classNode.getName(), fcode, 0, fcode.length, unit.getAST().getCodeSource()); this.loadedClasses.add(theClass); if (generatedClass == null) { ModuleNode mn = classNode.getModule(); SourceUnit msu = null; if (mn != null) msu = mn.getContext(); ClassNode main = null; if (mn != null) main = (ClassNode) mn.getClasses().get(0); if (msu == su && main == classNode) generatedClass = theClass; } return theClass; }
private static void doAddGlobalTransforms( ASTTransformationsContext context, boolean isFirstScan) { final CompilationUnit compilationUnit = context.getCompilationUnit(); GroovyClassLoader transformLoader = compilationUnit.getTransformLoader(); Map<String, URL> transformNames = new LinkedHashMap<String, URL>(); try { Enumeration<URL> globalServices = transformLoader.getResources( "META-INF/services/org.codehaus.groovy.transform.ASTTransformation"); while (globalServices.hasMoreElements()) { URL service = globalServices.nextElement(); String className; BufferedReader svcIn = null; try { svcIn = new BufferedReader(new InputStreamReader(service.openStream())); try { className = svcIn.readLine(); } catch (IOException ioe) { compilationUnit .getErrorCollector() .addError( new SimpleMessage( "IOException reading the service definition at " + service.toExternalForm() + " because of exception " + ioe.toString(), null)); continue; } Set<String> disabledGlobalTransforms = compilationUnit.getConfiguration().getDisabledGlobalASTTransformations(); if (disabledGlobalTransforms == null) disabledGlobalTransforms = Collections.emptySet(); while (className != null) { if (!className.startsWith("#") && className.length() > 0) { if (!disabledGlobalTransforms.contains(className)) { if (transformNames.containsKey(className)) { if (!service.equals(transformNames.get(className))) { compilationUnit .getErrorCollector() .addWarning( WarningMessage.POSSIBLE_ERRORS, "The global transform for class " + className + " is defined in both " + transformNames.get(className).toExternalForm() + " and " + service.toExternalForm() + " - the former definition will be used and the latter ignored.", null, null); } } else { transformNames.put(className, service); } } } try { className = svcIn.readLine(); } catch (IOException ioe) { compilationUnit .getErrorCollector() .addError( new SimpleMessage( "IOException reading the service definition at " + service.toExternalForm() + " because of exception " + ioe.toString(), null)); //noinspection UnnecessaryContinue continue; } } } finally { if (svcIn != null) svcIn.close(); } } } catch (IOException e) { // FIXME the warning message will NPE with what I have :( compilationUnit .getErrorCollector() .addError( new SimpleMessage( "IO Exception attempting to load global transforms:" + e.getMessage(), null)); } try { Class.forName("java.lang.annotation.Annotation"); // test for 1.5 JVM } catch (Exception e) { // we failed, notify the user StringBuffer sb = new StringBuffer(); sb.append("Global ASTTransformations are not enabled in retro builds of groovy.\n"); sb.append("The following transformations will be ignored:"); for (Map.Entry<String, URL> entry : transformNames.entrySet()) { sb.append('\t'); sb.append(entry.getKey()); sb.append('\n'); } compilationUnit .getErrorCollector() .addWarning( new WarningMessage(WarningMessage.POSSIBLE_ERRORS, sb.toString(), null, null)); return; } // record the transforms found in the first scan, so that in the 2nd scan, phase operations // can be added for only for new transforms that have come in if (isFirstScan) { for (Map.Entry<String, URL> entry : transformNames.entrySet()) { context.getGlobalTransformNames().add(entry.getKey()); } addPhaseOperationsForGlobalTransforms( context.getCompilationUnit(), transformNames, isFirstScan); } else { Iterator<Map.Entry<String, URL>> it = transformNames.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, URL> entry = it.next(); if (!context.getGlobalTransformNames().add(entry.getKey())) { // phase operations for this transform class have already been added before, so remove // from current scan cycle it.remove(); } } addPhaseOperationsForGlobalTransforms( context.getCompilationUnit(), transformNames, isFirstScan); } }