/*
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());
}
}