diff options
Diffstat (limited to 'jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/validation/internal/el/ASTSemanticValidator.java')
-rw-r--r-- | jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/validation/internal/el/ASTSemanticValidator.java | 612 |
1 files changed, 0 insertions, 612 deletions
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/validation/internal/el/ASTSemanticValidator.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/validation/internal/el/ASTSemanticValidator.java deleted file mode 100644 index 1ee65f51c..000000000 --- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/validation/internal/el/ASTSemanticValidator.java +++ /dev/null @@ -1,612 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Oracle Corporation. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Cameron Bateman/Oracle - initial API and implementation - * - ********************************************************************************/ - -package org.eclipse.jst.jsf.validation.internal.el; - -import java.io.IOException; - -import org.eclipse.core.resources.IFile; -import org.eclipse.emf.common.util.Diagnostic; -import org.eclipse.jst.jsf.common.internal.types.BooleanLiteralType; -import org.eclipse.jst.jsf.common.internal.types.FloatLiteralType; -import org.eclipse.jst.jsf.common.internal.types.IntegerLiteralType; -import org.eclipse.jst.jsf.common.internal.types.LiteralType; -import org.eclipse.jst.jsf.common.internal.types.MethodType; -import org.eclipse.jst.jsf.common.internal.types.NullLiteralType; -import org.eclipse.jst.jsf.common.internal.types.SignatureBasedType; -import org.eclipse.jst.jsf.common.internal.types.StringLiteralType; -import org.eclipse.jst.jsf.common.internal.types.ValueType; -import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory; -import org.eclipse.jst.jsf.context.resolver.structureddocument.IWorkspaceContextResolver; -import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext; -import org.eclipse.jst.jsf.context.symbol.IInstanceSymbol; -import org.eclipse.jst.jsf.context.symbol.IPropertySymbol; -import org.eclipse.jst.jsf.context.symbol.ISymbol; -import org.eclipse.jst.jsf.context.symbol.internal.util.IObjectSymbolBasedValueType; -import org.eclipse.jst.jsf.core.internal.JSFCorePlugin; -import org.eclipse.jst.jsf.designtime.resolver.IStructuredDocumentSymbolResolverFactory; -import org.eclipse.jst.jsf.designtime.resolver.ISymbolContextResolver; -import org.eclipse.jst.jsf.validation.internal.IJSFViewValidator.IValidationReporter; -import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory; -import org.eclipse.jst.jsf.validation.internal.el.operators.BinaryOperator; -import org.eclipse.jst.jsf.validation.internal.el.operators.BracketOperator; -import org.eclipse.jst.jsf.validation.internal.el.operators.DotOperator; -import org.eclipse.jst.jsf.validation.internal.el.operators.TernaryChoiceOperator; -import org.eclipse.jst.jsf.validation.internal.el.operators.UnaryOperator; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTAddExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTAndExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTChoiceExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTEqualityExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTFunctionInvocation; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTLiteral; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTMultiplyExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTOperatorExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTOrExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTRelationalExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTUnaryExpression; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTValue; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTValuePrefix; -import org.eclipse.jst.jsp.core.internal.java.jspel.ASTValueSuffix; -import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParser; -import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParserConstants; -import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParserVisitor; -import org.eclipse.jst.jsp.core.internal.java.jspel.ParseException; -import org.eclipse.jst.jsp.core.internal.java.jspel.SimpleNode; -import org.eclipse.jst.jsp.core.internal.java.jspel.Token; - - -class ASTSemanticValidator implements JSPELParserVisitor, IExpressionSemanticValidator -{ - private final IFile _targetFile; - private final ASTExpression _expr; - private final IStructuredDocumentContext _context; - private final ISymbolContextResolver _symbolResolver; -// private final List<IMessage> _messages; - private final EvaluationTracker _tracker; - private final DiagnosticFactory _diagnosticFactory; - private final IValidationReporter _reporter; - - ASTSemanticValidator(final ASTExpression expr, - final IStructuredDocumentContext context, - final IStructuredDocumentSymbolResolverFactory symbolResolverFactory, - final IValidationReporter reporter) - { - final IWorkspaceContextResolver resolver = IStructuredDocumentContextResolverFactory.INSTANCE - .getWorkspaceContextResolver(context); - - if (resolver != null) - { - _targetFile = (IFile) resolver.getResource(); - } - else - { - _targetFile = null; - } - - _expr = expr; - _context = context; - _symbolResolver = symbolResolverFactory.getSymbolContextResolver(context); - _tracker = new EvaluationTracker(); - _diagnosticFactory = new DiagnosticFactory(); - _reporter = reporter; - } - - /* (non-Javadoc) - * @see org.eclipse.jst.jsf.validation.internal.el.IExpressionSemanticValidator#validate() - */ - public void validate() - { - _expr.jjtAccept(this, _tracker); - } - - public Object visit(final ASTAddExpression node, final Object data) - { - performBinaryEvaluation(node, (EvaluationTracker)data); - return data; - } - - public Object visit(final ASTAndExpression node, final Object data) - { - performBinaryEvaluation(node, (EvaluationTracker)data); - return data; - } - - public Object visit(final ASTChoiceExpression node, final Object data) - { - if (node.jjtGetNumChildren() != 3) - { - throw new AssertionError("Binary operators should always have two sub-expressions"); //$NON-NLS-1$ - } - - // evaluate choice argument - node.jjtGetChild(0).jjtAccept(this, data); - final ValueType choiceArg = ((EvaluationTracker)data).getValueType(); - // evaluate when true argument - node.jjtGetChild(1).jjtAccept(this, data); - final ValueType whenTrueArg = ((EvaluationTracker)data).getValueType(); - //evaluate when false argument - node.jjtGetChild(2).jjtAccept(this, data); - final ValueType whenFalseArg = ((EvaluationTracker)data).getValueType(); - - - if (choiceArg != null && whenTrueArg != null && whenFalseArg != null) - { - final TernaryChoiceOperator operator = - new TernaryChoiceOperator(_diagnosticFactory); - - final Diagnostic diagnostic = - operator.validate(choiceArg/* whenTrueArg, whenFalseArg*/); - - if (diagnostic.getSeverity() != Diagnostic.OK) - { - final Token firstToken = node.getFirstToken(); - final int offset = _context.getDocumentPosition() + firstToken.beginColumn - 1; - final int length = node.getLastToken().endColumn - firstToken.beginColumn+1; - _reporter.report(diagnostic, offset, length); - } - - ((EvaluationTracker)data).setType(operator.perform(choiceArg, whenTrueArg, whenFalseArg)); - } - else - { - ((EvaluationTracker)data).setType(null); - } - - return data; - } - - public Object visit(final ASTEqualityExpression node, final Object data) - { - performBinaryEvaluation(node, (EvaluationTracker)data); - return data; - } - - public Object visit(final ASTExpression node, final Object data) { - return node.childrenAccept(this, data); - } - - public Object visit(final ASTFunctionInvocation node, final Object data) - { - // when we see a function invocation, null the type - // we do not validate function invocations currently - final Object retVal = node.childrenAccept(this, data); - ((EvaluationTracker)data).setType(null); - return retVal; - } - - public Object visit(final ASTLiteral node, final Object data) - { - // note, there is an implicit assumption here that literals - // are all terminals (leafs in the tree) - if (node.jjtGetNumChildren() > 0) - { - throw new AssertionError("Literals should be terminal"); //$NON-NLS-1$ - } - - LiteralType type = null; - - final Token literalToken = node.getFirstToken(); - - switch (literalToken.kind) - { - case JSPELParserConstants.STRING_LITERAL: - type = new StringLiteralType(stripQuotes(literalToken.image)); - break; - - case JSPELParserConstants.INTEGER_LITERAL: - type = new IntegerLiteralType(Long.parseLong(literalToken.image)); - break; - - case JSPELParserConstants.FLOATING_POINT_LITERAL: - type = new FloatLiteralType(Double.parseDouble(literalToken.image)); - break; - - case JSPELParserConstants.FALSE: - type = BooleanLiteralType.FALSE; - break; - - case JSPELParserConstants.TRUE: - type = BooleanLiteralType.TRUE; - break; - - case JSPELParserConstants.NULL: - type = NullLiteralType.SINGLETON; - break; - - default: - JSFCorePlugin.log("Unknown EL literal: " +literalToken.toString(), new Throwable("This throwable simply used to mark a stack trace")); //$NON-NLS-1$ //$NON-NLS-2$ - } - - ((EvaluationTracker)data).setType(type); - return data; - } - - private String stripQuotes(final String stringLiteral) - { - if (stringLiteral.startsWith("'") //$NON-NLS-1$ - || stringLiteral.startsWith("\"")) //$NON-NLS-1$ - - { - if (stringLiteral.length() > 2) - { - // take 'literal' -> literal - return stringLiteral.substring(1, stringLiteral.length()-1); - } - // if only two characters, then the empty string - return ""; //$NON-NLS-1$ - } - - return stringLiteral; - } - - public Object visit(final ASTMultiplyExpression node, final Object data) - { - performBinaryEvaluation(node, (EvaluationTracker)data); - return data; - } - - public Object visit(final ASTOrExpression node, final Object data) - { - performBinaryEvaluation(node, (EvaluationTracker)data); - return data; - } - - public Object visit(final ASTRelationalExpression node, final Object data) - { - performBinaryEvaluation(node, (EvaluationTracker)data); - return data; - } - - public Object visit(final ASTUnaryExpression node, final Object data) - { - // assertion here is that this expression decomposes: - // UnaryExpr -> Value - // UnaryExpr -> UnaryOp UnaryExpression - // since UnaryOp is a terminal (-,!,not,empty) node will - // always have exactly one child - node.childrenAccept(this, data); - final SignatureBasedType type = ((EvaluationTracker)data).getType(); - - if (type != null) - { - final Token firstToken = node.getFirstToken(); - if (UnaryOperator.isUnaryOperator(firstToken)) - { - if (type instanceof ValueType) - { - final UnaryOperator unaryOp = UnaryOperator.createUnaryOperator(firstToken, _diagnosticFactory); - final Diagnostic diagnostic = unaryOp.validate((ValueType)type); - - if (diagnostic.getSeverity() != Diagnostic.OK) - { - final int offset = _context.getDocumentPosition() + firstToken.beginColumn - 1; - final int length = node.getLastToken().endColumn - firstToken.beginColumn+1; - _reporter.report(diagnostic, offset, length); - } - - ((EvaluationTracker)data). - setType(unaryOp.performOperation ((ValueType)type)); - } - // cannot apply operations to method bindings - else - { - final int offset = _context.getDocumentPosition() + - firstToken.beginColumn - 1; - final int length = node.getLastToken().endColumn - - firstToken.beginColumn+1; - - Diagnostic diagnostic = - _diagnosticFactory.create_CANNOT_APPLY_OPERATOR_TO_METHOD_BINDING(); - - _reporter.report(diagnostic, offset, length); - } - } - } - - return data; - } - - public Object visit(final ASTValue node, final Object data) { - final ValueExpressionTracker tracker = new ValueExpressionTracker(); - - ((EvaluationTracker)data).setValueTracker(tracker); - - node.childrenAccept(this, data); - - final SignatureBasedType type = ((EvaluationTracker)data).getType(); - - // now check the tracker. If the last property in the expression - // is non-null (i.e. the value has one or more suffices) then we - // to very the leaf node (i.e. 'z' in #{x.y.z}) is more than just - // an intermediate value used to get to other properties - if (type instanceof IObjectSymbolBasedValueType - && ((IObjectSymbolBasedValueType)type).getSymbol() instanceof IPropertySymbol - && ((IPropertySymbol)((IObjectSymbolBasedValueType)type).getSymbol()).isIntermediate()) - { - final int offset = tracker.getCurPropertySymbolOffset(); - final int length = tracker.getCurPropertySymbolLength(); - final Diagnostic diagnostic = - _diagnosticFactory.create_MEMBER_IS_INTERMEDIATE( - ((IPropertySymbol)((IObjectSymbolBasedValueType)type).getSymbol()).getName()); - _reporter.report(diagnostic, offset, length); - } - - return data; - } - - public Object visit(final ASTValuePrefix node, final Object data) - { - if (node.jjtGetNumChildren() == 0) - { - final Token token = node.getFirstToken(); - final String image = token.image; - - final ISymbol symbol = _symbolResolver.getVariable(image); - - if (symbol == null) - { - final int offset = - _context.getDocumentPosition() + token.beginColumn - 1; - final int length = token.endColumn - token.beginColumn + 1; - - final Diagnostic diagnostic = - _diagnosticFactory.create_VARIABLE_NOT_FOUND(image); - - if (diagnostic.getSeverity() != Diagnostic.OK) - { - _reporter.report(diagnostic, offset, length); - } - } - else if (symbol instanceof IInstanceSymbol) - { - final IObjectSymbolBasedValueType symbolType = - IObjectSymbolBasedValueType.getInstance(symbol); - ((EvaluationTracker) data).setType(symbolType); - } - } - - return node.childrenAccept(this, data); - } - - public Object visit(final ASTValueSuffix node, final Object data) - { - final ValueExpressionTracker tracker = ((EvaluationTracker) data).getValueTracker(); - final SignatureBasedType type = ((EvaluationTracker) data).getType(); - - if (type instanceof IObjectSymbolBasedValueType) - { - final IObjectSymbolBasedValueType symbolType = - (IObjectSymbolBasedValueType) type; - final Token firstToken = node.getFirstToken(); - - if (node.jjtGetNumChildren() == 0 - && firstToken.kind == JSPELParserConstants.DOT) - { - final Token dotId = node.getLastToken(); - - final int offset = - _context.getDocumentPosition() + dotId.beginColumn - 1; - final int length = dotId.endColumn - dotId.beginColumn + 1; - - final DotOperator dotOp = new DotOperator(_diagnosticFactory, _targetFile, _symbolResolver); - - final StringLiteralType suffixLiteral = new StringLiteralType(dotId.image); - final Diagnostic diagnostic = - dotOp.validate(symbolType, - suffixLiteral); - - if (diagnostic.getSeverity() != Diagnostic.OK) - { - _reporter.report(diagnostic, offset, length); - ((EvaluationTracker) data).setType(null); - } - else - { - // // if the base (value-a) is a map, then using the bracket value-a['y'] type - // // syntax is recommended. Note that we do this here instead of - // // DotOperator so that we don't tie the default property resolver - // // behaviour to that operator class. If someone changes the rules - // // of how the prop resolver interprets the base, then they may want to - // // write their own validator that doesn't do this - // if (symbolType.getSymbol().supportsCoercion(TypeConstants.TYPE_MAP)) - // { - // _messages.add(ValidationMessageFactory.createFromDiagnostic( - // DiagnosticFactory.create_BINARY_OP_DOT_WITH_VALUEA_MAP_SHOULD_USE_ARRAY - // (symbolType.getSymbol().getName(), dotId.image), - // startOffset, length, _targetFile)); - // } - - ((EvaluationTracker) data).setType(dotOp.performOperation(symbolType, - suffixLiteral)); - tracker.setCurMemberSymbol(offset, length); - } - - // we finished with the single dot suffix here - return data; - } - else if (firstToken.kind == JSPELParserConstants.LBRACKET) - { - final EvaluationTracker subExprTracker = new EvaluationTracker(); - node.childrenAccept(this, subExprTracker); - - final SignatureBasedType subExprType = subExprTracker.getType(); - - if (subExprType instanceof ValueType) - { - final Token lastToken = node.getLastToken(); - final int offset = - _context.getDocumentPosition() + firstToken.beginColumn - 1; - final int length = lastToken.endColumn - firstToken.beginColumn + 1; - - final BracketOperator bracketOperator = new BracketOperator(_diagnosticFactory, _targetFile, _symbolResolver); - - final Diagnostic diagnostic = - bracketOperator.validate(symbolType, - (ValueType)subExprType); - - if (diagnostic.getSeverity() != Diagnostic.OK) - { - _reporter.report(diagnostic, offset, length); - ((EvaluationTracker) data).setType(null); - } - else - { - ((EvaluationTracker) data).setType(bracketOperator.performOperation(symbolType, - (ValueType)subExprType)); - tracker.setCurMemberSymbol(offset, length); - } - } - // we are finished with the bracketed suffix at this point. - return data; - } - } - - // don't bother to accept children, since if we haven't done - // something above, there's not much sensible we can do with it - // clear the type first though - ((EvaluationTracker) data).setType(null); - return data; //node.childrenAccept(this, data); - } - - public Object visit(final SimpleNode node, final Object data) { - return node.childrenAccept(this, data); - } - - /** - * Copies stored messages into the validation reporter - * @param validator - * @param reporter - */ -// public void reportFindings(final IValidator validator, final IReporter reporter) -// { -// for (final IMessage message : _messages) -// { -// // don't report messages that have no severity. -// if ((message.getSeverity() & IMessage.ALL_MESSAGES) != 0) -// { -// reporter.addMessage(validator, message); -// } -// } -// } - - private void performBinaryEvaluation(final ASTOperatorExpression node, final EvaluationTracker tracker) - { - if (node.jjtGetNumChildren() < 2) - { - throw new AssertionError("Binary operators should always have at least two sub-expressions"); //$NON-NLS-1$ - } - else if (node.getOperatorTokens().size() != node.jjtGetNumChildren()-1) - { - throw new AssertionError("Binary operators should always have one operator token less than number of sub-expressions"); //$NON-NLS-1$ - } - - // evaluate left-most argument - node.jjtGetChild(0).jjtAccept(this, tracker); - - ValueType curType = getValueTypeForBinaryOperation(tracker.getType(), (SimpleNode) node.jjtGetChild(0)); - - for (int child = 1; child < node.jjtGetNumChildren(); child++) - { - // evaluate next argument running left-to-right - node.jjtGetChild(child).jjtAccept(this, tracker); - final ValueType secondType = - getValueTypeForBinaryOperation(tracker.getType(), (SimpleNode) node.jjtGetChild(child)); - - if (curType != null && secondType != null) - { - final BinaryOperator operator = - BinaryOperator.getBinaryOperator((Token)node.getOperatorTokens().get(child-1), _diagnosticFactory, _context); - - final Diagnostic diagnostic = operator.validate(curType, secondType); - - if (diagnostic.getSeverity() != Diagnostic.OK) - { - final Token firstToken = node.getFirstToken(); - final int offset = _context.getDocumentPosition() + firstToken.beginColumn - 1; - final int length = node.getLastToken().endColumn - firstToken.beginColumn+1; - _reporter.report(diagnostic, offset, length); - } - - curType = operator.performOperation(curType, secondType); - } - } - - tracker.setType(curType); - } - - private ValueType getValueTypeForBinaryOperation(final SignatureBasedType type, final SimpleNode node) - { - if (type instanceof ValueType) - { - return (ValueType) type; - } - else if (type instanceof MethodType) - { - final int offset = _context.getDocumentPosition() + node.getFirstToken().beginColumn - 1; - final int length = node.getLastToken().endColumn - node.getFirstToken().beginColumn+1; - final Diagnostic diagnostic = _diagnosticFactory.create_CANNOT_APPLY_OPERATOR_TO_METHOD_BINDING(); - _reporter.report(diagnostic, offset, length); - } - - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.jst.jsf.validation.internal.el.IExpressionSemanticValidator#getMessages() - */ -// public List getMessages() -// { -// if (!_validatorHasBeenCalled) -// { -// throw new AssertionError("Should not call getMessages before validate has been called"); -// } -// return _messages; -// } - - /* (non-Javadoc) - * @see org.eclipse.jst.jsf.validation.internal.el.IExpressionSemanticValidator#getExpressionType() - */ - public SignatureBasedType getExpressionType() - { - return _tracker.getType(); - } - - /** - * @param args - * @throws IOException - * @throws ParseException - */ - public static void main(final String[] args) throws IOException, ParseException - { - String elText = ""; //$NON-NLS-1$ - int nextCharacter; - - while(((nextCharacter = System.in.read()) != -1)) - { - final char nextChar = (char) nextCharacter; - - if (nextChar == '\n') - { - final JSPELParser parser = JSPELParser.createParser(elText); - final ASTExpression expr = parser.Expression(); - expr.dump(""); //$NON-NLS-1$ - - elText = ""; //$NON-NLS-1$ - } - else - { - elText += nextChar; - } - } - } -} |