org.tizen.web.assignmenttracing_1.0.0.201310101535

16:50:32.326 INFO  jd.cli.Main - Decompiling org.tizen.web.assignmenttracing_1.0.0.201310101535.jar
package org.tizen.web.assignmenttracing.core;

class CFGBuilder$DefChecker$DefFound
  extends RuntimeException
{
  private static final long serialVersionUID = -2769993374371688073L;
  
  CFGBuilder$DefChecker$DefFound(CFGBuilder.DefChecker paramDefChecker) {}
}

/* Location:
 * Qualified Name:     org.tizen.web.assignmenttracing.core.CFGBuilder.DefChecker.DefFound
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package org.tizen.web.assignmenttracing.core;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.wst.jsdt.core.dom.FunctionDeclaration;
import org.eclipse.wst.jsdt.core.dom.SimpleName;

class CFGBuilder$DefChecker
  extends CFGBuilder
{
  public CFGBuilder$DefChecker(CFGBuilder paramCFGBuilder, IProgressMonitor monitor)
  {
    super(monitor);
  }
  
  public boolean checkDefExists(FunctionDeclaration func, SimpleName name)
  {
    try
    {
      buildCFG(func, name);
    }
    catch (DefFound localDefFound)
    {
      return true;
    }
    return false;
  }
  
  protected CFGNode createSimpleName(CFGNode prev, SimpleName name)
  {
    if (isSelectedBinding(name)) {
      throw new DefFound();
    }
    return null;
  }
  
  protected CFGNode createNode(SimpleName name, Integer nodeType)
  {
    return null;
  }
  
  protected CFGNode createSkipNode()
  {
    return null;
  }
  
  protected void connectNodes(CFGNode prev, CFGNode next) {}
  
  class DefFound
    extends RuntimeException
  {
    private static final long serialVersionUID = -2769993374371688073L;
    
    DefFound() {}
  }
}

/* Location:
 * Qualified Name:     org.tizen.web.assignmenttracing.core.CFGBuilder.DefChecker
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package org.tizen.web.assignmenttracing.core;

import org.eclipse.wst.jsdt.core.dom.ASTVisitor;
import org.eclipse.wst.jsdt.core.dom.SimpleName;
import org.eclipse.wst.jsdt.core.dom.WithStatement;

public class CFGBuilder$SelectedNameContainingChecker
  extends ASTVisitor
{
  private boolean nameExists = false;
  
  public CFGBuilder$SelectedNameContainingChecker(CFGBuilder paramCFGBuilder)
  {
    super(false);
    nameExists = false;
  }
  
  public boolean getResult()
  {
    return nameExists;
  }
  
  public boolean visit(SimpleName node)
  {
    if (this$0.isSelectedBinding(node))
    {
      nameExists = true;
      return false;
    }
    return true;
  }
  
  public boolean visit(WithStatement node)
  {
    nameExists = ((nameExists) || (CFGBuilder.access$1(this$0, node.getExpression())));
    nameExists = ((nameExists) || (CFGBuilder.access$2(this$0, node.getBody())));
    return false;
  }
}

/* Location:
 * Qualified Name:     org.tizen.web.assignmenttracing.core.CFGBuilder.SelectedNameContainingChecker
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package org.tizen.web.assignmenttracing.core;

import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.ASTVisitor;
import org.eclipse.wst.jsdt.core.dom.FieldAccess;
import org.eclipse.wst.jsdt.core.dom.SimpleName;

public class CFGBuilder$SelectedNameStringChecker
  extends ASTVisitor
{
  private boolean nameStringExists = false;
  
  public CFGBuilder$SelectedNameStringChecker(CFGBuilder paramCFGBuilder)
  {
    super(false);
    nameStringExists = false;
  }
  
  public boolean getResult()
  {
    return nameStringExists;
  }
  
  public boolean visit(SimpleName node)
  {
    if (CFGBuilder.access$0(this$0, node))
    {
      ASTNode parent = node.getParent();
      if (node.resolveBinding() == null) {
        return true;
      }
      if (((parent instanceof FieldAccess)) && 
        (((FieldAccess)parent).getName() == node)) {
        return true;
      }
      nameStringExists = true;
      return false;
    }
    return true;
  }
}

/* Location:
 * Qualified Name:     org.tizen.web.assignmenttracing.core.CFGBuilder.SelectedNameStringChecker
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package org.tizen.web.assignmenttracing.core;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.ASTVisitor;
import org.eclipse.wst.jsdt.core.dom.ArrayAccess;
import org.eclipse.wst.jsdt.core.dom.ArrayInitializer;
import org.eclipse.wst.jsdt.core.dom.Assignment;
import org.eclipse.wst.jsdt.core.dom.Assignment.Operator;
import org.eclipse.wst.jsdt.core.dom.Block;
import org.eclipse.wst.jsdt.core.dom.BreakStatement;
import org.eclipse.wst.jsdt.core.dom.CatchClause;
import org.eclipse.wst.jsdt.core.dom.ClassInstanceCreation;
import org.eclipse.wst.jsdt.core.dom.ConditionalExpression;
import org.eclipse.wst.jsdt.core.dom.ContinueStatement;
import org.eclipse.wst.jsdt.core.dom.DoStatement;
import org.eclipse.wst.jsdt.core.dom.Expression;
import org.eclipse.wst.jsdt.core.dom.ExpressionStatement;
import org.eclipse.wst.jsdt.core.dom.FieldAccess;
import org.eclipse.wst.jsdt.core.dom.ForInStatement;
import org.eclipse.wst.jsdt.core.dom.ForStatement;
import org.eclipse.wst.jsdt.core.dom.FunctionDeclaration;
import org.eclipse.wst.jsdt.core.dom.FunctionExpression;
import org.eclipse.wst.jsdt.core.dom.FunctionInvocation;
import org.eclipse.wst.jsdt.core.dom.IBinding;
import org.eclipse.wst.jsdt.core.dom.IfStatement;
import org.eclipse.wst.jsdt.core.dom.InfixExpression;
import org.eclipse.wst.jsdt.core.dom.InfixExpression.Operator;
import org.eclipse.wst.jsdt.core.dom.LabeledStatement;
import org.eclipse.wst.jsdt.core.dom.ListExpression;
import org.eclipse.wst.jsdt.core.dom.ObjectLiteral;
import org.eclipse.wst.jsdt.core.dom.ObjectLiteralField;
import org.eclipse.wst.jsdt.core.dom.ParenthesizedExpression;
import org.eclipse.wst.jsdt.core.dom.PostfixExpression;
import org.eclipse.wst.jsdt.core.dom.PostfixExpression.Operator;
import org.eclipse.wst.jsdt.core.dom.PrefixExpression;
import org.eclipse.wst.jsdt.core.dom.PrefixExpression.Operator;
import org.eclipse.wst.jsdt.core.dom.ReturnStatement;
import org.eclipse.wst.jsdt.core.dom.SimpleName;
import org.eclipse.wst.jsdt.core.dom.SingleVariableDeclaration;
import org.eclipse.wst.jsdt.core.dom.Statement;
import org.eclipse.wst.jsdt.core.dom.SwitchCase;
import org.eclipse.wst.jsdt.core.dom.SwitchStatement;
import org.eclipse.wst.jsdt.core.dom.ThrowStatement;
import org.eclipse.wst.jsdt.core.dom.TryStatement;
import org.eclipse.wst.jsdt.core.dom.VariableDeclarationExpression;
import org.eclipse.wst.jsdt.core.dom.VariableDeclarationFragment;
import org.eclipse.wst.jsdt.core.dom.VariableDeclarationStatement;
import org.eclipse.wst.jsdt.core.dom.WhileStatement;
import org.eclipse.wst.jsdt.core.dom.WithStatement;
import org.tizen.web.assignmenttracing.core.environment.CatchElement;
import org.tizen.web.assignmenttracing.core.environment.EnvironmentElement;
import org.tizen.web.assignmenttracing.core.environment.EnvironmentStack;
import org.tizen.web.assignmenttracing.core.environment.LabeledStmtElement;
import org.tizen.web.assignmenttracing.core.environment.LoopElement;
import org.tizen.web.assignmenttracing.core.environment.NotInterestingElement;
import org.tizen.web.assignmenttracing.core.environment.SwitchElement;
import org.tizen.web.assignmenttracing.core.environment.TryElement;
import org.tizen.web.assignmenttracing.core.exceptions.TracingCancelException;
import org.tizen.web.assignmenttracing.core.exceptions.TracingInternalErrorException;
import org.tizen.web.assignmenttracing.core.exceptions.TracingUnsupportedException;

public class CFGBuilder
{
  private static final int DEF = 0;
  private static final int USE = 1;
  private static final int DECL = 2;
  private static final int LHS = 0;
  private static final int RHS = 1;
  private List<CFGNode> nameMatchedNode;
  private CFGNode start = null;
  private SimpleName selectedName;
  private Stack<EnvironmentStack> environments;
  private EnvironmentStack currentEnv = null;
  private int nodeCount;
  private IProgressMonitor cancelMonitor;
  
  public class SelectedNameStringChecker
    extends ASTVisitor
  {
    private boolean nameStringExists = false;
    
    public SelectedNameStringChecker()
    {
      super();
      nameStringExists = false;
    }
    
    public boolean getResult()
    {
      return nameStringExists;
    }
    
    public boolean visit(SimpleName node)
    {
      if (CFGBuilder.this.hasSelectedNameString(node))
      {
        ASTNode parent = node.getParent();
        if (node.resolveBinding() == null) {
          return true;
        }
        if (((parent instanceof FieldAccess)) && 
          (((FieldAccess)parent).getName() == node)) {
          return true;
        }
        nameStringExists = true;
        return false;
      }
      return true;
    }
  }
  
  public class SelectedNameContainingChecker
    extends ASTVisitor
  {
    private boolean nameExists = false;
    
    public SelectedNameContainingChecker()
    {
      super();
      nameExists = false;
    }
    
    public boolean getResult()
    {
      return nameExists;
    }
    
    public boolean visit(SimpleName node)
    {
      if (isSelectedBinding(node))
      {
        nameExists = true;
        return false;
      }
      return true;
    }
    
    public boolean visit(WithStatement node)
    {
      nameExists = ((nameExists) || (CFGBuilder.this.checkSelectedNameContainment(node.getExpression())));
      nameExists = ((nameExists) || (CFGBuilder.this.checkSelectedNameString(node.getBody())));
      return false;
    }
  }
  
  private class DefChecker
    extends CFGBuilder
  {
    public DefChecker(IProgressMonitor monitor)
    {
      super();
    }
    
    public boolean checkDefExists(FunctionDeclaration func, SimpleName name)
    {
      try
      {
        buildCFG(func, name);
      }
      catch (DefFound localDefFound)
      {
        return true;
      }
      return false;
    }
    
    protected CFGNode createSimpleName(CFGNode prev, SimpleName name)
    {
      if (isSelectedBinding(name)) {
        throw new DefFound();
      }
      return null;
    }
    
    protected CFGNode createNode(SimpleName name, Integer nodeType)
    {
      return null;
    }
    
    protected CFGNode createSkipNode()
    {
      return null;
    }
    
    protected void connectNodes(CFGNode prev, CFGNode next) {}
    
    class DefFound
      extends RuntimeException
    {
      private static final long serialVersionUID = -2769993374371688073L;
      
      DefFound() {}
    }
  }
  
  public CFGBuilder(IProgressMonitor monitor)
  {
    nameMatchedNode = new ArrayList();
    
    environments = new Stack();
    
    environments.push(new EnvironmentStack());
    currentEnv = ((EnvironmentStack)environments.peek());
    
    nodeCount = 0;
    
    cancelMonitor = monitor;
  }
  
  public List<CFGNode> buildCFG(FunctionDeclaration func, SimpleName selName)
  {
    selectedName = selName;
    
    start = createSkipNode();
    
    CFGNode prev = createSkipNode();
    connectNodes(start, prev);
    
    List parameters = func.parameters();
    for (Object parameter : parameters) {
      prev = createSingleVariableDeclaration(prev, (SingleVariableDeclaration)parameter);
    }
    createStatement(prev, func.getBody());
    
    return nameMatchedNode;
  }
  
  public void checkReachability()
  {
    Stack<CFGNode> nodeStack = new Stack();
    
    nodeStack.push(start);
    while (!nodeStack.empty())
    {
      CFGNode currentNode = (CFGNode)nodeStack.pop();
      currentNode.setReachable();
      for (CFGNode succ : currentNode.getSucc()) {
        if (!succ.isReachable()) {
          nodeStack.push(succ);
        }
      }
      if ((currentNode instanceof TrySkipNode))
      {
        CFGNode catchBeginNode = ((TrySkipNode)currentNode).getCatchBeginNode();
        if ((catchBeginNode != null) && (!catchBeginNode.isReachable())) {
          nodeStack.push(catchBeginNode);
        }
      }
    }
  }
  
  private CFGNode createSingleVariableDeclaration(CFGNode prev, SingleVariableDeclaration variableDecl)
  {
    SimpleName name = variableDecl.getName();
    return createSimpleName(prev, name);
  }
  
  private CFGNode createStatement(CFGNode prev, Statement stmt)
  {
    if (cancelMonitor.isCanceled()) {
      throw new TracingCancelException();
    }
    if (stmt == null) {
      return prev;
    }
    switch (stmt.getNodeType())
    {
    case 8: 
      return createBlockStatement(prev, (Block)stmt);
    case 21: 
      return createExpressionStatement(prev, (ExpressionStatement)stmt);
    case 60: 
      return createVariableDeclarationStatement(prev, (VariableDeclarationStatement)stmt);
    case 25: 
      return createIfStatement(prev, (IfStatement)stmt);
    case 24: 
      return createForStatement(prev, (ForStatement)stmt);
    case 83: 
      return createForInStatement(prev, (ForInStatement)stmt);
    case 61: 
      return createWhileStatement(prev, (WhileStatement)stmt);
    case 19: 
      return createDoWhileStatement(prev, (DoStatement)stmt);
    case 50: 
      return createSwitchStatement(prev, (SwitchStatement)stmt);
    case 49: 
      return createCaseDefaultStatement(prev, (SwitchCase)stmt);
    case 41: 
      return createReturnStatement(prev, (ReturnStatement)stmt);
    case 10: 
      return createBreakStatement(prev, (BreakStatement)stmt);
    case 18: 
      return createContinueStatement(prev, (ContinueStatement)stmt);
    case 30: 
      return createLabeledStatement(prev, (LabeledStatement)stmt);
    case 90: 
      return createWithStatement(prev, (WithStatement)stmt);
    case 54: 
      return createTryStatement(prev, (TryStatement)stmt);
    case 53: 
      return createThrowStatement(prev, (ThrowStatement)stmt);
    case 20: 
      return prev;
    }
    throw new TracingInternalErrorException();
  }
  
  private CFGNode createBlockStatement(CFGNode prev, Block stmt)
  {
    currentEnv.push(new NotInterestingElement());
    
    List statements = stmt.statements();
    for (Object statement : statements) {
      if ((statement instanceof FunctionDeclaration))
      {
        FunctionDeclaration functionDecl = (FunctionDeclaration)statement;
        if (checkDefExists(functionDecl)) {
          throw new TracingUnsupportedException();
        }
      }
      else
      {
        prev = createStatement(prev, (Statement)statement);
      }
    }
    currentEnv.pop();
    
    return prev;
  }
  
  private CFGNode createExpressionStatement(CFGNode prev, ExpressionStatement stmt)
  {
    prev = createExpr(prev, stmt.getExpression(), 1);
    return prev;
  }
  
  private CFGNode createVariableDeclarationStatement(CFGNode prev, VariableDeclarationStatement stmt)
  {
    List fragments = stmt.fragments();
    for (Object fragment : fragments)
    {
      VariableDeclarationFragment declFragment = (VariableDeclarationFragment)fragment;
      prev = createVariableDeclarationFragment(prev, declFragment);
    }
    return prev;
  }
  
  private CFGNode createVariableDeclarationFragment(CFGNode prev, VariableDeclarationFragment fragment)
  {
    Expression initializer = fragment.getInitializer();
    SimpleName name = fragment.getName();
    if (initializer != null)
    {
      prev = createExpr(prev, initializer, 1);
      prev = createSimpleName(prev, name);
    }
    else if (isSelectedBinding(name))
    {
      CFGNode declNode = createNode(name, Integer.valueOf(2));
      for (CFGNode succ : start.getSucc())
      {
        succ.getPred().remove(start);
        connectNodes(declNode, succ);
      }
      start.getSucc().clear();
      connectNodes(start, declNode);
    }
    return prev;
  }
  
  private CFGNode createIfStatement(CFGNode prev, IfStatement stmt)
  {
    currentEnv.push(new NotInterestingElement());
    
    prev = createExpr(prev, stmt.getExpression(), 1);
    
    CFGNode thenNode = createStatement(prev, stmt.getThenStatement());
    CFGNode joinNode = createSkipNode();
    CFGNode elseNode = null;
    
    connectNodes(thenNode, joinNode);
    
    Statement elseStatement = stmt.getElseStatement();
    if (elseStatement == null)
    {
      connectNodes(prev, joinNode);
    }
    else
    {
      elseNode = createStatement(prev, elseStatement);
      connectNodes(elseNode, joinNode);
    }
    currentEnv.pop();
    return joinNode;
  }
  
  private CFGNode createForStatement(CFGNode prev, ForStatement stmt)
  {
    CFGNode beforeCondNode = createSkipNode();
    CFGNode beforeIterNode = createSkipNode();
    CFGNode joinNode = createSkipNode();
    CFGNode lastNode = null;
    
    currentEnv.push(new LoopElement(joinNode, beforeIterNode));
    
    List initializers = stmt.initializers();
    if (initializers.size() != 0)
    {
      Object initializer = initializers.get(0);
      prev = createExpr(prev, (Expression)initializer, 1);
    }
    connectNodes(prev, beforeCondNode);
    
    prev = beforeCondNode;
    Expression condExpr = stmt.getExpression();
    if (condExpr != null) {
      prev = createExpr(prev, condExpr, 1);
    }
    lastNode = createStatement(prev, stmt.getBody());
    
    connectNodes(lastNode, beforeIterNode);
    if (condExpr != null) {
      connectNodes(prev, joinNode);
    }
    prev = beforeIterNode;
    
    List updaters = stmt.updaters();
    for (Object updater : updaters)
    {
      Expression expr = (Expression)updater;
      prev = createExpr(prev, expr, 1);
    }
    connectNodes(prev, beforeCondNode);
    
    currentEnv.pop();
    
    return joinNode;
  }
  
  private CFGNode createForInStatement(CFGNode prev, ForInStatement stmt)
  {
    Statement iterationVariable = stmt.getIterationVariable();
    Expression collection = stmt.getCollection();
    
    CFGNode joinNode = createSkipNode();
    CFGNode beforeVariableNode = createSkipNode();
    CFGNode lastNode = null;
    SimpleName name = null;
    
    currentEnv.push(new LoopElement(joinNode, beforeVariableNode));
    
    prev = createExpr(prev, collection, 1);
    if ((iterationVariable instanceof VariableDeclarationStatement))
    {
      VariableDeclarationStatement declStmt = (VariableDeclarationStatement)iterationVariable;
      List fragments = declStmt.fragments();
      VariableDeclarationFragment fragment = (VariableDeclarationFragment)fragments.get(0);
      
      prev = createVariableDeclarationFragment(prev, fragment);
      
      name = fragment.getName();
    }
    else
    {
      ExpressionStatement exprStmt = (ExpressionStatement)iterationVariable;
      Expression expr = exprStmt.getExpression();
      
      name = (SimpleName)expr;
    }
    connectNodes(prev, beforeVariableNode);
    prev = beforeVariableNode;
    
    prev = createSimpleName(prev, name);
    
    lastNode = createStatement(prev, stmt.getBody());
    connectNodes(lastNode, beforeVariableNode);
    connectNodes(prev, joinNode);
    
    currentEnv.pop();
    
    return joinNode;
  }
  
  private CFGNode createWhileStatement(CFGNode prev, WhileStatement stmt)
  {
    CFGNode joinNode = createSkipNode();
    CFGNode beforeCondNode = createSkipNode();
    CFGNode lastNode = null;
    
    currentEnv.push(new LoopElement(joinNode, beforeCondNode));
    
    connectNodes(prev, beforeCondNode);
    
    prev = createExpr(beforeCondNode, stmt.getExpression(), 1);
    lastNode = createStatement(prev, stmt.getBody());
    
    connectNodes(lastNode, beforeCondNode);
    
    connectNodes(prev, joinNode);
    
    currentEnv.pop();
    
    return joinNode;
  }
  
  private CFGNode createDoWhileStatement(CFGNode prev, DoStatement stmt)
  {
    CFGNode loopBeginNode = createSkipNode();
    CFGNode beforeCondNode = createSkipNode();
    CFGNode joinNode = createSkipNode();
    CFGNode lastNode = null;
    
    currentEnv.push(new LoopElement(joinNode, beforeCondNode));
    
    connectNodes(prev, loopBeginNode);
    
    lastNode = createStatement(loopBeginNode, stmt.getBody());
    
    connectNodes(lastNode, beforeCondNode);
    
    prev = createExpr(beforeCondNode, stmt.getExpression(), 1);
    
    connectNodes(prev, loopBeginNode);
    connectNodes(prev, joinNode);
    
    currentEnv.pop();
    
    return joinNode;
  }
  
  private CFGNode createSwitchStatement(CFGNode prev, SwitchStatement stmt)
  {
    prev = createExpr(prev, stmt.getExpression(), 1);
    
    CFGNode joinNode = createSkipNode();
    
    currentEnv.push(new SwitchElement(joinNode, prev));
    
    currentEnv.getEnclosingSwitch().setPrevOfCaseExprChain(prev);
    
    List body = stmt.statements();
    
    prev = null;
    for (Object statement : body)
    {
      Statement node = (Statement)statement;
      prev = createStatement(prev, node);
    }
    connectNodes(prev, joinNode);
    if (currentEnv.getEnclosingSwitch().getDefaultNode() == null)
    {
      connectNodes(currentEnv.getEnclosingSwitch().getPrevOfCaseExprChain(), joinNode);
    }
    else
    {
      CFGNode prevCaseExpr = currentEnv.getEnclosingSwitch().getPrevOfCaseExprChain();
      CFGNode defaultBeginNode = currentEnv.getEnclosingSwitch().getDefaultNode();
      connectNodes(prevCaseExpr, defaultBeginNode);
    }
    currentEnv.pop();
    
    return joinNode;
  }
  
  private CFGNode createCaseDefaultStatement(CFGNode prev, SwitchCase stmt)
  {
    CFGNode caseBeginNode = createSkipNode();
    CFGNode caseAfterNode = createSkipNode();
    
    connectNodes(prev, caseAfterNode);
    
    Expression expr = stmt.getExpression();
    if (expr != null)
    {
      CFGNode prevCaseExpr = currentEnv.getEnclosingSwitch().getPrevOfCaseExprChain();
      connectNodes(prevCaseExpr, caseBeginNode);
      prev = createExpr(caseBeginNode, expr, 1);
      currentEnv.getEnclosingSwitch().setPrevOfCaseExprChain(prev);
    }
    else
    {
      currentEnv.getEnclosingSwitch().setDefaultNode(caseBeginNode);
      prev = caseBeginNode;
    }
    connectNodes(prev, caseAfterNode);
    
    return caseAfterNode;
  }
  
  private CFGNode createReturnStatement(CFGNode prev, ReturnStatement stmt)
  {
    Expression expr = stmt.getExpression();
    if (expr != null) {
      prev = createExpr(prev, expr, 1);
    }
    for (int i = currentEnv.size() - 1; i >= 0; i--)
    {
      EnvironmentElement element = currentEnv.get(i);
      
      prev = createFinallyByEnv(prev, element, i - 1);
    }
    return null;
  }
  
  private CFGNode createBreakStatement(CFGNode prev, BreakStatement stmt)
  {
    SimpleName labelName = stmt.getLabel();
    if (labelName == null) {
      for (int i = currentEnv.size() - 1; i >= 0; i--)
      {
        EnvironmentElement element = currentEnv.get(i);
        if ((element instanceof SwitchElement))
        {
          connectNodes(prev, ((SwitchElement)element).getBreakTarget());
          
          return null;
        }
        if ((element instanceof LoopElement))
        {
          connectNodes(prev, ((LoopElement)element).getBreakTarget());
          
          return null;
        }
        prev = createFinallyByEnv(prev, element, i - 1);
      }
    } else {
      for (int i = currentEnv.size() - 1; i >= 0; i--)
      {
        EnvironmentElement element = currentEnv.get(i);
        if (((element instanceof SwitchElement)) || 
          ((element instanceof LoopElement)) || 
          ((element instanceof LabeledStmtElement)))
        {
          i = currentEnv.hasCorrespondingLabel(labelName.getIdentifier(), i);
          if (i == -10)
          {
            CFGNode breakTarget = null;
            if ((element instanceof SwitchElement)) {
              breakTarget = ((SwitchElement)element).getBreakTarget();
            } else if ((element instanceof LoopElement)) {
              breakTarget = ((LoopElement)element).getBreakTarget();
            } else if ((element instanceof LabeledStmtElement)) {
              breakTarget = ((LabeledStmtElement)element).getBreakTarget();
            }
            connectNodes(prev, breakTarget);
            
            return null;
          }
        }
        else
        {
          prev = createFinallyByEnv(prev, element, i - 1);
        }
      }
    }
    throw new TracingUnsupportedException();
  }
  
  private CFGNode createContinueStatement(CFGNode prev, ContinueStatement stmt)
  {
    SimpleName labelName = stmt.getLabel();
    if (labelName == null) {
      for (int i = currentEnv.size() - 1; i >= 0; i--)
      {
        EnvironmentElement element = currentEnv.get(i);
        if ((element instanceof LoopElement))
        {
          connectNodes(prev, ((LoopElement)element).getContinueTarget());
          
          return null;
        }
        prev = createFinallyByEnv(prev, element, i - 1);
      }
    } else {
      for (int i = currentEnv.size() - 1; i >= 0; i--)
      {
        EnvironmentElement element = currentEnv.get(i);
        if ((element instanceof LoopElement))
        {
          i = currentEnv.hasCorrespondingLabel(labelName.getIdentifier(), i);
          if (i == -10)
          {
            CFGNode continueTarget = ((LoopElement)element).getContinueTarget();
            connectNodes(prev, continueTarget);
            
            return null;
          }
        }
        else
        {
          prev = createFinallyByEnv(prev, element, i - 1);
        }
      }
    }
    throw new TracingUnsupportedException();
  }
  
  private CFGNode createLabeledStatement(CFGNode prev, LabeledStatement stmt)
  {
    String labelName = stmt.getLabel().getIdentifier();
    CFGNode joinNode = createSkipNode();
    Statement body = stmt.getBody();
    
    currentEnv.push(new LabeledStmtElement(labelName, joinNode));
    
    prev = createStatement(prev, body);
    connectNodes(prev, joinNode);
    
    currentEnv.pop();
    
    return joinNode;
  }
  
  private CFGNode createWithStatement(CFGNode prev, WithStatement stmt)
  {
    prev = createExpr(prev, stmt.getExpression(), 1);
    if (checkSelectedNameString(stmt.getBody())) {
      throw new TracingUnsupportedException();
    }
    return prev;
  }
  
  private CFGNode createTryStatement(CFGNode prev, TryStatement stmt)
  {
    CFGNode catchBeginNode = null;
    CFGNode finallyBeginNode = null;
    List catchClauses = stmt.catchClauses();
    Block finallyBlock = stmt.getFinally();
    if (catchClauses.size() > 0) {
      catchBeginNode = createSkipNode();
    }
    if (finallyBlock != null) {
      finallyBeginNode = createSkipNode();
    }
    CFGNode trySkipNode = createTrySkipNode(catchBeginNode);
    connectNodes(prev, trySkipNode);
    prev = trySkipNode;
    
    Block tryBlock = stmt.getBody();
    currentEnv.push(new TryElement(stmt, catchBeginNode));
    
    prev = createStatement(prev, tryBlock);
    
    currentEnv.pop();
    
    CFGNode prev1 = prev;
    if (catchClauses.size() > 0)
    {
      currentEnv.push(new CatchElement(stmt));
      
      Object catchClauseObject = catchClauses.get(0);
      
      prev = catchBeginNode;
      CatchClause catchClause = (CatchClause)catchClauseObject;
      SimpleName exceptionParam = catchClause.getException().getName();
      prev = createSimpleName(prev, exceptionParam);
      prev = createStatement(prev, catchClause.getBody());
      
      currentEnv.pop();
    }
    if (finallyBlock != null)
    {
      connectNodes(prev, finallyBeginNode);
      if (catchClauses.size() > 0) {
        connectNodes(prev1, finallyBeginNode);
      }
      prev = finallyBeginNode;
      prev = createStatement(prev, finallyBlock);
    }
    else
    {
      CFGNode joinNode = createSkipNode();
      connectNodes(prev, joinNode);
      if (catchClauses.size() > 0) {
        connectNodes(prev1, joinNode);
      }
      prev = joinNode;
    }
    return prev;
  }
  
  private CFGNode createThrowStatement(CFGNode prev, ThrowStatement stmt)
  {
    prev = createExpr(prev, stmt.getExpression(), 1);
    for (int i = currentEnv.size() - 1; i >= 0; i--)
    {
      EnvironmentElement element = currentEnv.get(i);
      if (((element instanceof TryElement)) && 
        (((TryElement)element).getCatchBeginNode() != null))
      {
        connectNodes(prev, ((TryElement)element).getCatchBeginNode());
        
        return null;
      }
      prev = createFinallyByEnv(prev, element, i - 1);
    }
    return null;
  }
  
  private CFGNode createFinallyByEnv(CFGNode prev, EnvironmentElement element, int toIndex)
  {
    if (((element instanceof TryElement)) && (((TryElement)element).hasFinally()))
    {
      environments.push(currentEnv.copyEnvironmentFromBottom(toIndex));
      currentEnv = ((EnvironmentStack)environments.peek());
      prev = createStatement(prev, ((TryElement)element).getTryStmt().getFinally());
      environments.pop();
      currentEnv = ((EnvironmentStack)environments.peek());
    }
    else if (((element instanceof CatchElement)) && (((CatchElement)element).hasFinally()))
    {
      environments.push(currentEnv.copyEnvironmentFromBottom(toIndex));
      currentEnv = ((EnvironmentStack)environments.peek());
      prev = createStatement(prev, ((CatchElement)element).getTryStmt().getFinally());
      environments.pop();
      currentEnv = ((EnvironmentStack)environments.peek());
    }
    return prev;
  }
  
  private CFGNode createExpr(CFGNode prev, Expression expr, int side)
  {
    if (expr == null) {
      return prev;
    }
    CFGNode def;
    Object argument;
    switch (expr.getNodeType())
    {
    case 42: 
      SimpleName name = (SimpleName)expr;
      if (isSelectedBinding(name))
      {
        CFGNode node = null;
        if (side == 1)
        {
          node = createNode(name, Integer.valueOf(1));
          connectNodes(prev, node);
          prev = node;
        }
      }
      break;
    case 27: 
      InfixExpression infixExpr = (InfixExpression)expr;
      InfixExpression.Operator operator = infixExpr.getOperator();
      
      Expression operand1 = infixExpr.getLeftOperand();
      Expression operand2 = infixExpr.getRightOperand();
      Object extendedOperand;
      if ((operator == InfixExpression.Operator.CONDITIONAL_OR) || 
        (operator == InfixExpression.Operator.CONDITIONAL_AND))
      {
        prev = createExpr(prev, operand1, 1);
        CFGNode skip = createSkipNode();
        connectNodes(prev, skip);
        prev = createExpr(prev, operand2, 1);
        connectNodes(prev, skip);
        if (infixExpr.hasExtendedOperands())
        {
          List extendedOperands = infixExpr.extendedOperands();
          for (Iterator localIterator = extendedOperands.iterator(); localIterator.hasNext();)
          {
            extendedOperand = localIterator.next();
            prev = createExpr(prev, (Expression)extendedOperand, 1);
            connectNodes(prev, skip);
          }
        }
        prev = skip;
      }
      else
      {
        prev = createExpr(prev, operand1, 1);
        prev = createExpr(prev, operand2, 1);
        if (infixExpr.hasExtendedOperands())
        {
          List extendedOperands = infixExpr.extendedOperands();
          for (extendedOperand = extendedOperands.iterator(); ((Iterator)extendedOperand).hasNext();)
          {
            Object extendedOperand = ((Iterator)extendedOperand).next();
            prev = createExpr(prev, (Expression)extendedOperand, 1);
          }
        }
      }
      break;
    case 37: 
      PostfixExpression postfixExpr = (PostfixExpression)expr;
      PostfixExpression.Operator operator = postfixExpr.getOperator();
      
      prev = createExpr(prev, postfixExpr.getOperand(), 1);
      if ((operator == PostfixExpression.Operator.INCREMENT) || 
        (operator == PostfixExpression.Operator.DECREMENT))
      {
        SimpleName interestingId = searchId(postfixExpr.getOperand());
        if (interestingId != null)
        {
          CFGNode use = createNode(interestingId, Integer.valueOf(1));
          connectNodes(prev, use);
          CFGNode def = createNode(interestingId, Integer.valueOf(0));
          connectNodes(use, def);
          prev = def;
        }
      }
      break;
    case 38: 
      PrefixExpression prefixExpr = (PrefixExpression)expr;
      PrefixExpression.Operator operator = prefixExpr.getOperator();
      if ((operator == PrefixExpression.Operator.INCREMENT) || 
        (operator == PrefixExpression.Operator.DECREMENT))
      {
        SimpleName interestingId = searchId(prefixExpr.getOperand());
        if (interestingId != null)
        {
          CFGNode use = createNode(interestingId, Integer.valueOf(1));
          connectNodes(prev, use);
          def = createNode(interestingId, Integer.valueOf(0));
          connectNodes(use, def);
          prev = def;
        }
      }
      prev = createExpr(prev, prefixExpr.getOperand(), 1);
      break;
    case 7: 
      Assignment assignmentExpr = (Assignment)expr;
      Assignment.Operator operator = assignmentExpr.getOperator();
      if (operator == Assignment.Operator.ASSIGN)
      {
        prev = createExpr(prev, assignmentExpr.getLeftHandSide(), 0);
        prev = createExpr(prev, assignmentExpr.getRightHandSide(), 1);
        prev = evaluateLHSdef(prev, assignmentExpr.getLeftHandSide());
      }
      else
      {
        prev = createExpr(prev, assignmentExpr.getLeftHandSide(), 1);
        prev = createExpr(prev, assignmentExpr.getRightHandSide(), 1);
        prev = evaluateLHSdef(prev, assignmentExpr.getLeftHandSide());
      }
      break;
    case 32: 
      FunctionInvocation functionInvocationExpr = (FunctionInvocation)expr;
      Expression optionalExpr = functionInvocationExpr.getExpression();
      if (optionalExpr != null) {
        prev = createExpr(prev, optionalExpr, 1);
      }
      if (functionInvocationExpr.getName() != null) {
        prev = createExpr(prev, functionInvocationExpr.getName(), 1);
      }
      List argumentExprList = functionInvocationExpr.arguments();
      for (def = argumentExprList.iterator(); def.hasNext();)
      {
        argument = def.next();
        prev = createExpr(prev, (Expression)argument, 1);
      }
      break;
    case 36: 
      ParenthesizedExpression parenthesizedExpr = (ParenthesizedExpression)expr;
      prev = createExpr(prev, parenthesizedExpr.getExpression(), side);
      break;
    case 91: 
      ListExpression listExpression = (ListExpression)expr;
      List exprList = listExpression.expressions();
      for (argument = exprList.iterator(); ((Iterator)argument).hasNext();)
      {
        Object expr1 = ((Iterator)argument).next();
        prev = createExpr(prev, (Expression)expr1, 1);
      }
      break;
    case 2: 
      ArrayAccess arrayAccessExpr = (ArrayAccess)expr;
      prev = createExpr(prev, arrayAccessExpr.getArray(), 1);
      prev = createExpr(prev, arrayAccessExpr.getIndex(), 1);
      break;
    case 4: 
      ArrayInitializer arrayInitializerExpr = (ArrayInitializer)expr;
      List elementExprList = arrayInitializerExpr.expressions();
      for (argument = elementExprList.iterator(); ((Iterator)argument).hasNext();)
      {
        Object arrayElement = ((Iterator)argument).next();
        prev = createExpr(prev, (Expression)arrayElement, 1);
      }
      break;
    case 14: 
      ClassInstanceCreation classInstanceCreationExpr = (ClassInstanceCreation)expr;
      
      prev = createExpr(prev, classInstanceCreationExpr.getMember(), 1);
      
      List argumentExprList = classInstanceCreationExpr.arguments();
      for (argument = argumentExprList.iterator(); ((Iterator)argument).hasNext();)
      {
        Object argument = ((Iterator)argument).next();
        prev = createExpr(prev, (Expression)argument, 1);
      }
      break;
    case 22: 
      FieldAccess fieldAccessExpr = (FieldAccess)expr;
      prev = createExpr(prev, fieldAccessExpr.getExpression(), 1);
      prev = createExpr(prev, fieldAccessExpr.getName(), 1);
      break;
    case 16: 
      ConditionalExpression condExpr = (ConditionalExpression)expr;
      
      CFGNode skip = createSkipNode();
      if (side == 1)
      {
        prev = createExpr(prev, condExpr.getExpression(), 1);
        connectNodes(createExpr(prev, condExpr.getThenExpression(), 1), skip);
        connectNodes(createExpr(prev, condExpr.getElseExpression(), 1), skip);
        prev = skip;
      }
      else
      {
        prev = createExpr(prev, condExpr.getExpression(), 1);
        connectNodes(createExpr(prev, condExpr.getThenExpression(), 0), skip);
        connectNodes(createExpr(prev, condExpr.getElseExpression(), 0), skip);
        prev = skip;
      }
      break;
    case 85: 
      ObjectLiteral objectLiteral = (ObjectLiteral)expr;
      List fieldList = objectLiteral.fields();
      for (argument = fieldList.iterator(); ((Iterator)argument).hasNext();)
      {
        Object objectLiteralField = ((Iterator)argument).next();
        prev = createExpr(prev, (Expression)objectLiteralField, 1);
      }
      break;
    case 86: 
      ObjectLiteralField objectLiteralField = (ObjectLiteralField)expr;
      prev = createExpr(prev, objectLiteralField.getFieldName(), 1);
      prev = createExpr(prev, objectLiteralField.getInitializer(), 1);
      break;
    case 58: 
      VariableDeclarationExpression varDeclExpr = 
        (VariableDeclarationExpression)expr;
      
      List fragments = varDeclExpr.fragments();
      for (argument = fragments.iterator(); ((Iterator)argument).hasNext();)
      {
        Object fragment = ((Iterator)argument).next();
        VariableDeclarationFragment varDecl = (VariableDeclarationFragment)fragment;
        prev = createVariableDeclarationFragment(prev, varDecl);
      }
      break;
    case 84: 
      FunctionExpression functionExpr = (FunctionExpression)expr;
      if (checkDefExists(functionExpr.getMethod())) {
        throw new TracingUnsupportedException();
      }
      break;
    case 9: 
    case 33: 
    case 34: 
    case 45: 
    case 52: 
    case 87: 
    case 88: 
    case 92: 
      break;
    default: 
      if (!$assertionsDisabled) {
        throw new AssertionError();
      }
      break;
    }
    return prev;
  }
  
  private CFGNode evaluateLHSdef(CFGNode prev, Expression expr)
  {
    if ((expr instanceof ParenthesizedExpression))
    {
      ParenthesizedExpression parenthesizedExpr = (ParenthesizedExpression)expr;
      prev = evaluateLHSdef(prev, parenthesizedExpr.getExpression());
    }
    else if ((expr instanceof ConditionalExpression))
    {
      ConditionalExpression conditionalExpr = (ConditionalExpression)expr;
      
      CFGNode skip = createSkipNode();
      
      connectNodes(evaluateLHSdef(prev, conditionalExpr.getThenExpression()), skip);
      connectNodes(evaluateLHSdef(prev, conditionalExpr.getElseExpression()), skip);
      prev = skip;
    }
    else if ((expr instanceof SimpleName))
    {
      SimpleName name = (SimpleName)expr;
      prev = createSimpleName(prev, name);
    }
    return prev;
  }
  
  private boolean checkDefExists(FunctionDeclaration func)
  {
    return new DefChecker(cancelMonitor).checkDefExists(func, selectedName);
  }
  
  private boolean checkSelectedNameContainment(ASTNode root)
  {
    SelectedNameContainingChecker checker = new SelectedNameContainingChecker();
    root.accept(checker);
    return checker.getResult();
  }
  
  private boolean hasSelectedNameString(SimpleName name)
  {
    return selectedName.getIdentifier().equals(name.getIdentifier());
  }
  
  private boolean checkSelectedNameString(ASTNode root)
  {
    SelectedNameStringChecker checker = new SelectedNameStringChecker();
    root.accept(checker);
    return checker.getResult();
  }
  
  protected void connectNodes(CFGNode prev, CFGNode next)
  {
    if ((prev == null) || (next == null)) {
      return;
    }
    prev.addSucc(next);
    next.addPred(prev);
  }
  
  protected CFGNode createNode(SimpleName name, Integer nodeType)
  {
    CFGNode node = null;
    if (nodeType.intValue() == 0) {
      node = new DefNode(name, nodeCo
1 2 3

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2017. Infinite Loop Ltd