Package ast

Source Code of ast.XmlVisitor

package ast;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.ArrayAccess;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.BooleanLiteral;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.PostfixExpression;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;
import org.eclipse.jdt.core.dom.InfixExpression.Operator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

public class XmlVisitor extends ASTVisitor implements NodeMapping{
  private static final String MAPPING_ATTRIBUTE = "id"; // Used to map xml node to AST node
  private static final String EXPRESSION_ELEMENT = "Expr"; // Wraps expressions
 
  private Stack<Element> xmlElementStack = new Stack<Element>();
  private Document doc;
  private int indent = 0;
  private int lastId = 0;
  private Map<String, ASTNode> xmlToAst = new HashMap<String, ASTNode>();
  private Set<IBinding> namesFromHeap = new HashSet<IBinding>();
  private Set<IBinding> currentIfConditionbindings = new HashSet<IBinding>();
  private boolean insideIfCondition;
  private Element lastElement;

  public XmlVisitor() throws ParserConfigurationException {
    DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
    doc = docBuilder.newDocument();
    Element sourceFileElement = doc.createElement("SourceFile");
    doc.appendChild(sourceFileElement);
    xmlElementStack.push(sourceFileElement);
  }

  public Document getDocument() {
    return doc;
  }

  private Element push(String name) {
    Element e = doc.createElement(name);
    xmlElementStack.peek().appendChild(e);
    xmlElementStack.push(e);
    return e;
  }

  private Element pop() {
    return xmlElementStack.pop();
  }

  @Override
  public void preVisit(org.eclipse.jdt.core.dom.ASTNode node) {
    Element e = push(node.getClass().getSimpleName());
    String idx = String.valueOf(lastId++);
    e.setAttribute(MAPPING_ATTRIBUTE, idx);
    xmlToAst.put(idx, node);
  }

  @Override
  public boolean visit(IfStatement node) {
    assert insideIfCondition == false;
    insideIfCondition = true;
    node.getExpression().accept(this);
    Set<IBinding> conditionBindings = currentIfConditionbindings;
    currentIfConditionbindings = new HashSet<IBinding>();
    insideIfCondition = false;
    node.getThenStatement().accept(this);
    if (node.getElseStatement() != null) {
      node.getElseStatement().accept(this);
    }
    namesFromHeap.addAll(conditionBindings);
    return false;
  }

  @Override
  public void postVisit(org.eclipse.jdt.core.dom.ASTNode node) {
    if (node instanceof ParenthesizedExpression) {
      // do nothing
    } else if (node instanceof Expression) {
      Expression expr = (Expression) node;
      if (expr.resolveConstantExpressionValue() != null) {
        Node oldNode = pop();
        try {
          xmlElementStack.peek().removeChild(oldNode);
        } catch (RuntimeException e) {
          System.out.println("HELLO");
          throw e;
        }
        Element newNode = push("Constant");
        updateType(expr, expr.resolveTypeBinding());
        newNode.setAttribute("value", expr
            .resolveConstantExpressionValue().toString());
        newNode.setAttribute("node", node.getClass().getSimpleName());
        newNode.setAttribute(MAPPING_ATTRIBUTE, ((Element)oldNode).getAttribute(MAPPING_ATTRIBUTE));
      }
    }
    lastElement = pop();
    indent -= 1;
  }

  @Override
  public boolean visit(QualifiedName node) {
    updateType(node, Utils.getTypeBinding(node));
    updateScope(node);
    Element elem = replaceTop("Name");
    if (Utils.isFinal(node))
      elem.setAttribute("final", "true");
    if (Utils.isFinalSuffix(node))
      elem.setAttribute("finalSuffix", "true");
    elem.setAttribute("name", Utils.getNamePrefix(node));
    elem.setAttribute("fullname", node.getFullyQualifiedName());
    return false;
  }

  private Element replaceTop(String newName) {
    Element oldXml = (Element) xmlElementStack.pop();
    xmlElementStack.peek().removeChild(oldXml);
    Element newXml = push(newName);
    NamedNodeMap attrMap = oldXml.getAttributes();
    for (int i = 0; i < attrMap.getLength(); i++) {
      Node n = attrMap.item(i);
      newXml.setAttribute(n.getNodeName(), n.getNodeValue());
    }
    return newXml;
  }

