private void printImports(PrintWriter out, ClassNode classNode) { List<String> imports = new ArrayList<String>(); ModuleNode moduleNode = classNode.getModule(); for (ImportNode importNode : moduleNode.getStarImports()) { imports.add(importNode.getPackageName()); } for (ImportNode imp : moduleNode.getImports()) { if (imp.getAlias() == null) imports.add(imp.getType().getName()); } imports.addAll(Arrays.asList(ResolveVisitor.DEFAULT_IMPORTS)); for (String imp : imports) { String s = new StringBuilder() .append("import ") .append(imp) .append((imp.charAt(imp.length() - 1) == '.') ? "*;" : ";") .toString() .replace('$', '.'); out.println(s); } out.println(); }
public void visitClass(ClassNode node) { visitAnnotations(node); visitPackage(node.getPackage()); visitImports(node.getModule()); node.visitContents(this); visitObjectInitializerStatements(node); }
private Expression findStaticFieldOrPropAccessorImportFromModule(String name) { ModuleNode module = currentClass.getModule(); if (module == null) return null; Map<String, ImportNode> importNodes = module.getStaticImports(); Expression expression; String accessorName = getAccessorName(name); // look for one of these: // import static MyClass.setProp [as setOtherProp] // import static MyClass.getProp [as getOtherProp] // when resolving prop reference if (importNodes.containsKey(accessorName)) { ImportNode importNode = importNodes.get(accessorName); expression = findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName()); if (expression != null) return expression; expression = findStaticPropertyAccessor( importNode.getType(), getPropNameForAccessor(importNode.getFieldName())); if (expression != null) return expression; } if (accessorName.startsWith("get")) { accessorName = "is" + accessorName.substring(3); if (importNodes.containsKey(accessorName)) { ImportNode importNode = importNodes.get(accessorName); expression = findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName()); if (expression != null) return expression; expression = findStaticPropertyAccessor( importNode.getType(), getPropNameForAccessor(importNode.getFieldName())); if (expression != null) return expression; } } // look for one of these: // import static MyClass.prop [as otherProp] // when resolving prop or field reference if (importNodes.containsKey(name)) { ImportNode importNode = importNodes.get(name); expression = findStaticPropertyAccessor(importNode.getType(), importNode.getFieldName()); if (expression != null) return expression; expression = findStaticField(importNode.getType(), importNode.getFieldName()); if (expression != null) return expression; } // look for one of these: // import static MyClass.* // when resolving prop or field reference for (ImportNode importNode : module.getStaticStarImports().values()) { ClassNode node = importNode.getType(); expression = findStaticPropertyAccessor(node, name); if (expression != null) return expression; expression = findStaticField(node, name); if (expression != null) return expression; } return null; }
/** * A loop driver for applying operations to all primary ClassNodes in our AST. Automatically skips * units that have already been processed through the current phase. */ public void applyToPrimaryClassNodes(PrimaryClassNodeOperation body) throws CompilationFailedException { // GRECLIPSE: start /*old{ Iterator classNodes = getPrimaryClassNodes(body.needSortedInput()).iterator(); }*/ // newcode List primaryClassNodes = getPrimaryClassNodes(body.needSortedInput()); Iterator classNodes = primaryClassNodes.iterator(); // end while (classNodes.hasNext()) { SourceUnit context = null; try { ClassNode classNode = (ClassNode) classNodes.next(); context = classNode.getModule().getContext(); // GRECLIPSE get to the bottom of this - why are operations running multiple times that // should only run once? if (context == null || context.phase < phase || (context.phase == phase && !context.phaseComplete)) { int offset = 1; Iterator<InnerClassNode> iterator = classNode.getInnerClasses(); while (iterator.hasNext()) { iterator.next(); offset++; } body.call(context, new GeneratorContext(this.ast, offset), classNode); } } catch (CompilationFailedException e) { // fall through, getErrorReporter().failIfErrors() will trigger } catch (NullPointerException npe) { throw npe; } catch (GroovyBugError e) { changeBugText(e, context); throw e; } catch (Exception e) { // check the exception for a nested compilation exception ErrorCollector nestedCollector = null; for (Throwable next = e.getCause(); next != e && next != null; next = next.getCause()) { if (!(next instanceof MultipleCompilationErrorsException)) continue; MultipleCompilationErrorsException mcee = (MultipleCompilationErrorsException) next; nestedCollector = mcee.collector; break; } if (nestedCollector != null) { getErrorCollector().addCollectorContents(nestedCollector); } else { getErrorCollector().addError(new ExceptionMessage(e, configuration.getDebug(), this)); } } } getErrorCollector().failIfErrors(); }
private void buildCommon( ClassNode buildee, AnnotationNode anno, List<FieldNode> fieldNodes, ClassNode builder) { String prefix = getMemberStringValue(anno, "prefix", ""); String buildMethodName = getMemberStringValue(anno, "buildMethodName", "create"); createBuilderConstructors(builder, buildee, fieldNodes); buildee.getModule().addClass(builder); String builderMethodName = getMemberStringValue(anno, "builderMethodName", "createInitializer"); buildee.addMethod( createBuilderMethod(buildMethodName, builder, fieldNodes.size(), builderMethodName)); for (int i = 0; i < fieldNodes.size(); i++) { builder.addMethod(createBuilderMethodForField(builder, fieldNodes, prefix, i)); } builder.addMethod(createBuildMethod(builder, buildMethodName, fieldNodes)); }
private Expression transformMapEntryExpression( MapEntryExpression me, ClassNode constructorCallType) { Expression key = me.getKeyExpression(); Expression value = me.getValueExpression(); ModuleNode module = currentClass.getModule(); if (module != null && key instanceof ConstantExpression) { Map<String, ImportNode> importNodes = module.getStaticImports(); if (importNodes.containsKey(key.getText())) { ImportNode importNode = importNodes.get(key.getText()); if (importNode.getType().equals(constructorCallType)) { String newKey = importNode.getFieldName(); return new MapEntryExpression( new ConstantExpression(newKey), value.transformExpression(this)); } } } return me; }
// GroovyClassVisitor interface // ------------------------------------------------------------------------- public void visitClass(ClassNode classNode) { try { this.classNode = classNode; this.internalClassName = BytecodeHelper.getClassInternalName(classNode); // System.out.println("Generating class: " + classNode.getName()); this.internalBaseClassName = BytecodeHelper.getClassInternalName(classNode.getSuperClass()); cv.visit( Opcodes.V1_3, classNode.getModifiers(), internalClassName, (String) null, internalBaseClassName, BytecodeHelper.getClassInternalNames(classNode.getInterfaces())); classNode.visitContents(this); for (Iterator iter = innerClasses.iterator(); iter.hasNext(); ) { ClassNode innerClass = (ClassNode) iter.next(); ClassNode innerClassType = innerClass; String innerClassInternalName = BytecodeHelper.getClassInternalName(innerClassType); String outerClassName = internalClassName; // default for inner classes MethodNode enclosingMethod = innerClass.getEnclosingMethod(); if (enclosingMethod != null) { // local inner classes do not specify the outer class name outerClassName = null; } cv.visitInnerClass( innerClassInternalName, outerClassName, innerClassType.getName(), innerClass.getModifiers()); } cv.visitEnd(); } catch (GroovyRuntimeException e) { e.setModule(classNode.getModule()); throw e; } }
/** * Loads the given class node returning the implementation Class. * * <p>WARNING: this compilation is not synchronized * * @param classNode * @return a class */ public Class defineClass(ClassNode classNode, String file, String newCodeBase) { CodeSource codeSource = null; try { codeSource = new CodeSource(new URL("file", "", newCodeBase), (java.security.cert.Certificate[]) null); } catch (MalformedURLException e) { // swallow } CompilationUnit unit = createCompilationUnit(config, codeSource); ClassCollector collector = createCollector(unit, classNode.getModule().getContext()); try { unit.addClassNode(classNode); unit.setClassgenCallback(collector); unit.compile(Phases.CLASS_GENERATION); definePackage(collector.generatedClass.getName()); return collector.generatedClass; } catch (CompilationFailedException e) { throw new RuntimeException(e); } }
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; }
public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException { optimizer.visitClass( classNode, source); // GROOVY-4272: repositioned it here from staticImport if (!classNode.isSynthetic()) { GenericsVisitor genericsVisitor = new GenericsVisitor(source); genericsVisitor.visitClass(classNode); } // // Run the Verifier on the outer class // try { verifier.visitClass(classNode); } catch (GroovyRuntimeException rpe) { ASTNode node = rpe.getNode(); getErrorCollector() .addError( new SyntaxException( rpe.getMessage(), node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source); } LabelVerifier lv = new LabelVerifier(source); lv.visitClass(classNode); ClassCompletionVerifier completionVerifier = new ClassCompletionVerifier(source); completionVerifier.visitClass(classNode); ExtendedVerifier xverifier = new ExtendedVerifier(source); xverifier.visitClass(classNode); // because the class may be generated even if a error was found // and that class may have an invalid format we fail here if needed getErrorCollector().failIfErrors(); // // Prep the generator machinery // ClassVisitor visitor = createClassVisitor(); String sourceName = (source == null ? classNode.getModule().getDescription() : source.getName()); // only show the file name and its extension like javac does in its stacktraces rather // than the full path // also takes care of both \ and / depending on the host compiling environment if (sourceName != null) sourceName = sourceName.substring( Math.max(sourceName.lastIndexOf('\\'), sourceName.lastIndexOf('/')) + 1); AsmClassGenerator generator = new AsmClassGenerator(source, context, visitor, sourceName); // // Run the generation and create the class (if required) // // GRECLIPSE: if there are errors, don't generate code. // code gen can fail unexpectedly if there was an earlier error. if (!source.getErrorCollector().hasErrors()) { // end generator.visitClass(classNode); byte[] bytes = ((ClassWriter) visitor).toByteArray(); /// GRECLIPSE: start: added classNode, sourceUnit /*old{ generatedClasses.add(new GroovyClass(classNode.getName(), bytes)); }*/ // newcode generatedClasses.add(new GroovyClass(classNode.getName(), bytes, classNode, source)); // end // // Handle any callback that's been set // if (CompilationUnit.this.classgenCallback != null) { classgenCallback.call(visitor, classNode); } // // Recurse for inner classes // LinkedList innerClasses = generator.getInnerClasses(); while (!innerClasses.isEmpty()) { classgen.call(source, context, (ClassNode) innerClasses.removeFirst()); } // GRECLIPSE: if there are errors, don't generate code } // end }
private Expression findStaticMethodImportFromModule(Expression method, Expression args) { ModuleNode module = currentClass.getModule(); if (module == null || !(method instanceof ConstantExpression)) return null; Map<String, ImportNode> importNodes = module.getStaticImports(); ConstantExpression ce = (ConstantExpression) method; Expression expression; Object value = ce.getValue(); // skip non-Strings, e.g. Integer if (!(value instanceof String)) return null; final String name = (String) value; // look for one of these: // import static SomeClass.method [as otherName] // when resolving methodCall() or getProp() or setProp() if (importNodes.containsKey(name)) { ImportNode importNode = importNodes.get(name); expression = findStaticMethod(importNode.getType(), importNode.getFieldName(), args); if (expression != null) return expression; expression = findStaticPropertyAccessorGivenArgs( importNode.getType(), getPropNameForAccessor(importNode.getFieldName()), args); if (expression != null) { return new StaticMethodCallExpression( importNode.getType(), importNode.getFieldName(), args); } } // look for one of these: // import static SomeClass.someProp [as otherName] // when resolving getProp() or setProp() if (validPropName(name)) { String propName = getPropNameForAccessor(name); if (importNodes.containsKey(propName)) { ImportNode importNode = importNodes.get(propName); expression = findStaticMethod( importNode.getType(), prefix(name) + capitalize(importNode.getFieldName()), args); if (expression != null) return expression; expression = findStaticPropertyAccessorGivenArgs( importNode.getType(), importNode.getFieldName(), args); if (expression != null) { return new StaticMethodCallExpression( importNode.getType(), prefix(name) + capitalize(importNode.getFieldName()), args); } } } Map<String, ImportNode> starImports = module.getStaticStarImports(); ClassNode starImportType; if (currentClass.isEnum() && starImports.containsKey(currentClass.getName())) { ImportNode importNode = starImports.get(currentClass.getName()); starImportType = importNode == null ? null : importNode.getType(); expression = findStaticMethod(starImportType, name, args); if (expression != null) return expression; } else { for (ImportNode importNode : starImports.values()) { starImportType = importNode == null ? null : importNode.getType(); expression = findStaticMethod(starImportType, name, args); if (expression != null) return expression; expression = findStaticPropertyAccessorGivenArgs(starImportType, getPropNameForAccessor(name), args); if (expression != null) { return new StaticMethodCallExpression(starImportType, name, args); } } } return null; }
private void printClassContents(PrintWriter out, ClassNode classNode) throws FileNotFoundException { if (classNode instanceof InnerClassNode && ((InnerClassNode) classNode).isAnonymous()) { // if it is an anonymous inner class, don't generate the stub code for it. return; } try { Verifier verifier = new Verifier() { public void addCovariantMethods(ClassNode cn) {} protected void addTimeStamp(ClassNode node) {} protected void addInitialization(ClassNode node) {} protected void addPropertyMethod(MethodNode method) { doAddMethod(method); } protected void addReturnIfNeeded(MethodNode node) {} protected void addMethod( ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) { doAddMethod( new MethodNode(name, modifiers, returnType, parameters, exceptions, code)); } protected void addConstructor( Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) { if (code instanceof ExpressionStatement) { // GROOVY-4508 Statement temp = code; code = new BlockStatement(); ((BlockStatement) code).addStatement(temp); } ConstructorNode ctrNode = new ConstructorNode(ctor.getModifiers(), newParams, ctor.getExceptions(), code); ctrNode.setDeclaringClass(node); constructors.add(ctrNode); } protected void addDefaultParameters(DefaultArgsAction action, MethodNode method) { final Parameter[] parameters = method.getParameters(); final Expression[] saved = new Expression[parameters.length]; for (int i = 0; i < parameters.length; i++) { if (parameters[i].hasInitialExpression()) saved[i] = parameters[i].getInitialExpression(); } super.addDefaultParameters(action, method); for (int i = 0; i < parameters.length; i++) { if (saved[i] != null) parameters[i].setInitialExpression(saved[i]); } } private void doAddMethod(MethodNode method) { String sig = method.getTypeDescriptor(); if (propertyMethodsWithSigs.containsKey(sig)) return; propertyMethods.add(method); propertyMethodsWithSigs.put(sig, method); } @Override protected void addDefaultConstructor(ClassNode node) { // not required for stub generation } }; verifier.visitClass(classNode); currentModule = classNode.getModule(); boolean isInterface = classNode.isInterface(); boolean isEnum = (classNode.getModifiers() & Opcodes.ACC_ENUM) != 0; boolean isAnnotationDefinition = classNode.isAnnotationDefinition(); printAnnotations(out, classNode); printModifiers( out, classNode.getModifiers() & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0) & ~(isEnum ? Opcodes.ACC_FINAL : 0)); if (isInterface) { if (isAnnotationDefinition) { out.print("@"); } out.print("interface "); } else if (isEnum) { out.print("enum "); } else { out.print("class "); } String className = classNode.getNameWithoutPackage(); if (classNode instanceof InnerClassNode) className = className.substring(className.lastIndexOf("$") + 1); out.println(className); printGenericsBounds(out, classNode, true); ClassNode superClass = classNode.getUnresolvedSuperClass(false); if (!isInterface && !isEnum) { out.print(" extends "); printType(out, superClass); } ClassNode[] interfaces = classNode.getInterfaces(); if (interfaces != null && interfaces.length > 0 && !isAnnotationDefinition) { if (isInterface) { out.println(" extends"); } else { out.println(" implements"); } for (int i = 0; i < interfaces.length - 1; ++i) { out.print(" "); printType(out, interfaces[i]); out.print(","); } out.print(" "); printType(out, interfaces[interfaces.length - 1]); } out.println(" {"); printFields(out, classNode); printMethods(out, classNode, isEnum); for (Iterator<InnerClassNode> inner = classNode.getInnerClasses(); inner.hasNext(); ) { // GROOVY-4004: Clear the methods from the outer class so that they don't get duplicated in // inner ones propertyMethods.clear(); propertyMethodsWithSigs.clear(); constructors.clear(); printClassContents(out, inner.next()); } out.println("}"); } finally { propertyMethods.clear(); propertyMethodsWithSigs.clear(); constructors.clear(); currentModule = null; } }
private String getPath(Class clazz) { CompilationUnit cu = getLocalData().get().cu; String name = clazz.getName(); ClassNode classNode = cu.getClassNode(name); return classNode.getModule().getContext().getName(); }
private Expression findStaticFieldOrPropAccessorImportFromModule(String name) { ModuleNode module = currentClass.getModule(); if (module == null) return null; Map<String, ImportNode> importNodes = module.getStaticImports(); Expression expression = null; String accessorName = getAccessorName(name); // look for one of these: // import static MyClass.setProp [as setOtherProp] // import static MyClass.getProp [as getOtherProp] // when resolving prop reference if (importNodes.containsKey(accessorName)) { ImportNode importNode = importNodes.get(accessorName); expression = findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName()); if (expression != null) return expression; expression = findStaticPropertyAccessor( importNode.getType(), getPropNameForAccessor(importNode.getFieldName())); if (expression != null) return expression; } if (accessorName.startsWith("get")) { accessorName = "is" + accessorName.substring(3); if (importNodes.containsKey(accessorName)) { ImportNode importNode = importNodes.get(accessorName); expression = findStaticPropertyAccessorByFullName(importNode.getType(), importNode.getFieldName()); if (expression != null) return expression; expression = findStaticPropertyAccessor( importNode.getType(), getPropNameForAccessor(importNode.getFieldName())); if (expression != null) return expression; } } // look for one of these: // import static MyClass.prop [as otherProp] // when resolving prop or field reference if (importNodes.containsKey(name)) { ImportNode importNode = importNodes.get(name); // GRECLIPSE add try { if (!isReconcile) { // GRECLIPSE end expression = findStaticPropertyAccessor(importNode.getType(), importNode.getFieldName()); if (expression != null) return expression; // GRECLIPSE add } // end expression = findStaticField(importNode.getType(), importNode.getFieldName()); if (expression != null) return expression; // GRECLIPSE add } finally { // store the identifier to facilitate organizing static imports if (expression != null) expression.setNodeMetaData("static.import.alias", name); } // GRECLIPSE end } // look for one of these: // import static MyClass.* // when resolving prop or field reference for (ImportNode importNode : module.getStaticStarImports().values()) { ClassNode node = importNode.getType(); expression = findStaticPropertyAccessor(node, name); if (expression != null) return expression; expression = findStaticField(node, name); if (expression != null) return expression; } return null; }
private void createBuilderFactoryMethod( AnnotationNode anno, ClassNode buildee, ClassNode builder) { buildee.getModule().addClass(builder); buildee.addMethod(createBuilderMethod(anno, builder)); }