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