  @Override
  public boolean visit(FieldAccess node) {
    updateType(node.getName(), Utils.getTypeBinding(node.getName()));
    Element elem = replaceTop("Name");
    if (Utils.isFinal(node.getName()))
      elem.setAttribute("final", "true");
    if (Utils.isFinalSuffix(node.getName()))
      elem.setAttribute("finalSuffix", "true");
    elem.setAttribute("scope", "field");
    elem.setAttribute("name", Utils.getNamePrefix(node.getName()));
    elem.setAttribute("fullname", node.toString());
    if ((new HeapVisitor()).check(node, namesFromHeap)) {
      elem.setAttribute("fromHeap", "true");
    }
    return false;
  }

  private void updateType(Expression node, ITypeBinding type) {
//    ITypeBinding type = Utils.getTypeBinding(node);
    // ITypeBinding type = node.resolveTypeBinding();
    Element xml = (Element) xmlElementStack.peek();
    if (type != null) {
      String ext = "";
      ITypeBinding ex = type.getSuperclass();
      while (ex != null) {
        ext += ex.getName() + ", ";
        ex = ex.getSuperclass();
      }
      type.getSuperclass();

      xml.setAttribute("type", type.getName());
      if (type.isArray()) {
        xml.setAttribute("isArray", "true");
      }
      if (ext.length() > 0) {
        xml.setAttribute("superclasses", ext);
      }
      ITypeBinding[] interfaces = type.getInterfaces();
      String impl = "";
      for (ITypeBinding inter : interfaces) {
        impl += inter.getName() + ", ";
      }
      if (impl.length() > 0) {
        xml.setAttribute("interfaces", impl);
      }
      String[] simplenumericTypes = { "int", "long", "short", "byte",
          "char", "float", "double" };
      if (type.isPrimitive()
          & Utils.contains(simplenumericTypes, type.getName())) {
        xml.setAttribute("numeric", "true");
      }
    }
  }

  private void updateScope(Name node) {
    Element xml = (Element) xmlElementStack.peek();
    IBinding binding = Utils.getBinding(node);
    if (binding != null && binding.getKind() == IBinding.VARIABLE) {
      IVariableBinding varBinding = (IVariableBinding) binding;
      if (varBinding.isField()) {
        xml.setAttribute("scope", "field");
        if ((varBinding.getModifiers() & org.eclipse.jdt.core.dom.Modifier.PRIVATE) > 0) {
          xml.setAttribute("private", varBinding.getDeclaringClass()
              .getName());
        }
      } else {
        xml.setAttribute("scope", "local");
      }
      if (namesFromHeap.contains(binding))
        xml.setAttribute("fromHeap", "true");
    }

  }

  //
  // private boolean isFinal(Name node) {
  // while (true) {
  // IBinding binding = node.resolveBinding();
  // int modifiers = 0;
  // if (binding != null) {
  // modifiers = binding.getModifiers();
  // }
  // if ((modifiers & org.eclipse.jdt.core.dom.Modifier.FINAL) == 0)
  // return false;
  // if (node.isQualifiedName()) {
  // node = ((QualifiedName) node).getQualifier();
  // } else {
  // break;
  // }
  // }
  // return true;
  // }

  @Override
  public boolean visit(SimpleName node) {
    Element xml = (Element) xmlElementStack.peek();
    updateType(node, Utils.getTypeBinding(node));
    updateScope(node);
    xml = replaceTop("Name");
    xml.setAttribute("name", node.getIdentifier());
    if (Utils.isFinalFieldAccess(node))
      xml.setAttribute("final", "true");
    return false;
  }

  private void updateBindings(ASTNode node) {
    if (!insideIfCondition)
      return;
    if (node instanceof Name) {
      IBinding binding = ((Name) node).resolveBinding();
      if (namesFromHeap.contains(binding)) {
        namesFromHeap.remove(binding);
        currentIfConditionbindings.add(binding);
      }
    }
  }

