/* * Copyright 2003-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.groovy.ast; import java.util.Iterator; import java.util.List; import java.util.Map; import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.expr.VariableExpression; import org.codehaus.groovy.ast.stmt.AssertStatement; import org.codehaus.groovy.ast.stmt.BlockStatement; import org.codehaus.groovy.ast.stmt.BreakStatement; import org.codehaus.groovy.ast.stmt.CaseStatement; import org.codehaus.groovy.ast.stmt.CatchStatement; import org.codehaus.groovy.ast.stmt.ContinueStatement; import org.codehaus.groovy.ast.stmt.DoWhileStatement; import org.codehaus.groovy.ast.stmt.ExpressionStatement; import org.codehaus.groovy.ast.stmt.ForStatement; import org.codehaus.groovy.ast.stmt.IfStatement; import org.codehaus.groovy.ast.stmt.ReturnStatement; import org.codehaus.groovy.ast.stmt.Statement; import org.codehaus.groovy.ast.stmt.SwitchStatement; import org.codehaus.groovy.ast.stmt.SynchronizedStatement; import org.codehaus.groovy.ast.stmt.ThrowStatement; import org.codehaus.groovy.ast.stmt.TryCatchStatement; import org.codehaus.groovy.ast.stmt.WhileStatement; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.control.messages.SyntaxErrorMessage; import org.codehaus.groovy.syntax.SyntaxException; import org.codehaus.groovy.syntax.PreciseSyntaxException; public abstract class ClassCodeVisitorSupport extends CodeVisitorSupport implements GroovyClassVisitor { public void visitClass(ClassNode node) { visitAnnotations(node); node.visitContents(this); List list = node.getObjectInitializerStatements(); for (Iterator iter = list.iterator(); iter.hasNext();) { Statement element = (Statement) iter.next(); element.visit(this); } } public void visitAnnotations(AnnotatedNode node) { List annotations = node.getAnnotations(); if (annotations.isEmpty()) return; Iterator it = annotations.iterator(); while (it.hasNext()) { AnnotationNode an = (AnnotationNode) it.next(); // skip built-in properties if (an.isBuiltIn()) continue; for (Iterator iter = an.getMembers().entrySet().iterator(); iter.hasNext();) { Map.Entry member = (Map.Entry) iter.next(); Expression memberValue = (Expression) member.getValue(); memberValue.visit(this); } } } protected void visitClassCodeContainer(Statement code) { if (code != null) code.visit(this); } protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { visitAnnotations(node); Statement code = node.getCode(); visitClassCodeContainer(code); } public void visitConstructor(ConstructorNode node) { visitConstructorOrMethod(node, true); } public void visitMethod(MethodNode node) { visitConstructorOrMethod(node, false); } public void visitField(FieldNode node) { visitAnnotations(node); Expression init = node.getInitialExpression(); if (init != null) init.visit(this); } public void visitProperty(PropertyNode node) { visitAnnotations(node); Statement statement = node.getGetterBlock(); visitClassCodeContainer(statement); statement = node.getSetterBlock(); visitClassCodeContainer(statement); Expression init = node.getInitialExpression(); if (init != null) init.visit(this); } protected void addError(String msg, ASTNode expr) { int line = expr.getLineNumber(); int col = expr.getColumnNumber(); SourceUnit source = getSourceUnit(); source.getErrorCollector().addErrorAndContinue( new SyntaxErrorMessage(new SyntaxException(msg + '\n', line, col), source) ); } protected void addTypeError(String msg, ClassNode expr ) { int line = expr.getLineNumber(); int col = expr.getColumnNumber(); SourceUnit source = getSourceUnit(); source.getErrorCollector().addErrorAndContinue( // FIXASC (groovychange) use new SyntaxException with accurate offsets new SyntaxErrorMessage(new PreciseSyntaxException(msg + '\n', line, col, expr.getNameStart(), expr.getNameEnd()), source) // end ); } protected abstract SourceUnit getSourceUnit(); protected void visitStatement(Statement statement) {} public void visitAssertStatement(AssertStatement statement) { visitStatement(statement); super.visitAssertStatement(statement); } public void visitBlockStatement(BlockStatement block) { visitStatement(block); super.visitBlockStatement(block); } public void visitBreakStatement(BreakStatement statement) { visitStatement(statement); super.visitBreakStatement(statement); } public void visitCaseStatement(CaseStatement statement) { visitStatement(statement); super.visitCaseStatement(statement); } public void visitCatchStatement(CatchStatement statement) { visitStatement(statement); super.visitCatchStatement(statement); } public void visitContinueStatement(ContinueStatement statement) { visitStatement(statement); super.visitContinueStatement(statement); } public void visitDoWhileLoop(DoWhileStatement loop) { visitStatement(loop); super.visitDoWhileLoop(loop); } public void visitExpressionStatement(ExpressionStatement statement) { visitStatement(statement); super.visitExpressionStatement(statement); } public void visitForLoop(ForStatement forLoop) { visitStatement(forLoop); super.visitForLoop(forLoop); } public void visitIfElse(IfStatement ifElse) { visitStatement(ifElse); super.visitIfElse(ifElse); } public void visitReturnStatement(ReturnStatement statement) { visitStatement(statement); super.visitReturnStatement(statement); } public void visitSwitch(SwitchStatement statement) { visitStatement(statement); super.visitSwitch(statement); } public void visitSynchronizedStatement(SynchronizedStatement statement) { visitStatement(statement); super.visitSynchronizedStatement(statement); } public void visitThrowStatement(ThrowStatement statement) { visitStatement(statement); super.visitThrowStatement(statement); } public void visitTryCatchFinally(TryCatchStatement statement) { visitStatement(statement); super.visitTryCatchFinally(statement); } public void visitWhileLoop(WhileStatement loop) { visitStatement(loop); super.visitWhileLoop(loop); } }