/******************************************************************************* * Copyright (c) 2009-2013 CWI * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * * Jouke Stoel - Jouke.Stoel@cwi.nl (CWI) * * Anastasia Izmaylova - A.Izmaylova@cwi.nl - CWI *******************************************************************************/ package lang.java.jdt.internal; import static org.rascalmpl.eclipse.library.lang.java.jdt.internal.Java.ADT_ENTITY; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Stack; import org.eclipse.imp.pdb.facts.IConstructor; import org.eclipse.imp.pdb.facts.IMapWriter; import org.eclipse.imp.pdb.facts.ISourceLocation; import org.eclipse.imp.pdb.facts.IValue; import org.eclipse.imp.pdb.facts.IValueFactory; import org.eclipse.imp.pdb.facts.exceptions.UndeclaredConstructorException; import org.eclipse.imp.pdb.facts.type.TypeFactory; import org.eclipse.imp.pdb.facts.type.TypeStore; import org.eclipse.jdt.core.dom.*; import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; @SuppressWarnings({"deprecation", "rawtypes"}) public class JdtAstToRascalAstConverter extends ASTVisitor { // private static final String ANNOTATION_JAVA_TYPE = "javaType"; private static final String DATATYPE_OPTION = "Option"; private static final String DATATYPE_RASCAL_AST_NODE = "AstNode"; /* * Richer binding information of a Java node */ public static final String ANNOTATION_JAVA_METHOD_BINDING = "methodBinding"; public static final String ANNOTATION_JAVA_PACKAGE_BINDING = "packageBinding"; public static final String ANNOTATION_JAVA_TYPE_BINDING = "typeBinding"; public static final String ANNOTATION_JAVA_VARIABLE_BINDING = "variableBinding"; public static final String ANNOTATION_JAVA_BINDINGS = "bindings"; public static final String ANNOTATION_SOURCE_LOCATION = "location"; private IValue ownValue; private final IValueFactory values; private final TypeStore typeStore; private static final TypeFactory TF = TypeFactory.getInstance(); private final BindingConverter bindingConverter; private CompilationUnit compilUnit; private ISourceLocation loc; private BindingsImporter bindingsImporter; private final org.eclipse.imp.pdb.facts.type.Type DATATYPE_RASCAL_AST_NODE_TYPE; private final org.eclipse.imp.pdb.facts.type.Type DATATYPE_OPTION_TYPE; private final Set<String> annotations; private final boolean collectBindings; public JdtAstToRascalAstConverter(final IValueFactory values, final TypeStore typeStore, final BindingConverter bindingConverter, boolean collectBindings) { this.values = values; this.typeStore = typeStore; this.bindingConverter = bindingConverter; this.bindingsImporter = new BindingsImporter(this.values, this.bindingConverter); this.DATATYPE_RASCAL_AST_NODE_TYPE = this.typeStore.lookupAbstractDataType(DATATYPE_RASCAL_AST_NODE); this.annotations = this.typeStore.getAnnotations(DATATYPE_RASCAL_AST_NODE_TYPE).keySet(); this.DATATYPE_OPTION_TYPE = this.typeStore.lookupAbstractDataType(DATATYPE_OPTION); this.collectBindings = collectBindings; } public void set(CompilationUnit compilUnit) { this.compilUnit = compilUnit; } public void set(ISourceLocation loc) { this.loc = loc; } public BindingsImporter getBindingsImporter() { return this.bindingsImporter; } public IValue getValue() { return this.ownValue; } public void setRascalAstNodeAnnotation(String annoName, IValue annoValue) { if(this.ownValue == null) return ; if(this.ownValue.getType().equals(DATATYPE_RASCAL_AST_NODE_TYPE) && annotations.contains(annoName)) this.ownValue = ((IConstructor) this.ownValue).asAnnotatable().setAnnotation(annoName, annoValue); } private IValueList parseModifiers(int modifiers) { IValueList modifierList = new IValueList(values); if (Modifier.isPublic(modifiers)) { modifierList.add(values.constructor(Java.CONS_PUBLIC)); } if (Modifier.isProtected(modifiers)) { modifierList.add(values.constructor(Java.CONS_PROTECTED)); } if (Modifier.isPrivate(modifiers)) { modifierList.add(values.constructor(Java.CONS_PRIVATE)); } if (Modifier.isStatic(modifiers)) { modifierList.add(values.constructor(Java.CONS_STATIC)); } if (Modifier.isAbstract(modifiers)) { modifierList.add(values.constructor(Java.CONS_ABSTRACT)); } if (Modifier.isFinal(modifiers)) { modifierList.add(values.constructor(Java.CONS_FINAL)); } if (Modifier.isSynchronized(modifiers)) { modifierList.add(values.constructor(Java.CONS_SYNCHRONIZED)); } if (Modifier.isVolatile(modifiers)) { modifierList.add(values.constructor(Java.CONS_VOLATILE)); } if (Modifier.isNative(modifiers)) { modifierList.add(values.constructor(Java.CONS_NATIVE)); } if (Modifier.isStrictfp(modifiers)) { modifierList.add(values.constructor(Java.CONS_STRICTFP)); } if (Modifier.isTransient(modifiers)) { modifierList.add(values.constructor(Java.CONS_TRANSIENT)); } return modifierList; } private java.util.Map.Entry<IValueList, IValueList> parseExtendedModifiers(List ext) { IValueList modifierList = new IValueList(values); IValueList annotationsList = new IValueList(values); for (Iterator it = ext.iterator(); it.hasNext();) { ASTNode p = (ASTNode) it.next(); if(p instanceof IExtendedModifier) { IValue val = visitChild(p); if(((IExtendedModifier) p).isModifier()) { modifierList.add(val); } else if(((IExtendedModifier) p).isAnnotation()) { annotationsList.add(val); } } } return new java.util.AbstractMap.SimpleEntry<IValueList, IValueList>(modifierList, annotationsList); } private java.util.Map.Entry<IValueList, IValueList> parseExtendedModifiers(BodyDeclaration node) { if (node.getAST().apiLevel() == AST.JLS2) { return new java.util.AbstractMap.SimpleEntry<IValueList, IValueList>(parseModifiers(node.getModifiers()), new IValueList(values)); } else { return parseExtendedModifiers(node.modifiers()); } } private IValue optional(IValue value) { if (value == null) { return none(); } else { return some(value); } } private IValue none() { org.eclipse.imp.pdb.facts.type.Type constructor = typeStore.lookupConstructor(DATATYPE_OPTION_TYPE, "none", TF.tupleEmpty()); if(constructor != null) return values.constructor(constructor, new IValue[] {}); // DATATYPE_OPTION_TYPE.make(values, typeStore, "none", new IValue[] {}); throw new UndeclaredConstructorException("none", TF.tupleEmpty()); } private IValue some(IValue value) { org.eclipse.imp.pdb.facts.type.Type constructor = typeStore.lookupConstructor(DATATYPE_OPTION_TYPE, "some", TF.tupleType(value)); if(constructor != null) return values.constructor(constructor, value); throw new UndeclaredConstructorException("some", TF.tupleType(value)); // DATATYPE_OPTION_TYPE.make(values, typeStore, "some", value); } private IValue visitChild(ASTNode node) { node.accept(this); return this.getValue(); } private String getNodeName(ASTNode node) { return node.getClass().getSimpleName(); } private IValue constructRascalNode(ASTNode node, IValue... children) { String constructorName = getNodeName(node); // Make sure that the constructor name starts with a lowercase character String modifiedConstructorName = constructorName.substring(0, 1).toLowerCase() + constructorName.substring(1); /* * Does not proper deal with possible initializers * if (rascalValue instanceof IConstructor) { IValue type = resolveType(node); if (type != null) { IConstructor rascalNode = (IConstructor) rascalValue; rascalValue = rascalNode.setAnnotation(ANNOTATION_JAVA_TYPE, type); } } */ org.eclipse.imp.pdb.facts.type.Type constructor = typeStore.lookupConstructor(DATATYPE_RASCAL_AST_NODE_TYPE, modifiedConstructorName, TF.tupleType(children)); if(constructor != null) return values.constructor(constructor, children); throw new UndeclaredConstructorException(modifiedConstructorName, TF.tupleType(children)); // DATATYPE_RASCAL_AST_NODE_TYPE.make(values, typeStore, modifiedConstructorName, children); } /* private IValue resolveType(ASTNode node) { IValue type = null; if (node instanceof Type) { type = bindingConverter.getEntity(((Type) node).resolveBinding()); } else if (node instanceof AbstractTypeDeclaration) { type = bindingConverter.getEntity(((AbstractTypeDeclaration) node).resolveBinding()); } else if (node instanceof AnonymousClassDeclaration) { type = bindingConverter.getEntity(((AnonymousClassDeclaration) node).resolveBinding()); } else if (node instanceof Expression) { type = (((Expression) node).resolveTypeBinding() != null) ? bindingConverter.getEntity(((Expression) node).resolveTypeBinding()) : null; } else if (node instanceof TypeDeclarationStatement) { type = bindingConverter.getEntity(((TypeDeclarationStatement) node).resolveBinding()); } else if (node instanceof TypeParameter) { type = bindingConverter.getEntity(((TypeParameter) node).resolveBinding()); } else if (node instanceof EnumDeclaration) { type = bindingConverter.getEntity(((EnumDeclaration) node).resolveBinding()); } else if (node instanceof AnnotationTypeDeclaration) { type = bindingConverter.getEntity(((AnnotationTypeDeclaration) node).resolveBinding()); } return type; } */ // private IValue constructRascalNode(String dataType, String constructorName, IValue... children) { // // Make sure that the constructor name starts with a lowercase character // String modifiedConstructorName = constructorName.substring(0, 1).toLowerCase() + constructorName.substring(1); // org.eclipse.imp.pdb.facts.type.Type type = typeStore.lookupAbstractDataType(dataType); // return type.make(values, typeStore, modifiedConstructorName, children); // } // private IValue constructRascalNode(String dataType, String constructorName) { // org.eclipse.imp.pdb.facts.type.Type constructor = getConstructor(dataType, constructorName); // // return constructor.make(values); // } // // private org.eclipse.imp.pdb.facts.type.Type getConstructor(String dataType, String constructorName) { // org.eclipse.imp.pdb.facts.type.Type type = typeStore.lookupAbstractDataType(dataType); // // // Make sure that the constructor name starts with a lowercase character // String modifiedConstructorName = constructorName.substring(0, 1).toLowerCase() + constructorName.substring(1); // Set<org.eclipse.imp.pdb.facts.type.Type> constructors = typeStore.lookupConstructor(type, modifiedConstructorName); // // // There should be only one constructor. // return constructors.iterator().next(); // } /* * 'preVisit' and 'postVisit' manage (scope) stacks of the bindingsImporter in a proper order * and resolve java bindings for a node if any */ public void preVisit(ASTNode node) { if(collectBindings) { bindingsImporter.resolveBindings(node); bindingsImporter.manageStacks(node, true); } } public void postVisit(ASTNode node) { // IValue javaType = bindingsImporter.popJavaType(); // if(javaType != null) // setRascalAstNodeAnnotation(ANNOTATION_JAVA_TYPE, javaType); if (collectBindings) { setRascalAstNodeAnnotation(ANNOTATION_JAVA_BINDINGS, bindingsImporter.popBindings()); bindingsImporter.manageStacks(node, false); } int start = node.getStartPosition(); int end = start + node.getLength() - 1; if(compilUnit != null && loc != null) setRascalAstNodeAnnotation(ANNOTATION_SOURCE_LOCATION, values.sourceLocation(loc.getURI(), start, node.getLength(), compilUnit.getLineNumber(start), compilUnit.getLineNumber(end), compilUnit.getColumnNumber(start), compilUnit.getColumnNumber(end))); else System.err.println("The 'location' annotation can not be added to the node"); } public boolean visit(AnnotationTypeDeclaration node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers = parseExtendedModifiers(node.modifiers()); IValue name = values.string(node.getName().getFullyQualifiedName()); IValueList bodyDeclarations = new IValueList(values); for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext();) { BodyDeclaration d = (BodyDeclaration) it.next(); bodyDeclarations.add(visitChild(d)); } ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), name, bodyDeclarations.asList()); return false; } public boolean visit(AnnotationTypeMemberDeclaration node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers = parseExtendedModifiers(node.modifiers()); IValue typeArgument = visitChild(node.getType()); IValue name = values.string(node.getName().getFullyQualifiedName()); IValue defaultBlock = node.getDefault() == null ? null : visitChild(node.getDefault()); ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), typeArgument, name, optional(defaultBlock)); return false; } public boolean visit(AnonymousClassDeclaration node) { IValueList bodyDeclarations = new IValueList(values); for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext();) { BodyDeclaration b = (BodyDeclaration) it.next(); bodyDeclarations.add(visitChild(b)); } ownValue = constructRascalNode(node, bodyDeclarations.asList()); return false; } public boolean visit(ArrayAccess node) { IValue array = visitChild(node.getArray()); IValue index = visitChild(node.getIndex()); ownValue = constructRascalNode(node, array, index); return false; } public boolean visit(ArrayCreation node) { IValue type = visitChild(node.getType().getElementType()); IValueList dimensions = new IValueList(values); for (Iterator it = node.dimensions().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); dimensions.add(visitChild(e)); } IValue initializer = node.getInitializer() == null ? null : visitChild(node.getInitializer()); ownValue = constructRascalNode(node, type, dimensions.asList(), optional(initializer)); return false; } public boolean visit(ArrayInitializer node) { IValueList expressions = new IValueList(values); for (Iterator it = node.expressions().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); expressions.add(visitChild(e)); } ownValue = constructRascalNode(node, expressions.asList()); return false; } public boolean visit(ArrayType node) { IValue type = visitChild(node.getComponentType()); ownValue = constructRascalNode(node, type); return false; } public boolean visit(AssertStatement node) { IValue expression = visitChild(node.getExpression()); IValue message = node.getMessage() == null ? null : visitChild(node.getMessage()); ownValue = constructRascalNode(node, expression, optional(message)); return false; } public boolean visit(Assignment node) { IValue leftSide = visitChild(node.getLeftHandSide()); IValue rightSide = visitChild(node.getRightHandSide()); ownValue = constructRascalNode(node, leftSide, rightSide); return false; } public boolean visit(Block node) { IValueList statements = new IValueList(values); for (Iterator it = node.statements().iterator(); it.hasNext();) { Statement s = (Statement) it.next(); statements.add(visitChild(s)); } ownValue = constructRascalNode(node, statements.asList()); return false; } public boolean visit(BlockComment node) { ownValue = constructRascalNode(node); return false; } public boolean visit(BooleanLiteral node) { IValue booleanValue = values.bool(node.booleanValue()); ownValue = constructRascalNode(node, booleanValue); return false; } public boolean visit(BreakStatement node) { IValue label = node.getLabel() == null ? values.string("") : values.string(node.getLabel().getFullyQualifiedName()); ownValue = constructRascalNode(node, optional(label)); return false; } public boolean visit(CastExpression node) { IValue type = visitChild(node.getType()); IValue expression = visitChild(node.getExpression()); ownValue = constructRascalNode(node, type, expression); return false; } public boolean visit(CatchClause node) { IValue exception = visitChild(node.getException()); IValue body = visitChild(node.getBody()); ownValue = constructRascalNode(node, exception, body); return false; } public boolean visit(CharacterLiteral node) { IValue value = values.string(node.getEscapedValue()); ownValue = constructRascalNode(node, value); return false; } public boolean visit(ClassInstanceCreation node) { IValue expression = node.getExpression() == null ? null : visitChild(node.getExpression()); IValue type = null; IValueList genericTypes = new IValueList(values); if (node.getAST().apiLevel() == AST.JLS2) { type = visitChild(node.getName()); } else { type = visitChild(node.getType()); if (!node.typeArguments().isEmpty()) { for (Iterator it = node.typeArguments().iterator(); it.hasNext();) { Type t = (Type) it.next(); genericTypes.add(visitChild(t)); } } } IValueList arguments = new IValueList(values); for (Iterator it = node.arguments().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); arguments.add(visitChild(e)); } IValue anonymousClassDeclaration = node.getAnonymousClassDeclaration() == null ? null : visitChild(node.getAnonymousClassDeclaration()); ownValue = constructRascalNode(node, optional(expression), type, genericTypes.asList(), arguments.asList(), optional(anonymousClassDeclaration)); return false; } public boolean visit(CompilationUnit node) { IValue packageOfUnit = node.getPackage() == null ? null : visitChild(node.getPackage()); IValueList imports = new IValueList(values); for (Iterator it = node.imports().iterator(); it.hasNext();) { ImportDeclaration d = (ImportDeclaration) it.next(); imports.add(visitChild(d)); } IValueList typeDeclarations = new IValueList(values); for (Iterator it = node.types().iterator(); it.hasNext();) { AbstractTypeDeclaration d = (AbstractTypeDeclaration) it.next(); typeDeclarations.add(visitChild(d)); } ownValue = constructRascalNode(node, optional(packageOfUnit), imports.asList(), typeDeclarations.asList()); return false; } public boolean visit(ConditionalExpression node) { IValue expression = visitChild(node.getExpression()); IValue thenBranch = visitChild(node.getThenExpression()); IValue elseBranch = visitChild(node.getElseExpression()); ownValue = constructRascalNode(node, expression, thenBranch, elseBranch); return false; } public boolean visit(ConstructorInvocation node) { IValueList types = new IValueList(values); if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeArguments().isEmpty()) { for (Iterator it = node.typeArguments().iterator(); it.hasNext();) { Type t = (Type) it.next(); types.add(visitChild(t)); } } } IValueList arguments = new IValueList(values); for (Iterator it = node.arguments().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); arguments.add(visitChild(e)); } ownValue = constructRascalNode(node, types.asList(), arguments.asList()); return false; } public boolean visit(ContinueStatement node) { IValue label = node.getLabel() == null ? null : values.string(node.getLabel().getFullyQualifiedName()); ownValue = constructRascalNode(node, optional(label)); return false; } public boolean visit(DoStatement node) { IValue body = visitChild(node.getBody()); IValue whileExpression = visitChild(node.getExpression()); ownValue = constructRascalNode(node, body, whileExpression); return false; } public boolean visit(EmptyStatement node) { ownValue = constructRascalNode(node); return false; } public boolean visit(EnhancedForStatement node) { IValue parameter = visitChild(node.getParameter()); IValue collectionExpression = visitChild(node.getExpression()); IValue body = visitChild(node.getBody()); ownValue = constructRascalNode(node, parameter, collectionExpression, body); return false; } public boolean visit(EnumConstantDeclaration node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers = parseExtendedModifiers(node.modifiers()); IValue name = values.string(node.getName().getFullyQualifiedName()); IValueList arguments = new IValueList(values); if (!node.arguments().isEmpty()) { for (Iterator it = node.arguments().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); arguments.add(visitChild(e)); } } IValue anonymousClassDeclaration = node.getAnonymousClassDeclaration() == null ? null : visitChild(node.getAnonymousClassDeclaration()); ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), name, arguments.asList(), optional(anonymousClassDeclaration)); return false; } public boolean visit(EnumDeclaration node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers = parseExtendedModifiers(node.modifiers()); IValue name = values.string(node.getName().getFullyQualifiedName()); IValueList implementedInterfaces = new IValueList(values); if (!node.superInterfaceTypes().isEmpty()) { for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext();) { Type t = (Type) it.next(); implementedInterfaces.add(visitChild(t)); } } IValueList enumConstants = new IValueList(values); for (Iterator it = node.enumConstants().iterator(); it.hasNext();) { EnumConstantDeclaration d = (EnumConstantDeclaration) it.next(); enumConstants.add(visitChild(d)); } IValueList bodyDeclarations = new IValueList(values); if (!node.bodyDeclarations().isEmpty()) { for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext();) { BodyDeclaration d = (BodyDeclaration) it.next(); bodyDeclarations.add(visitChild(d)); } } ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), name, implementedInterfaces.asList(), enumConstants.asList(), bodyDeclarations.asList()); return false; } public boolean visit(ExpressionStatement node) { IValue expression = visitChild(node.getExpression()); ownValue = constructRascalNode(node, expression); return false; } public boolean visit(FieldAccess node) { IValue expression = visitChild(node.getExpression()); IValue name = values.string(node.getName().getFullyQualifiedName()); ownValue = constructRascalNode(node, expression, name); return false; } public boolean visit(FieldDeclaration node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers = parseExtendedModifiers(node); IValue type = visitChild(node.getType()); IValueList fragments = new IValueList(values); for (Iterator it = node.fragments().iterator(); it.hasNext();) { VariableDeclarationFragment f = (VariableDeclarationFragment) it.next(); fragments.add(visitChild(f)); } ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), type, fragments.asList()); return false; } public boolean visit(ForStatement node) { IValueList initializers = new IValueList(values); for (Iterator it = node.initializers().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); initializers.add(visitChild(e)); } IValue booleanExpression = node.getExpression() == null ? null : visitChild(node.getExpression()); IValueList updaters = new IValueList(values); for (Iterator it = node.updaters().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); updaters.add(visitChild(e)); } IValue body = visitChild(node.getBody()); ownValue = constructRascalNode(node, initializers.asList(), optional(booleanExpression), updaters.asList(), body); return false; } public boolean visit(IfStatement node) { IValue booleanExpression = visitChild(node.getExpression()); IValue thenStatement = visitChild(node.getThenStatement()); IValue elseStatement = node.getElseStatement() == null ? null : visitChild(node.getElseStatement()); ownValue = constructRascalNode(node, booleanExpression, thenStatement, optional(elseStatement)); return false; } public boolean visit(ImportDeclaration node) { IValue name = values.string(node.getName().getFullyQualifiedName()); IValue staticImport = values.bool(false); if (node.getAST().apiLevel() >= AST.JLS3) { staticImport = values.bool(node.isStatic()); } IValue onDemand = values.bool(node.isOnDemand()); ownValue = constructRascalNode(node, name, staticImport, onDemand); return false; } public boolean visit(InfixExpression node) { IValue operator = values.string(node.getOperator().toString()); IValue leftSide = visitChild(node.getLeftOperand()); IValue rightSide = visitChild(node.getRightOperand()); IValueList extendedOperands = new IValueList(values); if (node.hasExtendedOperands()) { for (Iterator it = node.extendedOperands().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); extendedOperands.add(visitChild(e)); } } ownValue = constructRascalNode(node, operator, leftSide, rightSide, extendedOperands.asList()); return false; } public boolean visit(Initializer node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers = parseExtendedModifiers(node); IValue body = visitChild(node.getBody()); ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), body); return false; } public boolean visit(InstanceofExpression node) { IValue leftSide = visitChild(node.getLeftOperand()); IValue rightSide = visitChild(node.getRightOperand()); ownValue = constructRascalNode(node, leftSide, rightSide); return false; } public boolean visit(Javadoc node) { ownValue = constructRascalNode(node); return false; } public boolean visit(LabeledStatement node) { IValue label = values.string(node.getLabel().getFullyQualifiedName()); IValue body = visitChild(node.getBody()); ownValue = constructRascalNode(node, label, body); return false; } public boolean visit(LineComment node) { ownValue = constructRascalNode(node); return false; } public boolean visit(MarkerAnnotation node) { IValue typeName = values.string(node.getTypeName().getFullyQualifiedName()); ownValue = constructRascalNode(node, typeName); return false; } public boolean visit(MemberRef node) { return false; } public boolean visit(MemberValuePair node) { IValue name = values.string(node.getName().getFullyQualifiedName()); IValue value = visitChild(node.getValue()); ownValue = constructRascalNode(node, name, value); return false; } public boolean visit(MethodDeclaration node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers = parseExtendedModifiers(node); IValueList genericTypes = new IValueList(values); if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeParameters().isEmpty()) { for (Iterator it = node.typeParameters().iterator(); it.hasNext();) { TypeParameter t = (TypeParameter) it.next(); genericTypes.add(visitChild(t)); } } } IValue returnType = null; if (!node.isConstructor()) { if (node.getAST().apiLevel() == AST.JLS2) { returnType = visitChild(node.getReturnType()); } else if (node.getReturnType2() != null) { returnType = visitChild(node.getReturnType2()); } else { // methods really ought to have a return type returnType = values.constructor(Java.CONS_VOID); } } IValue name = values.string(node.getName().getFullyQualifiedName()); IValueList parameters = new IValueList(values); for (Iterator it = node.parameters().iterator(); it.hasNext();) { SingleVariableDeclaration v = (SingleVariableDeclaration) it.next(); parameters.add(visitChild(v)); } /* * for (int i = 0; i < node.getExtraDimensions(); i++) { * //this.buffer.append("[]"); //$NON-NLS-1$ // TODO: Do these need to be included in the node tree? * } */ IValueList possibleExceptions = new IValueList(values); if (!node.thrownExceptions().isEmpty()) { for (Iterator it = node.thrownExceptions().iterator(); it.hasNext();) { Name n = (Name) it.next(); possibleExceptions.add(visitChild(n)); } } IValue body = node.getBody() == null ? null : visitChild(node.getBody()); ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), genericTypes.asList(), optional(returnType), name, parameters.asList(), possibleExceptions.asList(), optional(body)); return false; } public boolean visit(MethodInvocation node) { IValue expression = node.getExpression() == null ? null : visitChild(node.getExpression()); IValueList genericTypes = new IValueList(values); if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeArguments().isEmpty()) { for (Iterator it = node.typeArguments().iterator(); it.hasNext();) { Type t = (Type) it.next(); genericTypes.add(visitChild(t)); } } } IValue name = values.string(node.getName().getFullyQualifiedName()); IValueList arguments = new IValueList(values); for (Iterator it = node.arguments().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); arguments.add(visitChild(e)); } ownValue = constructRascalNode(node, optional(expression), genericTypes.asList(), name, arguments.asList()); return false; } public boolean visit(MethodRef node) { return false; } public boolean visit(MethodRefParameter node) { return false; } public boolean visit(Modifier node) { if (node.getKeyword().equals(ModifierKeyword.PUBLIC_KEYWORD)) { ownValue = values.constructor(Java.CONS_PUBLIC); } else if (node.getKeyword().equals(ModifierKeyword.PROTECTED_KEYWORD)) { ownValue = values.constructor(Java.CONS_PROTECTED); } else if (node.getKeyword().equals(ModifierKeyword.PRIVATE_KEYWORD)) { ownValue = values.constructor(Java.CONS_PRIVATE); } else if (node.getKeyword().equals(ModifierKeyword.STATIC_KEYWORD)) { ownValue = values.constructor(Java.CONS_STATIC); } else if (node.getKeyword().equals(ModifierKeyword.ABSTRACT_KEYWORD)) { ownValue = values.constructor(Java.CONS_ABSTRACT); } else if (node.getKeyword().equals(ModifierKeyword.FINAL_KEYWORD)) { ownValue = values.constructor(Java.CONS_FINAL); } else if (node.getKeyword().equals(ModifierKeyword.SYNCHRONIZED_KEYWORD)) { ownValue = values.constructor(Java.CONS_SYNCHRONIZED); } else if (node.getKeyword().equals(ModifierKeyword.VOLATILE_KEYWORD)) { ownValue = values.constructor(Java.CONS_VOLATILE); } else if (node.getKeyword().equals(ModifierKeyword.NATIVE_KEYWORD)) { ownValue = values.constructor(Java.CONS_NATIVE); } else if (node.getKeyword().equals(ModifierKeyword.STRICTFP_KEYWORD)) { ownValue = values.constructor(Java.CONS_STRICTFP); } else if (node.getKeyword().equals(ModifierKeyword.TRANSIENT_KEYWORD)) { ownValue = values.constructor(Java.CONS_TRANSIENT); } return false; } public boolean visit(NormalAnnotation node) { IValue typeName = values.string(node.getTypeName().getFullyQualifiedName()); IValueList memberValuePairs = new IValueList(values); for (Iterator it = node.values().iterator(); it.hasNext();) { MemberValuePair p = (MemberValuePair) it.next(); memberValuePairs.add(visitChild(p)); } ownValue = constructRascalNode(node, typeName, memberValuePairs.asList()); return false; } public boolean visit(NullLiteral node) { ownValue = constructRascalNode(node); return false; } public boolean visit(NumberLiteral node) { IValue number = values.string(node.getToken()); ownValue = constructRascalNode(node, number); return false; } public boolean visit(PackageDeclaration node) { IValue name = values.string(node.getName().getFullyQualifiedName()); IValueList annotations = new IValueList(values); if (node.getAST().apiLevel() >= AST.JLS3) { for (Iterator it = node.annotations().iterator(); it.hasNext();) { Annotation p = (Annotation) it.next(); annotations.add(visitChild(p)); } } ownValue = constructRascalNode(node, name, annotations.asList()); return false; } public boolean visit(ParameterizedType node) { IValue type = visitChild(node.getType()); IValueList genericTypes = new IValueList(values); for (Iterator it = node.typeArguments().iterator(); it.hasNext();) { Type t = (Type) it.next(); genericTypes.add(visitChild(t)); } ownValue = constructRascalNode(node, type, genericTypes.asList()); return false; } public boolean visit(ParenthesizedExpression node) { IValue expression = visitChild(node.getExpression()); ownValue = constructRascalNode(node, expression); return false; } public boolean visit(PostfixExpression node) { IValue operand = visitChild(node.getOperand()); IValue operator = values.string(node.getOperator().toString()); ownValue = constructRascalNode(node, operand, operator); return false; } public boolean visit(PrefixExpression node) { IValue operand = visitChild(node.getOperand()); IValue operator = values.string(node.getOperator().toString()); ownValue = constructRascalNode(node, operand, operator); return false; } public boolean visit(PrimitiveType node) { IValue type; if (node.getPrimitiveTypeCode().equals(PrimitiveType.BOOLEAN)) { type = values.constructor(Java.CONS_BOOLEAN); } else if (node.getPrimitiveTypeCode().equals(PrimitiveType.BYTE)) { type = values.constructor(Java.CONS_BYTE); } else if (node.getPrimitiveTypeCode().equals(PrimitiveType.CHAR)) { type = values.constructor(Java.CONS_CHAR); } else if (node.getPrimitiveTypeCode().equals(PrimitiveType.DOUBLE)) { type = values.constructor(Java.CONS_DOUBLE); } else if (node.getPrimitiveTypeCode().equals(PrimitiveType.FLOAT)) { type = values.constructor(Java.CONS_FLOAT); } else if (node.getPrimitiveTypeCode().equals(PrimitiveType.INT)) { type = values.constructor(Java.CONS_INT); } else if (node.getPrimitiveTypeCode().equals(PrimitiveType.LONG)) { type = values.constructor(Java.CONS_LONG); } else if (node.getPrimitiveTypeCode().equals(PrimitiveType.SHORT)) { type = values.constructor(Java.CONS_SHORT); } else { type = values.constructor(Java.CONS_VOID); } ownValue = constructRascalNode(node, type); return false; } public boolean visit(QualifiedName node) { IValue qualifier = visitChild(node.getQualifier()); IValue name = values.string((node.getName().getFullyQualifiedName())); ownValue = constructRascalNode(node, qualifier, name); return false; } public boolean visit(QualifiedType node) { IValue qualifier = visitChild(node.getQualifier()); IValue name = values.string((node.getName().getFullyQualifiedName())); ownValue = constructRascalNode(node, qualifier, name); return false; } public boolean visit(ReturnStatement node) { IValue expression = node.getExpression() == null ? null : visitChild(node.getExpression()); ownValue = constructRascalNode(node, optional(expression)); return false; } public boolean visit(SimpleName node) { IValue value = values.string(node.getFullyQualifiedName()); ownValue = constructRascalNode(node, value); return false; } public boolean visit(SimpleType node) { IValue type = values.string(node.getName().getFullyQualifiedName()); ownValue = constructRascalNode(node, type); return false; } public boolean visit(SingleMemberAnnotation node) { IValue name = values.string(node.getTypeName().getFullyQualifiedName()); IValue value = visitChild(node.getValue()); ownValue = constructRascalNode(node, name, value); return false; } public boolean visit(SingleVariableDeclaration node) { IValue name = values.string(node.getName().getFullyQualifiedName()); java.util.Map.Entry<IValueList, IValueList> extendedModifiers; if (node.getAST().apiLevel() == AST.JLS2) { extendedModifiers = new java.util.AbstractMap.SimpleEntry<IValueList, IValueList>(parseModifiers(node.getModifiers()), new IValueList(values)); } else { extendedModifiers = parseExtendedModifiers(node.modifiers()); } IValue type = visitChild(node.getType()); IValue initializer = node.getInitializer() == null ? null : visitChild(node.getInitializer()); IValue isVarags = values.bool(false); if (node.getAST().apiLevel() >= AST.JLS3) { isVarags = values.bool(node.isVarargs()); } /* * for (int i = 0; i < node.getExtraDimensions(); i++) { * //TODO: What todo with the extra dimensions... * this.buffer.append("[]"); * //$NON-NLS-1$ } */ ownValue = constructRascalNode(node, name, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), type, optional(initializer), isVarags); return false; } public boolean visit(StringLiteral node) { IValue value = values.string(node.getEscapedValue()); ownValue = constructRascalNode(node, value); return false; } public boolean visit(SuperConstructorInvocation node) { IValue expression = node.getExpression() == null ? null : visitChild(node.getExpression()); IValueList genericTypes = new IValueList(values); if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeArguments().isEmpty()) { for (Iterator it = node.typeArguments().iterator(); it.hasNext();) { Type t = (Type) it.next(); genericTypes.add(visitChild(t)); } } } IValueList arguments = new IValueList(values); for (Iterator it = node.arguments().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); arguments.add(visitChild(e)); } ownValue = constructRascalNode(node, optional(expression), genericTypes.asList(), arguments.asList()); return false; } public boolean visit(SuperFieldAccess node) { IValue qualifier = node.getQualifier() == null ? null : visitChild(node.getQualifier()); IValue name = values.string((node.getName().getFullyQualifiedName())); ownValue = constructRascalNode(node, optional(qualifier), name); return false; } public boolean visit(SuperMethodInvocation node) { IValue qualifier = node.getQualifier() == null ? null : visitChild(node.getQualifier()); IValueList genericTypes = new IValueList(values); if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeArguments().isEmpty()) { for (Iterator it = node.typeArguments().iterator(); it.hasNext();) { Type t = (Type) it.next(); genericTypes.add(visitChild(t)); } } } IValue name = values.string(node.getName().getFullyQualifiedName()); IValueList arguments = new IValueList(values); for (Iterator it = node.arguments().iterator(); it.hasNext();) { Expression e = (Expression) it.next(); arguments.add(visitChild(e)); } ownValue = constructRascalNode(node, optional(qualifier), genericTypes.asList(), name, arguments.asList()); return false; } public boolean visit(SwitchCase node) { IValue isDefault = values.bool(node.isDefault()); IValue expression = node.getExpression() == null ? null : visitChild(node.getExpression()); ownValue = constructRascalNode(node, isDefault, optional(expression)); return false; } public boolean visit(SwitchStatement node) { IValue expression = visitChild(node.getExpression()); IValueList statements = new IValueList(values); for (Iterator it = node.statements().iterator(); it.hasNext();) { Statement s = (Statement) it.next(); statements.add(visitChild(s)); } ownValue = constructRascalNode(node, expression, statements.asList()); return false; } public boolean visit(SynchronizedStatement node) { IValue expression = visitChild(node.getExpression()); IValue body = visitChild(node.getBody()); ownValue = constructRascalNode(node, expression, body); return false; } public boolean visit(TagElement node) { // TODO: What to do with JavaDoc? return false; } public boolean visit(TextElement node) { // TODO: What to do with JavaDoc? return false; } public boolean visit(ThisExpression node) { IValue qualifier = node.getQualifier() == null ? null : visitChild(node.getQualifier()); ownValue = constructRascalNode(node, optional(qualifier)); return false; } public boolean visit(ThrowStatement node) { IValue expression = visitChild(node.getExpression()); ownValue = constructRascalNode(node, expression); return false; } public boolean visit(TryStatement node) { IValue body = visitChild(node.getBody()); IValueList catchClauses = new IValueList(values); for (Iterator it = node.catchClauses().iterator(); it.hasNext();) { CatchClause cc = (CatchClause) it.next(); catchClauses.add(visitChild(cc)); } IValue finallyBlock = node.getFinally() == null ? null : visitChild(node.getFinally()); ownValue = constructRascalNode(node, body, catchClauses.asList(), optional(finallyBlock)); return false; } public boolean visit(TypeDeclaration node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers = parseExtendedModifiers(node); IValue objectType = node.isInterface() ? values.string("interface") : values.string("class"); IValue name = values.string(node.getName().getFullyQualifiedName()); IValueList genericTypes = new IValueList(values); if (node.getAST().apiLevel() >= AST.JLS3) { if (!node.typeParameters().isEmpty()) { for (Iterator it = node.typeParameters().iterator(); it.hasNext();) { TypeParameter t = (TypeParameter) it.next(); genericTypes.add(visitChild(t)); } } } IValue extendsClass = null; IValueList implementsInterfaces = new IValueList(values); if (node.getAST().apiLevel() == AST.JLS2) { if (node.getSuperclass() != null) { extendsClass = visitChild(node.getSuperclass()); } if (!node.superInterfaces().isEmpty()) { for (Iterator it = node.superInterfaces().iterator(); it.hasNext();) { Name n = (Name) it.next(); implementsInterfaces.add(visitChild(n)); } } } else if (node.getAST().apiLevel() >= AST.JLS3) { if (node.getSuperclassType() != null) { extendsClass = visitChild(node.getSuperclassType()); } if (!node.superInterfaceTypes().isEmpty()) { for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext();) { Type t = (Type) it.next(); implementsInterfaces.add(visitChild(t)); } } } IValueList bodyDeclarations = new IValueList(values); for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext();) { BodyDeclaration d = (BodyDeclaration) it.next(); bodyDeclarations.add(visitChild(d)); } ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), objectType, name, genericTypes.asList(), optional(extendsClass), implementsInterfaces.asList(), bodyDeclarations.asList()); return false; } public boolean visit(TypeDeclarationStatement node) { IValue typeDeclaration; if (node.getAST().apiLevel() == AST.JLS2) { typeDeclaration = visitChild(node.getTypeDeclaration()); } else { typeDeclaration = visitChild(node.getDeclaration()); } ownValue = constructRascalNode(node, typeDeclaration); return false; } public boolean visit(TypeLiteral node) { IValue type = visitChild(node.getType()); ownValue = constructRascalNode(node, type); return false; } public boolean visit(TypeParameter node) { IValue name = values.string(node.getName().getFullyQualifiedName()); IValueList extendsList = new IValueList(values); if (!node.typeBounds().isEmpty()) { for (Iterator it = node.typeBounds().iterator(); it.hasNext();) { Type t = (Type) it.next(); extendsList.add(visitChild(t)); } } ownValue = constructRascalNode(node, name, extendsList.asList()); return false; } public boolean visit(UnionType node) { IValueList typesValues = new IValueList(values); for(Iterator types = node.types().iterator(); types.hasNext();) { Type type = (Type) types.next(); typesValues.add(visitChild(type)); } ownValue = constructRascalNode(node, typesValues.asList()); return false; } public boolean visit(VariableDeclarationExpression node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers; if (node.getAST().apiLevel() == AST.JLS2) { extendedModifiers = new java.util.AbstractMap.SimpleEntry<IValueList, IValueList>(parseModifiers(node.getModifiers()), new IValueList(values)); } else { extendedModifiers = parseExtendedModifiers(node.modifiers()); } IValue type = visitChild(node.getType()); IValueList fragments = new IValueList(values); for (Iterator it = node.fragments().iterator(); it.hasNext();) { VariableDeclarationFragment f = (VariableDeclarationFragment) it.next(); fragments.add(visitChild(f)); } ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), type, fragments.asList()); return false; } public boolean visit(VariableDeclarationFragment node) { IValue name = values.string(node.getName().getFullyQualifiedName()); //TODO: Extra dimensions? /*for (int i = 0; i < node.getExtraDimensions(); i++) { this.buffer.append("[]");//$NON-NLS-1$ }*/ IValue initializer = node.getInitializer() == null ? null : visitChild(node.getInitializer()); ownValue = constructRascalNode(node, name, optional(initializer)); return false; } public boolean visit(VariableDeclarationStatement node) { java.util.Map.Entry<IValueList, IValueList> extendedModifiers; if (node.getAST().apiLevel() == AST.JLS2) { extendedModifiers = new java.util.AbstractMap.SimpleEntry<IValueList, IValueList>(parseModifiers(node.getModifiers()), new IValueList(values)); } else { extendedModifiers = parseExtendedModifiers(node.modifiers()); } IValue type = visitChild(node.getType()); IValueList fragments = new IValueList(values); for (Iterator it = node.fragments().iterator(); it.hasNext();) { VariableDeclarationFragment f = (VariableDeclarationFragment) it.next(); fragments.add(visitChild(f)); } ownValue = constructRascalNode(node, extendedModifiers.getKey().asList(), extendedModifiers.getValue().asList(), type, fragments.asList()); return false; } public boolean visit(WhileStatement node) { IValue expression = visitChild(node.getExpression()); IValue body = visitChild(node.getBody()); ownValue = constructRascalNode(node, expression, body); return false; } public boolean visit(WildcardType node) { IValue type = null; IValue bound = null; if (node.getBound() != null) { type = visitChild(node.getBound()); if (node.isUpperBound()) { bound = values.string(Java.CONS_EXTENDS.getName()); } else { bound = values.string(Java.CONS_SUPER.getName()); } } ownValue = constructRascalNode(node, optional(type), optional(bound)); return false; } /* * Inner class to resolve various java bindings * An object manages scope stacks and imports possible bindings */ static public class BindingsImporter extends BindingsResolver { // private IValue javaType; private IMapWriter bindings; // private final Stack<IValue> javaTypeStack; private final Stack<IValue> bindingsStack; private TypeFactory ftypes = TypeFactory.getInstance(); private final IValueFactory values; private final BindingConverter bindingConverter; public BindingsImporter(final IValueFactory values, final BindingConverter bindingConverter) { super(bindingConverter); this.values = values; this.bindingConverter = bindingConverter; // this.javaTypeStack = new Stack<IValue>(); this.bindingsStack = new Stack<IValue>(); } // public IValue popJavaType() { // return this.javaTypeStack.pop(); // } public IValue popBindings() { return this.bindingsStack.pop(); } private void pushAllBindings() { // javaTypeStack.push(javaType); bindingsStack.push(bindings.done()); } public void resolveBindings(ASTNode node) { // this.javaType = null; this.bindings = this.values.mapWriter(this.ftypes.stringType(), ADT_ENTITY); super.resolveBindings(node); this.pushAllBindings(); } public void importBinding(IMethodBinding binding) { this.bindings.put(this.values.string(ANNOTATION_JAVA_METHOD_BINDING), this.bindingConverter.getEntity(binding)); } public void importBinding(IPackageBinding binding) { this.bindings.put(this.values.string(ANNOTATION_JAVA_PACKAGE_BINDING), this.bindingConverter.getEntity(binding)); } public void importBinding(ITypeBinding binding, Initializer initializer) { // this.javaType = this.bindingConverter.getEntity(binding, initializer); // this.bindings.put(this.values.string(ANNOTATION_JAVA_TYPE_BINDING), this.javaType); this.bindings.put(this.values.string(ANNOTATION_JAVA_TYPE_BINDING), this.bindingConverter.getEntity(binding, initializer)); } public void importBinding(IVariableBinding binding, Initializer initializer) { this.bindings.put(this.values.string(ANNOTATION_JAVA_VARIABLE_BINDING), this.bindingConverter.getEntity(binding, initializer)); } } }