public void call(SourceUnit source) throws CompilationFailedException { List<ClassNode> classes = source.ast.getClasses(); for (ClassNode node : classes) { CompileUnit cu = node.getCompileUnit(); for (Iterator iter = cu.iterateClassNodeToCompile(); iter.hasNext(); ) { String name = (String) iter.next(); SourceUnit su = ast.getScriptSourceLocation(name); List<ClassNode> classesInSourceUnit = su.ast.getClasses(); StringBuilder message = new StringBuilder(); message .append("Compilation incomplete: expected to find the class ") .append(name) .append(" in ") .append(su.getName()); if (classesInSourceUnit.isEmpty()) { message.append(", but the file seems not to contain any classes"); } else { message.append(", but the file contains the classes: "); boolean first = true; for (ClassNode cn : classesInSourceUnit) { if (!first) { message.append(", "); } else { first = false; } message.append(cn.getName()); } } getErrorCollector() .addErrorAndContinue(new SimpleMessage(message.toString(), CompilationUnit.this)); iter.remove(); } } }
public void visitInboundClassNode(ClassNode node) { if (!getCoverage().contains(node)) { getSelectedNodes().add(node); Node copy = getFactory().createClass(node.getName(), node.isConfirmed()); getCopiedNodes().add(copy); copy.addDependency(currentNode); } }
private FieldNode getKeyField(ClassNode target) { List<FieldNode> annotatedFields = getAnnotatedFieldsOfHierarchy(target, KEY_ANNOTATION); if (annotatedFields.isEmpty()) return null; if (annotatedFields.size() > 1) { addCompileError( String.format( "Found more than one key fields, only one is allowed in hierarchy (%s, %s)", getQualifiedName(annotatedFields.get(0)), getQualifiedName(annotatedFields.get(1))), annotatedFields.get(0)); return null; } FieldNode result = annotatedFields.get(0); if (!result.getType().equals(ClassHelper.STRING_TYPE)) { addCompileError( String.format( "Key field '%s' must be of type String, but is '%s' instead", result.getName(), result.getType().getName()), result); return null; } ClassNode ancestor = ASTHelper.getHighestAncestorDSLObject(target); if (target.equals(ancestor)) return result; FieldNode firstKey = getKeyField(ancestor); if (firstKey == null) { addCompileError( String.format( "Inconsistent hierarchy: Toplevel class %s has no key, but child class %s defines '%s'.", ancestor.getName(), target.getName(), result.getName()), result); return null; } return result; }
/** * Sets this instance as proxy for the given ClassNode. * * @param cn the class to redirect to. If set to null the redirect will be removed */ public void setRedirect(ClassNode cn) { if (isPrimaryNode) throw new GroovyBugError( "tried to set a redirect for a primary ClassNode (" + getName() + "->" + cn.getName() + ")."); if (cn != null) cn = cn.redirect(); if (cn == this) return; redirect = cn; }
private void injectToStringMethod(ClassNode classNode) { final boolean hasToString = /*GrailsASTUtils.*/ implementsZeroArgMethod(classNode, "toString"); if (!hasToString) { GStringExpression ge = new GStringExpression(classNode.getName() + " : ${id}"); ge.addString(new ConstantExpression(classNode.getName() + " : ")); ge.addValue(new VariableExpression("id")); Statement s = new ReturnStatement(ge); MethodNode mn = new MethodNode( "toString", Modifier.PUBLIC, new ClassNode(String.class), new Parameter[0], new ClassNode[0], s); // if(LOG.isDebugEnabled()) { // LOG.debug("[GrailsDomainInjector] Adding method [toString()] to class [" + // classNode.getName() + "]"); // } classNode.addMethod(mn); } }
/** * This exists to avoid a recursive definition of toString. The default toString in GenericsType * calls ClassNode.toString(), which calls GenericsType.toString(), etc. * * @param genericsType * @param showRedirect * @return the string representing the generic type */ private String genericTypeAsString(GenericsType genericsType, boolean showRedirect) { String ret = genericsType.getName(); if (genericsType.getUpperBounds() != null) { ret += " extends "; for (int i = 0; i < genericsType.getUpperBounds().length; i++) { ClassNode classNode = genericsType.getUpperBounds()[i]; if (classNode.equals(this)) { ret += classNode.getName(); } else { ret += classNode.toString(showRedirect); } if (i + 1 < genericsType.getUpperBounds().length) ret += " & "; } } else if (genericsType.getLowerBound() != null) { ClassNode classNode = genericsType.getLowerBound(); if (classNode.equals(this)) { ret += " super " + classNode.getName(); } else { ret += " super " + classNode; } } return ret; }
private static void showDocument(Document doc) { StringBuffer content = new StringBuffer(); Node node = doc.getChildNodes().item(0); ApplicationNode appNode = new ApplicationNode(node); content.append("Application \n"); List<ClassNode> classes = appNode.getClasses(); for (int i = 0; i < classes.size(); i++) { ClassNode classNode = classes.get(i); content.append(SPACE + "Class: " + classNode.getName() + " \n"); List<MethodNode> methods = classNode.getMethods(); for (int j = 0; j < methods.size(); j++) { MethodNode methodNode = methods.get(j); content.append(SPACE + SPACE + "Method: " + methodNode.getName() + " \n"); } } System.out.println(content.toString()); }
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; }
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 void createMapOfDSLObjectMethods( FieldNode fieldNode, ClassNode keyType, ClassNode elementType) { if (getKeyField(elementType) == null) { addCompileError( String.format( "Value type of map %s (%s) has no key field", fieldNode.getName(), elementType.getName()), fieldNode); return; } MethodBuilder.createPublicMethod(fieldNode.getName()) .closureParam("closure") .assignS(propX(varX("closure"), "delegate"), varX("this")) .assignS( propX(varX("closure"), "resolveStrategy"), propX(classX(ClassHelper.CLOSURE_TYPE), "DELEGATE_FIRST")) .callMethod("closure", "call") .addTo(annotatedClass); String methodName = getElementNameForCollectionField(fieldNode); String targetOwner = getOwnerFieldName(elementType); if (!ASTHelper.isAbstract(elementType)) { MethodBuilder.createPublicMethod(methodName) .returning(elementType) .namedParams("values") .param(keyType, "key") .delegatingClosureParam(elementType) .declareVariable("created", callX(classX(elementType), "newInstance", args("key"))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created"))) .callMethod("created", "apply", args("values", "closure")) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); MethodBuilder.createPublicMethod(methodName) .returning(elementType) .param(keyType, "key") .delegatingClosureParam(elementType) .declareVariable("created", callX(classX(elementType), "newInstance", args("key"))) .callMethod("created", "copyFromTemplate") .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created"))) .callMethod("created", "apply", varX("closure")) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); } if (!isFinal(elementType)) { MethodBuilder.createPublicMethod(methodName) .returning(elementType) .namedParams("values") .classParam("typeToCreate", elementType) .param(keyType, "key") .delegatingClosureParam(elementType) .declareVariable("created", callX(varX("typeToCreate"), "newInstance", args("key"))) .callMethod("created", "copyFromTemplate") .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created"))) .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod("created", "apply", args("values", "closure")) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); MethodBuilder.createPublicMethod(methodName) .returning(elementType) .classParam("typeToCreate", elementType) .param(keyType, "key") .delegatingClosureParam(elementType) .declareVariable("created", callX(varX("typeToCreate"), "newInstance", args("key"))) .callMethod("created", "copyFromTemplate") .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created"))) .optionalAssignThisToPropertyS("created", targetOwner, targetOwner) .callMethod("created", "apply", varX("closure")) .callValidationOn("created") .doReturn("created") .addTo(annotatedClass); } //noinspection ConstantConditions MethodBuilder.createPublicMethod(methodName) .param(elementType, "value") .callMethod( fieldNode.getName(), "put", args(propX(varX("value"), getKeyField(elementType).getName()), varX("value"))) .optionalAssignThisToPropertyS("value", targetOwner, targetOwner) .addTo(annotatedClass); }
public void visitClassNode(ClassNode node) { currentNode = getFactory().createClass(node.getName(), node.isConfirmed()); }
/* * Constructor used by makeArray() if no real class is available */ private ClassNode(ClassNode componentType) { this(componentType.getName() + "[]", ACC_PUBLIC, ClassHelper.OBJECT_TYPE); this.componentType = componentType.redirect(); isPrimaryNode = false; }