📄 expressionevaluator.java
字号:
/**
* Copyright (c) 2003-2005 Craig Setera
* All Rights Reserved.
* Licensed under the Eclipse Public License - v 1.0
* For more information see http://www.eclipse.org/legal/epl-v10.html
*/
package eclipseme.core.internal.preprocessor.directive;
import java.util.Stack;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import eclipseme.core.model.SymbolDefinitionSet;
/**
* A class that is capable of evaluating a directive
* expression for a true or false value.
* <p />
* Copyright (c) 2003-2005 Craig Setera<br>
* All Rights Reserved.<br>
* Licensed under the Eclipse Public License - v 1.0<p/>
* <br>
* $Revision: 1.2 $
* <br>
* $Date: 2006/11/12 01:11:01 $
* <br>
* @author Craig Setera
*/
public class ExpressionEvaluator {
private static final String PREAMBLE =
"public class ParseClass { " +
"public static boolean value = ";
private static final String POSTLUDE = "; }";
// An AST visitor to find the actual expression that we are interested in
// locating.
private class LocateExpressionVisitor extends ASTVisitor {
private Expression expression;
/**
* Construct a new visitor
*/
LocateExpressionVisitor() {
super(false);
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationExpression)
*/
public boolean visit(VariableDeclarationFragment node) {
expression = node.getInitializer();
return false; // No need to continue searching
}
/**
* Return the expression located by the visitor.
*
* @return
*/
public Expression getExpression() {
return expression;
}
}
private class ExpressionEvaluationVisitor extends ASTVisitor {
private SymbolDefinitionSet identifiers;
private Stack resultStack;
/**
* Construct a new visitor
* @param identifiers
*/
public ExpressionEvaluationVisitor(SymbolDefinitionSet identifiers) {
super(false);
this.identifiers = identifiers;
resultStack = new Stack();
}
/**
* Return the result of the evaluation.
*
* @return
*/
public boolean getResult() {
return ((Boolean) resultStack.peek()).booleanValue();
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InfixExpression)
*/
public void endVisit(InfixExpression node) {
InfixExpression.Operator operator = node.getOperator();
if (operator == InfixExpression.Operator.AND) {
pushValue(popValue() & popValue());
} else if (operator == InfixExpression.Operator.CONDITIONAL_AND) {
pushValue(popValue() && popValue());
} else if (operator == InfixExpression.Operator.CONDITIONAL_OR) {
pushValue(popValue() || popValue());
} else if (operator == InfixExpression.Operator.XOR) {
pushValue(popValue() ^ popValue());
} else if (operator == InfixExpression.Operator.OR) {
pushValue(popValue() | popValue());
} else {
throw new UnsupportedOperationException(operator + " unsupported");
}
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.PrefixExpression)
*/
public void endVisit(PrefixExpression node) {
PrefixExpression.Operator operator = node.getOperator();
if (operator == PrefixExpression.Operator.NOT) {
pushValue(!popValue());
} else {
throw new UnsupportedOperationException(operator + " unsupported");
}
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedName)
*/
public boolean visit(QualifiedName node) {
visitName(node);
return true;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleName)
*/
public boolean visit(SimpleName node) {
visitName(node);
return true;
}
/**
* Return the top boolean value on the stack.
*
* @return
*/
private boolean popValue() {
Boolean topValue = (Boolean) resultStack.pop();
return topValue.booleanValue();
}
/**
* Push a new boolean value onto the stack.
*
* @param value
*/
private void pushValue(boolean value) {
resultStack.push(Boolean.valueOf(value));
}
/**
* Visit a name.
*
* @param node
*/
private void visitName(Name node) {
String name = node.getFullyQualifiedName();
pushValue(identifiers.isDefined(name));
}
}
private String expression;
/**
* Construct a new evaluator for the specified expression.
*
* @param expression
*/
public ExpressionEvaluator(String expression) {
super();
this.expression = expression;
}
/**
* Evaluate the expression and return the results of the evaluation.
*
* @param monitor
* @return
*/
public boolean evaluate(SymbolDefinitionSet identifiers, IProgressMonitor monitor) {
Expression expression = getExpression(monitor);
ExpressionEvaluationVisitor visitor = new ExpressionEvaluationVisitor(identifiers);
expression.accept(visitor);
return visitor.getResult();
}
/**
* Return the expression node created for the expression.
*
* @param monitor
* @return
*/
private Expression getExpression(IProgressMonitor monitor) {
ASTNode compilationUnitNode = parseExpression(monitor);
LocateExpressionVisitor visitor = new LocateExpressionVisitor();
compilationUnitNode.accept(visitor);
return visitor.getExpression();
}
/**
* Return the expression in a form that it may be parsed by the
* Eclipse AST implementation.
*
* @return
*/
private String getParsableExpression() {
StringBuffer sb = new StringBuffer(PREAMBLE);
sb.append(expression).append(POSTLUDE);
return sb.toString();
}
/**
* Return an AST compilation unit representing the
* parsable expression.
*
* @param monitor
* @return
*/
private ASTNode parseExpression(IProgressMonitor monitor) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
String parsable = getParsableExpression();
parser.setSource(parsable.toCharArray());
return parser.createAST(monitor);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -