001package daikon.tools.jtb; 002 003import java.util.Enumeration; 004import jtb.syntaxtree.*; 005import jtb.visitor.*; 006 007/** 008 * OrigModifier is a visitor that places "orig()" around varible names and correspondingly corrects 009 * positioning fields of all the tokens in tree to accomodate the change. For example, the 010 * expression get(this.x) would be changed to get(orig(this.x)). 011 */ 012public class OrigModifier extends DepthFirstVisitor { 013 014 private int columnshift = 0; 015 private int columnshiftline = -1; 016 017 // columnshifting only applies to a single line, then is turned off agian. 018 // States for the variables: 019 // columnshift == 0, columnshiftline == -1: 020 // no column shifting needed 021 // columnshift != 0, columnshiftline != -1: 022 // column shifting being needed, applies only to specified line 023 024 /** 025 * Corrects column fields of n. 026 * 027 * <p>Modifies: n, this. 028 */ 029 @Override 030 public void visit(NodeToken n) { 031 if (n.beginLine == columnshiftline) { 032 n.beginColumn = n.beginColumn + columnshift; 033 n.endColumn = n.endColumn + columnshift; 034 } else { 035 columnshift = 0; 036 columnshiftline = -1; 037 } 038 } 039 040 /** 041 * Checks if n is a variable name. If so adds "orig(" to the front of the name and ")" to the end. 042 * 043 * <p>Modifies: n, this. 044 */ 045 // f0 -> PrimaryPrefix() 046 // f1 -> ( PrimarySuffix() )* 047 @Override 048 @SuppressWarnings("JdkObsolete") // JTB Enumeration 049 public void visit(PrimaryExpression n) { 050 // let simple variables be variables with out "."'s in their names 051 // such as x or myList 052 // let compound variables be variables with "."'s in their names 053 // such as this.x or myPackage.MyObject.myList 054 055 // First checks for and handles simple variables. 056 057 // test if optional list length is zero, if not, then it is not 058 // the name of a simple variable 059 if (n.f1.size() == 0) { 060 // checks if the nodeChoice's choice is Name 061 if (n.f0.f0.choice instanceof Name) { 062 // checks if the Name is simple 063 if (((Name) n.f0.f0.choice).f1.size() == 0) { 064 NodeToken variableToken = ((Name) n.f0.f0.choice).f0; 065 variableToken.tokenImage = "orig(" + variableToken.tokenImage + ")"; 066 columnshift = columnshift + 6; 067 columnshiftline = variableToken.endLine; 068 super.visit(n); 069 070 // Corrects for the fact that super.visit(n) incremented 071 // variableToken.beginColumn by 6 too much since the addition of 072 // "orig()" does not effect firstToken.beginColumn. 073 variableToken.beginColumn = variableToken.beginColumn - 6; 074 return; 075 } 076 } 077 } 078 079 if (n.f1.size() == 1) { 080 // System.out.println("if1"); 081 if (n.f1.elementAt(0) instanceof PrimarySuffix) { 082 // System.out.println("if2"); 083 if (((PrimarySuffix) n.f1.elementAt(0)).f0.choice instanceof NodeSequence) { 084 if (n.f0.f0.choice instanceof NodeToken) { 085 NodeToken firstToken = (NodeToken) n.f0.f0.choice; 086 firstToken.tokenImage = "orig(" + firstToken.tokenImage; 087 Enumeration<Node> nodeSequence = 088 ((NodeSequence) ((PrimarySuffix) n.f1.elementAt(0)).f0.choice).elements(); 089 NodeToken lastToken = firstToken; 090 while (nodeSequence.hasMoreElements()) { 091 lastToken = (NodeToken) nodeSequence.nextElement(); 092 } 093 lastToken.tokenImage = lastToken.tokenImage + ")"; 094 095 // Updates columnshift for the addition of "orig(", the 096 // columnshift is updated for the addition of ")" after 097 // super.visit(n) 098 columnshift = columnshift + 5; 099 columnshiftline = firstToken.beginLine; 100 super.visit(n); 101 102 // Corrects for the fact that super.visit(n) incremented 103 // firstToken.beginColumn by 5 too much since the addition 104 // of "orig(" does not effect firstToken.beginColumn. 105 firstToken.beginColumn = firstToken.beginColumn - 5; 106 107 // since lastToken is the last node in the visiting order 108 // of n, all NodeToken effected by the addition of the 109 // ")" at the end of lastToken are visited after all the children 110 // of are visited. Thus,super.visit(n) may be called before 111 // all code that corrects the column fields for the addition of 112 // ")". 113 columnshiftline = lastToken.endLine; 114 columnshift = columnshift + 1; 115 lastToken.endColumn = lastToken.endColumn + 1; 116 return; 117 } 118 } 119 } 120 } 121 super.visit(n); 122 } 123}