1   // Copyright 2012- Bill Campbell, Swami Iyer and Bahar Akbal-Delibas
2   
3   package jminusminus;
4   
5   import java.util.StringTokenizer;
6   
7   /**
8    * This class is used to encapsulate ambiguous names that the parser can't distinguish and
9    * disambiguate them during the analysis phase. Ambiguous names are meant to deal with snippets
10   * like x.y.z and x.y.z().
11   */
12  class AmbiguousName {
13      // Line in which the ambiguous name occurs in the source file.
14      private int line;
15  
16      // The ambiguous part, for example x.y in x.y.z.
17      private String name;
18  
19      /**
20       * Constructs an encapsulation of the ambiguous portion of a snippet like x.y.z.
21       *
22       * @param line line in which the ambiguous name occurs in the source file.
23       * @param name the ambiguous part, for example x.y in x.y.z.
24       */
25      public AmbiguousName(int line, String name) {
26          this.line = line;
27          this.name = name;
28      }
29  
30      /**
31       * Reclassifies the name according to the rules in the Java Language Specification, and
32       * returns an AST for it.
33       *
34       * @param context context in which we look up the component names.
35       * @return the AST for the reclassified name.
36       */
37      public JExpression reclassify(Context context) {
38          JExpression result = null;
39          StringTokenizer st = new StringTokenizer(name, ".");
40  
41          // Firstly, find a variable or type.
42          String newName = st.nextToken();
43          IDefn iDefn = null;
44          do {
45              iDefn = context.lookup(newName);
46              if (iDefn != null) {
47                  result = new JVariable(line, newName);
48                  break;
49              } else if (!st.hasMoreTokens()) {
50                  // Nothing found. :(
51                  JAST.compilationUnit.reportSemanticError(line, "Cannot find name " + newName);
52                  return null;
53              } else {
54                  newName += "." + st.nextToken();
55              }
56          } while (true);
57  
58          // For now we can assume everything else is a field.
59          while (st.hasMoreTokens()) {
60              result = new JFieldSelection(line, result, st.nextToken());
61          }
62  
63          return result;
64      }
65  
66      /**
67       * Returns the ambiguous part.
68       *
69       * @return the ambiguous part.
70       */
71      public String toString() {
72          return name;
73      }
74  }
75