blob: 76d4c9accf6bc0a8e045fd96f52e8d89c0bbc1e7 [file] [log] [blame]
/*
* 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);
}
}