| /* |
| * Copyright (C) 2010 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.clearsilver.jsilver.interpreter; |
| |
| import com.google.clearsilver.jsilver.syntax.analysis.DepthFirstAdapter; |
| import com.google.clearsilver.jsilver.syntax.node.ADecNumberVariable; |
| import com.google.clearsilver.jsilver.syntax.node.ADescendVariable; |
| import com.google.clearsilver.jsilver.syntax.node.AExpandVariable; |
| import com.google.clearsilver.jsilver.syntax.node.AHexNumberVariable; |
| import com.google.clearsilver.jsilver.syntax.node.ANameVariable; |
| import com.google.clearsilver.jsilver.syntax.node.PVariable; |
| import com.google.clearsilver.jsilver.values.Value; |
| |
| /** |
| * Walks a PVariable node from the parse tree and returns a Data path name. |
| * |
| * @see #getVariableName(com.google.clearsilver.jsilver.syntax.node.PVariable) |
| */ |
| public class VariableLocator extends DepthFirstAdapter { |
| |
| private StringBuilder currentName; |
| |
| private final ExpressionEvaluator expressionEvaluator; |
| |
| public VariableLocator(ExpressionEvaluator expressionEvaluator) { |
| this.expressionEvaluator = expressionEvaluator; |
| } |
| |
| /** |
| * If the root PVariable we are evaluating is a simple one then skip creating the StringBuilder |
| * and descending the tree. |
| * |
| * @param variable the variable node to evaluate. |
| * @return a String representing the Variable name, or {@code null} if it is a compound variable |
| * node. |
| */ |
| private String quickEval(PVariable variable) { |
| if (variable instanceof ANameVariable) { |
| return ((ANameVariable) variable).getWord().getText(); |
| } else if (variable instanceof ADecNumberVariable) { |
| return ((ADecNumberVariable) variable).getDecNumber().getText(); |
| } else if (variable instanceof AHexNumberVariable) { |
| return ((AHexNumberVariable) variable).getHexNumber().getText(); |
| } else { |
| // This is a compound variable. Evaluate the slow way. |
| return null; |
| } |
| } |
| |
| /** |
| * Returns a Data variable name extracted during evaluation. |
| * |
| * @param variable the parsed variable name node to traverse |
| */ |
| public String getVariableName(PVariable variable) { |
| String result = quickEval(variable); |
| if (result != null) { |
| return result; |
| } |
| StringBuilder lastName = currentName; |
| currentName = new StringBuilder(10); |
| variable.apply(this); |
| result = currentName.toString(); |
| currentName = lastName; |
| return result; |
| } |
| |
| @Override |
| public void caseANameVariable(ANameVariable node) { |
| descendVariable(node.getWord().getText()); |
| } |
| |
| @Override |
| public void caseADecNumberVariable(ADecNumberVariable node) { |
| descendVariable(node.getDecNumber().getText()); |
| } |
| |
| @Override |
| public void caseAHexNumberVariable(AHexNumberVariable node) { |
| descendVariable(node.getHexNumber().getText()); |
| } |
| |
| @Override |
| public void caseADescendVariable(ADescendVariable node) { |
| node.getParent().apply(this); |
| node.getChild().apply(this); |
| } |
| |
| @Override |
| public void caseAExpandVariable(AExpandVariable node) { |
| node.getParent().apply(this); |
| Value value = expressionEvaluator.evaluate(node.getChild()); |
| descendVariable(value.asString()); |
| } |
| |
| private void descendVariable(String name) { |
| if (currentName.length() != 0) { |
| currentName.append('.'); |
| } |
| currentName.append(name); |
| } |
| } |