  @Override
  public boolean visit(org.eclipse.jdt.core.dom.InfixExpression node) {
    Element xml = (Element) xmlElementStack.peek();
    if (node.getOperator() != null) {
      xml.setAttribute("operator", node.getOperator().toString());
    }
    if (Operator.NOT_EQUALS.equals(node.getOperator())
        || Operator.EQUALS.equals(node.getOperator())) {
      if (node.getLeftOperand().getNodeType() == ASTNode.NULL_LITERAL) {
        updateBindings(node.getRightOperand());
      } else if (node.getRightOperand().getNodeType() == ASTNode.NULL_LITERAL) {
        updateBindings(node.getLeftOperand());
      }
    }
    push(EXPRESSION_ELEMENT);
    node.getLeftOperand().accept(this);
    pop().setAttribute(MAPPING_ATTRIBUTE, lastElement.getAttribute(MAPPING_ATTRIBUTE));
    push(EXPRESSION_ELEMENT);
    node.getRightOperand().accept(this);
    pop().setAttribute(MAPPING_ATTRIBUTE, lastElement.getAttribute(MAPPING_ATTRIBUTE));
    if (node.extendedOperands() != null) {
      for (ASTNode n : (List<ASTNode>) node.extendedOperands()) {
        push(EXPRESSION_ELEMENT);
        n.accept(this);
        pop().setAttribute(MAPPING_ATTRIBUTE, lastElement.getAttribute(MAPPING_ATTRIBUTE));;
      }
    }
    return false;
  }

  @Override
  public boolean visit(Assignment node) {
    replaceTop("ChangeVal");
    Element xml = (Element) xmlElementStack.peek();
    String kind = node.getOperator().toString();
    String a = "other";
    if (kind == "+=") {
      a = "inc";
    }
    if (kind == "-=") {
      a = "dec";
    }
    if (kind == "=") {
      a = "assign";
    }
    if (kind == "*=") {
      a = "mul";
    }
    if (kind == "/=") {
      a = "div";
    }
    xml.setAttribute("kind", a);
    xml.setAttribute("realNode", "Assignment");
    push("LeftOfAssignment");
    node.getLeftHandSide().accept(this);
    pop();
    push("RightOfAssignment");
    node.getRightHandSide().accept(this);
    pop();

    if ((new HeapVisitor()).check(node.getRightHandSide(), namesFromHeap)) {
      if (node.getLeftHandSide() instanceof Name) {
        namesFromHeap.add(((Name) node.getLeftHandSide())
            .resolveBinding());
      } else if (node.getLeftHandSide() instanceof FieldAccess) {
        namesFromHeap.add(((FieldAccess) node.getLeftHandSide())
            .resolveFieldBinding());
      }
    }
    return false;
  }

  @Override
  public boolean visit(PrefixExpression node) {
    replaceTop("ChangeVal");
    Element xml = (Element) xmlElementStack.peek();
    String kind = node.getOperator().toString();
    String a = "dec";
    if (kind == "++") {
      a = "inc";
    }
    xml.setAttribute("kind", a);
    xml.setAttribute("realNode", "PrefixExpression");
    push("LeftOfAssignment");
    node.getOperand().accept(this);
    pop();
    push("RightOfAssignment");
    pop();
    return false;
  }

  @Override
  public boolean visit(org.eclipse.jdt.core.dom.EnhancedForStatement node) {
    Element xml = (Element) xmlElementStack.peek();
    xml.setAttribute("isLoop", "true");

    return super.visit(node);
  };

  @Override
  public boolean visit(org.eclipse.jdt.core.dom.ForStatement node) {
    Element xml = (Element) xmlElementStack.peek();
    xml.setAttribute("isLoop", "true");

    //create artificial element for initialisers
    push("Initializers");
    if (node.initializers() != null) {
      for (Object n : node.initializers()) {
        ((ASTNode) n).accept(this);
      }
    }
    pop();

    //create artificial element for the loop condition
    push("Condition");
    if (node.getExpression() != null)
      node.getExpression().accept(this);
    pop();
    push("Updaters");
    if (node.updaters() != null) {
      for (Object n : node.updaters()) {
        ((ASTNode) n).accept(this);
      }
    }
    pop();
    if (node.getBody() != null) {
      if (node.getBody().getNodeType() != ASTNode.BLOCK) {
        push("Block");
        node.getBody().accept(this);
        pop();
      } else {
        node.getBody().accept(this);
      }
    }
    return false;
  };

