public List<TreeContext> pathUpTo(Class<ASTNode> node, ASTNodePredicate predicate) { List<TreeContext> path = new LinkedList<TreeContext>(); TreeContext current = lastContext; boolean found = false; while (current != null && !found) { path.add(current); ASTNode currentNode = current.node; if (node == null) { if (predicate.matches(currentNode)) { found = true; } } else { if (predicate == null) { if (currentNode == null || node == currentNode.getClass()) { found = true; } } else { found = currentNode != null && node == currentNode.getClass() && predicate.matches(currentNode); } } current = current.parent; } if (found) { return path; } return Collections.emptyList(); }
public void addCompileWarning(String msg, ASTNode node) { Token token = new Token(Types.UNKNOWN, node.getText(), node.getLineNumber(), node.getColumnNumber()); sourceUnit .getErrorCollector() .addWarning(WarningMessage.POSSIBLE_ERRORS, msg, token, sourceUnit); }
/** * Generates a fatal compilation error * * @param sourceUnit the SourceUnit * @param astNode the ASTNode which caused the error * @param message The error message * @param fatal indicates if this is a fatal error */ public static void error( final SourceUnit sourceUnit, final ASTNode astNode, final String message, final boolean fatal) { final SyntaxException syntaxException = new SyntaxException(message, astNode.getLineNumber(), astNode.getColumnNumber()); final SyntaxErrorMessage syntaxErrorMessage = new SyntaxErrorMessage(syntaxException, sourceUnit); sourceUnit.getErrorCollector().addError(syntaxErrorMessage, fatal); }
protected void addError(String msg, ASTNode expr) { this.source .getErrorCollector() .addErrorAndContinue( new SyntaxErrorMessage( new SyntaxException( msg + '\n', expr.getLineNumber(), expr.getColumnNumber(), expr.getLastLineNumber(), expr.getLastColumnNumber()), this.source)); }
private String getRefDescriptor(ASTNode ref) { if (ref instanceof FieldNode) { FieldNode f = (FieldNode) ref; return "the field " + f.getName() + " "; } else if (ref instanceof PropertyNode) { PropertyNode p = (PropertyNode) ref; return "the property " + p.getName() + " "; } else if (ref instanceof ConstructorNode) { return "the constructor " + ref.getText() + " "; } else if (ref instanceof MethodNode) { return "the method " + ref.getText() + " "; } else if (ref instanceof ClassNode) { return "the super class " + ref + " "; } return "<unknown with class " + ref.getClass() + "> "; }
private void declare(Variable var, ASTNode expr) { String scopeType = "scope"; String variableType = "variable"; if (expr.getClass() == FieldNode.class) { scopeType = "class"; variableType = "field"; } else if (expr.getClass() == PropertyNode.class) { scopeType = "class"; variableType = "property"; } StringBuilder msg = new StringBuilder(); msg.append("The current ").append(scopeType); msg.append(" already contains a ").append(variableType); msg.append(" of the name ").append(var.getName()); if (currentScope.getDeclaredVariable(var.getName()) != null) { addError(msg.toString(), expr); return; } for (VariableScope scope = currentScope.getParent(); scope != null; scope = scope.getParent()) { // if we are in a class and no variable is declared until // now, then we can break the loop, because we are allowed // to declare a variable of the same name as a class member if (scope.getClassScope() != null) break; if (scope.getDeclaredVariable(var.getName()) != null) { // variable already declared addError(msg.toString(), expr); break; } } // declare the variable even if there was an error to allow more checks currentScope.putDeclaredVariable(var); }
/** * @param inferredElement * @return */ private String createLabel(ASTNode inferredElement) { if (inferredElement instanceof PropertyNode) { inferredElement = ((PropertyNode) inferredElement).getField(); } String label; if (inferredElement instanceof ClassNode) { label = createClassLabel((ClassNode) inferredElement); } else if (inferredElement instanceof MethodNode) { label = createMethodLabel((MethodNode) inferredElement); } else if (inferredElement instanceof FieldNode) { label = createFieldLabel((FieldNode) inferredElement); } else { label = inferredElement.getText(); } return "<b>" + label + "</b><br>\n"; }
@Override public boolean matches(final ASTNode node) { return astNodeClass == node.getClass(); }
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 }
protected ClassNode createClosureClass(ClosureExpression expression, int mods) { ClassNode classNode = controller.getClassNode(); ClassNode outerClass = controller.getOutermostClass(); MethodNode methodNode = controller.getMethodNode(); String name = classNode.getName() + "$" + controller .getContext() .getNextClosureInnerName( outerClass, classNode, methodNode); // add a more informative name boolean staticMethodOrInStaticClass = controller.isStaticMethod() || classNode.isStaticClass(); Parameter[] parameters = expression.getParameters(); if (parameters == null) { parameters = Parameter.EMPTY_ARRAY; } else if (parameters.length == 0) { // let's create a default 'it' parameter Parameter it = new Parameter(ClassHelper.OBJECT_TYPE, "it", ConstantExpression.NULL); parameters = new Parameter[] {it}; Variable ref = expression.getVariableScope().getDeclaredVariable("it"); if (ref != null) it.setClosureSharedVariable(ref.isClosureSharedVariable()); } Parameter[] localVariableParams = getClosureSharedVariables(expression); removeInitialValues(localVariableParams); InnerClassNode answer = new InnerClassNode(classNode, name, mods, ClassHelper.CLOSURE_TYPE.getPlainNodeReference()); answer.setEnclosingMethod(controller.getMethodNode()); answer.setSynthetic(true); answer.setUsingGenerics(outerClass.isUsingGenerics()); answer.setSourcePosition(expression); if (staticMethodOrInStaticClass) { answer.setStaticClass(true); } if (controller.isInScriptBody()) { answer.setScriptBody(true); } MethodNode method = answer.addMethod( "doCall", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, expression.getCode()); method.setSourcePosition(expression); VariableScope varScope = expression.getVariableScope(); if (varScope == null) { throw new RuntimeException( "Must have a VariableScope by now! for expression: " + expression + " class: " + name); } else { method.setVariableScope(varScope.copy()); } if (parameters.length > 1 || (parameters.length == 1 && parameters[0].getType() != null && parameters[0].getType() != ClassHelper.OBJECT_TYPE && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType().getComponentType()))) { // let's add a typesafe call method MethodNode call = answer.addMethod( "call", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, new ReturnStatement( new MethodCallExpression( VariableExpression.THIS_EXPRESSION, "doCall", new ArgumentListExpression(parameters)))); call.setSourcePosition(expression); } // let's make the constructor BlockStatement block = new BlockStatement(); // this block does not get a source position, because we don't // want this synthetic constructor to show up in corbertura reports VariableExpression outer = new VariableExpression("_outerInstance"); outer.setSourcePosition(expression); block.getVariableScope().putReferencedLocalVariable(outer); VariableExpression thisObject = new VariableExpression("_thisObject"); thisObject.setSourcePosition(expression); block.getVariableScope().putReferencedLocalVariable(thisObject); TupleExpression conArgs = new TupleExpression(outer, thisObject); block.addStatement( new ExpressionStatement(new ConstructorCallExpression(ClassNode.SUPER, conArgs))); // let's assign all the parameter fields from the outer context for (Parameter param : localVariableParams) { String paramName = param.getName(); ClassNode type = param.getType(); if (true) { VariableExpression initialValue = new VariableExpression(paramName); initialValue.setAccessedVariable(param); initialValue.setUseReferenceDirectly(true); ClassNode realType = type; type = ClassHelper.makeReference(); param.setType(ClassHelper.makeReference()); FieldNode paramField = answer.addField(paramName, ACC_PRIVATE | ACC_SYNTHETIC, type, initialValue); paramField.setOriginType(ClassHelper.getWrapper(param.getOriginType())); paramField.setHolder(true); String methodName = Verifier.capitalize(paramName); // let's add a getter & setter Expression fieldExp = new FieldExpression(paramField); answer.addMethod( "get" + methodName, ACC_PUBLIC, realType.getPlainNodeReference(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new ReturnStatement(fieldExp)); } } Parameter[] params = new Parameter[2 + localVariableParams.length]; params[0] = new Parameter(ClassHelper.OBJECT_TYPE, "_outerInstance"); params[1] = new Parameter(ClassHelper.OBJECT_TYPE, "_thisObject"); System.arraycopy(localVariableParams, 0, params, 2, localVariableParams.length); ASTNode sn = answer.addConstructor(ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, block); sn.setSourcePosition(expression); correctAccessedVariable(answer, expression); return answer; }
public static void warning( final SourceUnit sourceUnit, final ASTNode node, final String warningMessage) { final String sample = sourceUnit.getSample(node.getLineNumber(), node.getColumnNumber(), new Janitor()); GrailsConsole.getInstance().warning(warningMessage + "\n\n" + sample); }
private void addCompileError(String msg, ASTNode node) { SyntaxException se = new SyntaxException(msg, node.getLineNumber(), node.getColumnNumber()); sourceUnit.getErrorCollector().addFatalError(new SyntaxErrorMessage(se, sourceUnit)); }
public NodeKey(ASTNode node) { pos = node.getStart(); len = node.getLength(); }