/* Copyright (c) 2009-2011 Olivier Chafik, All Rights Reserved This file is part of JNAerator (http://jnaerator.googlecode.com/). JNAerator is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. JNAerator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with JNAerator. If not, see <http://www.gnu.org/licenses/>. */ package com.ochafik.lang.jnaerator.parser; import com.ochafik.lang.jnaerator.parser.Statement.Catch; import com.ochafik.lang.jnaerator.parser.Statement.Delete; import com.ochafik.lang.jnaerator.parser.Statement.Try; import com.ochafik.lang.jnaerator.parser.Statement.While; import com.ochafik.lang.jnaerator.parser.TypeRef.PrecisionTypeRef; import java.util.ArrayList; import java.util.Collection; import com.ochafik.lang.jnaerator.parser.Declarator.ArrayDeclarator; import com.ochafik.lang.jnaerator.parser.Declarator.DirectDeclarator; import com.ochafik.lang.jnaerator.parser.Declarator.FunctionDeclarator; import com.ochafik.lang.jnaerator.parser.Declarator.PointerDeclarator; import com.ochafik.lang.jnaerator.parser.Declarator.TargettedDeclarator; import com.ochafik.lang.jnaerator.parser.Enum.EnumItem; import com.ochafik.lang.jnaerator.parser.Expression.ArrayAccess; import com.ochafik.lang.jnaerator.parser.Expression.AssignmentOp; import com.ochafik.lang.jnaerator.parser.Expression.BinaryOp; import com.ochafik.lang.jnaerator.parser.Expression.Cast; import com.ochafik.lang.jnaerator.parser.Expression.ConditionalExpression; import com.ochafik.lang.jnaerator.parser.Expression.Constant; import com.ochafik.lang.jnaerator.parser.Expression.EmptyArraySize; import com.ochafik.lang.jnaerator.parser.Expression.ExpressionSequence; import com.ochafik.lang.jnaerator.parser.Expression.ExpressionsBlock; import com.ochafik.lang.jnaerator.parser.Expression.FunctionCall; import com.ochafik.lang.jnaerator.parser.Expression.MemberRef; import com.ochafik.lang.jnaerator.parser.Expression.New; import com.ochafik.lang.jnaerator.parser.Expression.NewArray; import com.ochafik.lang.jnaerator.parser.Expression.NullExpression; import com.ochafik.lang.jnaerator.parser.Expression.OpaqueExpression; import com.ochafik.lang.jnaerator.parser.Expression.TypeRefExpression; import com.ochafik.lang.jnaerator.parser.Expression.UnaryOp; import com.ochafik.lang.jnaerator.parser.Expression.VariableRef; import com.ochafik.lang.jnaerator.parser.Identifier.QualifiedIdentifier; import com.ochafik.lang.jnaerator.parser.Identifier.SimpleIdentifier; import com.ochafik.lang.jnaerator.parser.Statement.Block; //import com.ochafik.lang.jnaerator.parser.Statement.DeclarationStatement; import com.ochafik.lang.jnaerator.parser.Statement.DoWhile; import com.ochafik.lang.jnaerator.parser.Statement.ExpressionStatement; import com.ochafik.lang.jnaerator.parser.Statement.If; import com.ochafik.lang.jnaerator.parser.Statement.For; import com.ochafik.lang.jnaerator.parser.Statement.Return; import com.ochafik.lang.jnaerator.parser.Statement.Throw; import com.ochafik.lang.jnaerator.parser.StoredDeclarations.TypeDef; import com.ochafik.lang.jnaerator.parser.TypeRef.ArrayRef; import com.ochafik.lang.jnaerator.parser.TypeRef.FunctionSignature; import com.ochafik.lang.jnaerator.parser.TypeRef.Pointer; import com.ochafik.lang.jnaerator.parser.TypeRef.Primitive; import com.ochafik.lang.jnaerator.parser.TypeRef.SimpleTypeRef; import com.ochafik.lang.jnaerator.parser.TypeRef.TaggedTypeRef; import com.ochafik.lang.jnaerator.parser.TypeRef.TargettedTypeRef; import com.nativelibs4java.jalico.Pair; import java.util.List; import java.util.Map; public class Scanner implements Visitor { public void visitArg(Arg arg) { visitDeclaration(arg); visit(arg.getDefaultValue()); visit(arg.getDeclarator()); } public void visitConstant(Constant constant) { visitExpression(constant); } protected void visitExpression(Expression expression) { visitElement(expression); } public void visitEnum(Enum enum1) { visitTaggedTypeRef(enum1); visit(enum1.getItems()); visit(enum1.getInterfaces()); visit(enum1.getBody()); } public void visitFunction(Function function) { visitDeclaration(function); visit(function.getArgs()); visit(function.getThrown()); visit(function.getInitializers()); visit(function.getBody()); visit(function.getName()); } public void visitFunctionPointerDeclaration(FunctionPointerDeclaration f) { visitDeclaration(f); visit(f.getDefaultValue()); } protected void visitDeclaration(Declaration d) { visitStatement(d); visit(d.getValueType()); } protected void visitElement(Element d) { visit(d.getResolvedJavaIdentifier()); } public void visitStruct(Struct struct) { if (struct.getType() != null) { switch (struct.getType()) { case CPPClass: visitCPPClass(struct); break; case CStruct: visitCStruct(struct); break; case ObjCClass: visitObjCClass(struct); break; case ObjCProtocol: visitObjCProtocol(struct); break; case JavaClass: visitJavaClass(struct); break; case JavaInterface: visitJavaInterface(struct); break; default: doVisitStruct(struct); } } else { doVisitStruct(struct); } } public void visitJavaClass(Struct struct) { doVisitStruct(struct); } public void visitJavaInterface(Struct struct) { doVisitStruct(struct); } protected void visitStoredDeclarations(StoredDeclarations d) { visitDeclaration(d); visit(d.getDeclarators()); } protected void visitCPPClass(Struct struct) { doVisitStruct(struct); } protected void doVisitStruct(Struct struct) { visitTaggedTypeRef(struct); visit(struct.getDeclarations()); visit(struct.getProtocols()); visit(struct.getParents()); } protected void visitCStruct(Struct struct) { doVisitStruct(struct); } protected void visitObjCClass(Struct struct) { doVisitStruct(struct); } protected void visitObjCProtocol(Struct struct) { doVisitStruct(struct); } public void visitTypeDef(TypeDef typeDef) { visitStoredDeclarations(typeDef); } public void visitArray(ArrayRef array) { visitTargettedTypeRef(array); visit(array.getDimensions()); } protected void visitTypeRef(TypeRef typeRef) { visitModifiableElement(typeRef); visit(typeRef.getResolvedJavaIdentifier()); } protected void visitTargettedTypeRef(TargettedTypeRef targettedTypeRef) { visitTypeRef(targettedTypeRef); visit(targettedTypeRef.getTarget()); } public void visitFunctionSignature(FunctionSignature functionSignature) { visitTypeRef(functionSignature); if (functionSignature != null) visit(functionSignature.getFunction()); } public void visitPointer(Pointer pointer) { visitTargettedTypeRef(pointer); } public void visitPrimitive(Primitive primitive) { visitSimpleTypeRef(primitive); } public void visitSimpleTypeRef(SimpleTypeRef simpleTypeRef) { visitTypeRef(simpleTypeRef); visit(simpleTypeRef.getName()); } static <T> Collection<T> copy(Collection<T> col) { return new ArrayList<T>(col); } public void visitSourceFile(SourceFile header) { visitElement(header); visit(header.getDeclarations()); } public void visitEnumItem(EnumItem enumItem) { visitElement(enumItem); visit(enumItem.getArguments()); visit(enumItem.getBody()); } public void visitUnaryOp(UnaryOp unaryOp) { visitExpression(unaryOp); visit(unaryOp.getOperand()); } public void visitVariableRef(VariableRef variableRef) { visitExpression(variableRef); visit(variableRef.getName()); } public void visitBinaryOp(BinaryOp binaryOp) { visitExpression(binaryOp); visit(binaryOp.getFirstOperand()); visit(binaryOp.getSecondOperand()); } public void visitFunctionCall(FunctionCall functionCall) { visitMemberRef(functionCall); visit(functionCall.getTarget()); visit(functionCall.getFunction()); for (Pair<String, Expression> x : copy(functionCall.getArguments())) if (x != null) visit(x.getSecond()); } public void visitMemberRef(MemberRef memberRef) { visitExpression(memberRef); visit(memberRef.getTarget()); visit(memberRef.getName()); } public void visitCast(Cast cast) { visitExpression(cast); visit(cast.getType()); visit(cast.getTarget()); } public void visitDeclarator(Declarator declarator) { visitModifiableElement(declarator); visit(declarator.getDefaultValue()); } public void visitVariablesDeclaration(VariablesDeclaration v) { visitDeclaration(v); visit(v.getDeclarators()); } public void visitTaggedTypeRefDeclaration(TaggedTypeRefDeclaration taggedTypeRefDeclaration) { visitDeclaration(taggedTypeRefDeclaration); visit(taggedTypeRefDeclaration.getTaggedTypeRef()); } public void visitEmptyArraySize(EmptyArraySize emptyArraySize) { visitExpression(emptyArraySize); } public void visitDefine(Define define) { visitDeclaration(define); visit(define.getValue()); } public void visitTypeRefExpression(TypeRefExpression typeRefExpression) { visitExpression(typeRefExpression); visit(typeRefExpression.getType()); } public void visitNew(New new1) { visitExpression(new1); visit(new1.getType()); visit(new1.getConstruction()); } public void visitAnnotation(Annotation annotation) { visitElement(annotation); visit(annotation.getAnnotationClass()); visit(annotation.getDefaultArgument()); visit(annotation.getNamedArguments()); } public void visitEmptyDeclaration(EmptyDeclaration emptyDeclaration) { visitDeclaration(emptyDeclaration); } public void visitNewArray(NewArray newArray) { visitExpression(newArray); visit(newArray.getType()); visit(newArray.getDimensions()); visit(newArray.getInitialValues()); } public void visitArrayDeclarator(ArrayDeclarator arrayDeclarator) { visitTargettedDeclarator(arrayDeclarator); visit(arrayDeclarator.getDimensions()); } public void visitDirectDeclarator(DirectDeclarator directDeclarator) { visitDeclarator(directDeclarator); } public void visitFunctionDeclarator(FunctionDeclarator functionDeclarator) { visitTargettedDeclarator(functionDeclarator); visit(functionDeclarator.getArgs()); } public void visitPointerDeclarator(PointerDeclarator pointerDeclarator) { visitTargettedDeclarator(pointerDeclarator); } private void visitTargettedDeclarator(TargettedDeclarator targettedDeclarator) { visitDeclarator(targettedDeclarator); visit(targettedDeclarator.getTarget()); } public void visitModifiableElement(ModifiableElement modifiableElement) { visitElement(modifiableElement); visit(modifiableElement.getAnnotations()); } public void visitTaggedTypeRef(TaggedTypeRef taggedTypeRef) { visitTypeRef(taggedTypeRef); visit(taggedTypeRef.getTag()); visit(taggedTypeRef.getOriginalTag()); if (taggedTypeRef.getParentNamespace() != null) visitIdentifier(taggedTypeRef.getParentNamespace()); } public void visitBlock(Block block) { visitStatement(block); visit(block.getStatements()); } public void visitExpressionStatement(ExpressionStatement expressionStatement) { visitStatement(expressionStatement); visit(expressionStatement.getExpression()); } public void visitStatement(Statement statement) { visitModifiableElement(statement); //visitElement(statement); } public void visitIf(If if1) { visitControlStructure(if1); visit(if1.getCondition()); visit(if1.getThenBranch()); visit(if1.getElseBranch()); } public void visitNullExpression(NullExpression nullExpression) { visitExpression(nullExpression); } public void visitReturn(Return return1) { visitSingleValueStatement(return1); } public void visitOpaqueExpression(OpaqueExpression opaqueExpression) { visitExpression(opaqueExpression); } public void visitArrayAccess(ArrayAccess arrayAccess) { visitExpression(arrayAccess); visit(arrayAccess.getTarget()); visit(arrayAccess.getIndex()); } public void visitAssignmentOp(AssignmentOp assignment) { visitExpression(assignment); visit(assignment.getTarget()); visit(assignment.getValue()); } public void visitConditionalExpression( ConditionalExpression conditionalExpression) { visitExpression(conditionalExpression); visit(conditionalExpression.getTest()); visit(conditionalExpression.getThenValue()); visit(conditionalExpression.getElseValue()); } public void visitExpressionSequence(ExpressionSequence expressionSequence) { visitExpression(expressionSequence); visit(expressionSequence.getExpressions()); } public void visitExpressionsBlock(ExpressionsBlock expressionSequence) { visitExpression(expressionSequence); visit(expressionSequence.getExpressions()); } public void visitSimpleIdentifier(SimpleIdentifier simpleIdentifier) { visitIdentifier(simpleIdentifier); visit(simpleIdentifier.getTemplateArguments()); } public void visitIdentifier(Identifier identifier) { visitElement(identifier); } public void visitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier) { visitIdentifier(qualifiedIdentifier); visit(qualifiedIdentifier.getIdentifiers()); } /*public void visitDeclarationStatement( DeclarationStatement declarationStatement) { visitStatement(declarationStatement); visit(declarationStatement.getDeclaration()); }*/ protected Scanner visit(Element e) { if (e != null) { try { e.accept(this); } catch (StackOverflowError err) { throw new RuntimeException("Overflow while visiting :\n" + e, err); } } return this; } protected Scanner visit(List<? extends Element> list) { if (list != null) for (Element e : copy(list)) if (e != null) e.accept(this); return this; } protected Scanner visit(Map<String, ? extends Element> map) { if (map != null) for (Element e : copy(map.values())) if (e != null) e.accept(this); return this; } public void visitThrow(Throw t) { visitStatement(t); visit(t.getExpression()); } public void visitProperty(Property property) { visitDeclaration(property); visit(property.getDeclaration()); } public void visitFriendDeclaration(FriendDeclaration friendDeclaration) { visitDeclaration(friendDeclaration); visit(friendDeclaration.getFriend()); } public void visitControlStructure(Statement tr) { visitStatement(tr); } public void visitTry(Try tr) { visitControlStructure(tr); visit(tr.getTryStatement()); visit(tr.getFinallyStatement()); visit(tr.getCatches()); } public void visitFor(For aFor) { visitControlStructure(aFor); visit(aFor.getInitStatements()); visit(aFor.getCondition()); visit(aFor.getPostStatements()); visit(aFor.getBody()); } public void visitCatch(Catch ca) { visitControlStructure(ca); visit(ca.getDeclaration()); visit(ca.getBody()); } public void visitTemplate(Template template) { visitDeclaration(template); visit(template.getArgs()); visit(template.getDeclaration()); } @Override public void visitWhile(While whileStat) { visitControlStructure(whileStat); visit(whileStat.getCondition()); visit(whileStat.getBody()); } @Override public void visitDoWhile(DoWhile doWhileStat) { visitWhile(doWhileStat); } public void visitDeclarations(Declarations declarations) { visitDeclaration(declarations); visit(declarations.getDeclarations()); } public void visitExternDeclarations(ExternDeclarations externDeclarations) { visitDeclarations(externDeclarations); } @Override public void visitNamespace(Namespace ns) { visit(ns.getName()); visitDeclarations(ns); } public void visitPrecisionTypeRef(PrecisionTypeRef tr) { visitTargettedTypeRef(tr); visit(tr.getPrecision()); } public void visitDelete(Delete aThis) { visitSingleValueStatement(aThis); } private void visitSingleValueStatement(Statement.SingleValueStatement s) { visitStatement(s); visit(s.getValue()); } public void visitInclude(Include aThis) { visitDeclaration(aThis); } public void visitStatementDeclaration(StatementDeclaration aThis) { visitStatement(aThis); visitDeclaration(aThis); visit(aThis.getStatement()); } }