• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.clearsilver.jsilver.interpreter;
18 
19 import com.google.clearsilver.jsilver.syntax.analysis.DepthFirstAdapter;
20 import com.google.clearsilver.jsilver.syntax.node.ADecNumberVariable;
21 import com.google.clearsilver.jsilver.syntax.node.ADescendVariable;
22 import com.google.clearsilver.jsilver.syntax.node.AExpandVariable;
23 import com.google.clearsilver.jsilver.syntax.node.AHexNumberVariable;
24 import com.google.clearsilver.jsilver.syntax.node.ANameVariable;
25 import com.google.clearsilver.jsilver.syntax.node.PVariable;
26 import com.google.clearsilver.jsilver.values.Value;
27 
28 /**
29  * Walks a PVariable node from the parse tree and returns a Data path name.
30  *
31  * @see #getVariableName(com.google.clearsilver.jsilver.syntax.node.PVariable)
32  */
33 public class VariableLocator extends DepthFirstAdapter {
34 
35   private StringBuilder currentName;
36 
37   private final ExpressionEvaluator expressionEvaluator;
38 
VariableLocator(ExpressionEvaluator expressionEvaluator)39   public VariableLocator(ExpressionEvaluator expressionEvaluator) {
40     this.expressionEvaluator = expressionEvaluator;
41   }
42 
43   /**
44    * If the root PVariable we are evaluating is a simple one then skip creating the StringBuilder
45    * and descending the tree.
46    *
47    * @param variable the variable node to evaluate.
48    * @return a String representing the Variable name, or {@code null} if it is a compound variable
49    *         node.
50    */
quickEval(PVariable variable)51   private String quickEval(PVariable variable) {
52     if (variable instanceof ANameVariable) {
53       return ((ANameVariable) variable).getWord().getText();
54     } else if (variable instanceof ADecNumberVariable) {
55       return ((ADecNumberVariable) variable).getDecNumber().getText();
56     } else if (variable instanceof AHexNumberVariable) {
57       return ((AHexNumberVariable) variable).getHexNumber().getText();
58     } else {
59       // This is a compound variable. Evaluate the slow way.
60       return null;
61     }
62   }
63 
64   /**
65    * Returns a Data variable name extracted during evaluation.
66    *
67    * @param variable the parsed variable name node to traverse
68    */
getVariableName(PVariable variable)69   public String getVariableName(PVariable variable) {
70     String result = quickEval(variable);
71     if (result != null) {
72       return result;
73     }
74     StringBuilder lastName = currentName;
75     currentName = new StringBuilder(10);
76     variable.apply(this);
77     result = currentName.toString();
78     currentName = lastName;
79     return result;
80   }
81 
82   @Override
caseANameVariable(ANameVariable node)83   public void caseANameVariable(ANameVariable node) {
84     descendVariable(node.getWord().getText());
85   }
86 
87   @Override
caseADecNumberVariable(ADecNumberVariable node)88   public void caseADecNumberVariable(ADecNumberVariable node) {
89     descendVariable(node.getDecNumber().getText());
90   }
91 
92   @Override
caseAHexNumberVariable(AHexNumberVariable node)93   public void caseAHexNumberVariable(AHexNumberVariable node) {
94     descendVariable(node.getHexNumber().getText());
95   }
96 
97   @Override
caseADescendVariable(ADescendVariable node)98   public void caseADescendVariable(ADescendVariable node) {
99     node.getParent().apply(this);
100     node.getChild().apply(this);
101   }
102 
103   @Override
caseAExpandVariable(AExpandVariable node)104   public void caseAExpandVariable(AExpandVariable node) {
105     node.getParent().apply(this);
106     Value value = expressionEvaluator.evaluate(node.getChild());
107     descendVariable(value.asString());
108   }
109 
descendVariable(String name)110   private void descendVariable(String name) {
111     if (currentName.length() != 0) {
112       currentName.append('.');
113     }
114     currentName.append(name);
115   }
116 }
117