  @Override
  public boolean visit(BooleanLiteral node) {
    Element xml = (Element) xmlElementStack.peek();
    xml.setAttribute("value", String.valueOf(node.booleanValue()));
    return super.visit(node);
  }

  @Override
  public boolean visit(WhileStatement node) {
    Element xml = (Element) xmlElementStack.peek();
    xml.setAttribute("isLoop", "true");

    push("Condition");
    if (node.getExpression() != null) {
      node.getExpression().accept(this);
    }
    pop();
    if (node.getBody() != null) {
      node.getBody().accept(this);
    }
    return false;
  }

  @Override
  public boolean visit(DoStatement node) {
    Element xml = (Element) xmlElementStack.peek();
    xml.setAttribute("isLoop", "true");
    return super.visit(node);
  }

  @Override
  public boolean visit(PostfixExpression node) {
    replaceTop("ChangeVal");
    Element xml = (Element) xmlElementStack.peek();
    String kind = node.getOperator().toString();
    String a = "dec";
    if (kind == "++") {
      a = "inc";
    }
    xml.setAttribute("kind", a);
    xml.setAttribute("realNode", "PostfixExpression");
    push("LeftOfAssignment");
    node.getOperand().accept(this);

    pop();
    push("RightOfAssignment");
    pop();

    return false;
  }

  @Override
  public ASTNode getNode(String index) {
    return xmlToAst.containsKey(index) ? xmlToAst.get(index) : null;
  }

  @Override
  public boolean visit(ArrayAccess node) {
    Element xml = (Element) xmlElementStack.peek();
    xml.setAttribute("fromHeap", "true");
    return true;
  }

  @Override
  public boolean visit(VariableDeclarationStatement node) {
    // node.
    // if ((new HeapVisitor()).check(node.getRightHandSide())){
    // namesFromHeap.add(((Name)node.getLeftHandSide()).resolveBinding());
    // }
    //
    // Element xml = (Element) xmlNodeStack.peek();
    // xml.setAttribute("fromHeap", "true");
    VariableDeclarationFragment frag = (VariableDeclarationFragment) node
        .fragments().get(node.fragments().size() - 1);
    if (frag.getInitializer() != null) {
      if ((new HeapVisitor()).check(frag.getInitializer(), namesFromHeap)) {
        namesFromHeap.add((frag.getName()).resolveBinding());
      }

    }
    return true;
  }

  @Override
  public boolean visit(MethodDeclaration node) {
    Element elem = (Element) xmlElementStack.peek();
    if (node.isConstructor()) {
      elem.setAttribute("constructor", "true");
    }
    for (int i = 0; i < node.parameters().size(); i++) {
      SingleVariableDeclaration dec = (SingleVariableDeclaration) node
          .parameters().get(i);
      if (!dec.getType().isPrimitiveType()) {
        IBinding binding = dec.getName().resolveBinding();
        namesFromHeap.add(binding);
      }
      // System.out.println(dec);
    }
    return true;
  }

  public boolean visit(ParenthesizedExpression node) {
    Element curNode = pop();
    xmlElementStack.peek().removeChild(curNode);
    node.getExpression().accept(this);
    xmlElementStack.push(curNode);
    return false;
  }

  @Override
  public boolean visit(MethodInvocation node) {
    Element elem = (Element) xmlElementStack.peek();
    // expression
    if (node.getExpression() != null){
      node.getExpression().accept(this);
//      IMethodBinding mb = Utils.findMethod(node.getExpression().resolveTypeBinding(), node.getName().toString());
////      ITypeBinding bind = node.getExpression().resolveTypeBinding();
//      System.out.println(mb);
    };
    elem.setAttribute("methodName", node.getName().toString());
    List<ASTNode> arguments = node.arguments();
    if (!arguments.isEmpty()) {
      push("MethodArguments");
      for (ASTNode arg : arguments) {
        push("MethodArgument");
        arg.accept(this);
        pop();
      }
      pop();
    }
    return false;
  }

}
TOP

Related Classes of ast.XmlVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.