/** * Wrap the given expression with a logging method call. Some kinds of expressions don't like * being wrapped in a simple fashion and so we have to handle them specially. The * ExpressionTransformer doesn't have methods for each type so we check for each one here. * * <p>TODO: There are potentially other expressions which need special handling (like indexing and * variables). This code may be working because those types have their parent being wrapped and we * don't transform their children. * * @param lineNumber line number to report for this value * @param expression the expression whose value we want to report * @return an expression that computes the value and also reports it somewheres */ private Expression loggingExpression(Integer lineNumber, Expression expression) { if (expression instanceof DeclarationExpression) { DeclarationExpression declarationExpression = (DeclarationExpression) expression; return new DeclarationExpression( declarationExpression.getLeftExpression(), declarationExpression.getOperation(), loggingExpression(lineNumber, declarationExpression.getRightExpression())); } if (expression instanceof BooleanExpression) { BooleanExpression booleanExpression = (BooleanExpression) expression; return new BooleanExpression( new MethodCallExpression( new VariableExpression("this"), "_log", new ArgumentListExpression( new ConstantExpression(lineNumber), booleanExpression.getExpression()))); } return new MethodCallExpression( new VariableExpression("this"), "_log", new ArgumentListExpression(new ConstantExpression(lineNumber), expression)); }
private void changeBaseScriptTypeFromDeclaration( final DeclarationExpression de, final AnnotationNode node) { if (de.isMultipleAssignmentDeclaration()) { addError( "Annotation " + MY_TYPE_NAME + " not supported with multiple assignment notation.", de); return; } if (!(de.getRightExpression() instanceof EmptyExpression)) { addError("Annotation " + MY_TYPE_NAME + " not supported with variable assignment.", de); return; } Expression value = node.getMember("value"); if (value != null) { addError( "Annotation " + MY_TYPE_NAME + " cannot have member 'value' if used on a declaration.", value); return; } ClassNode cNode = de.getDeclaringClass(); ClassNode baseScriptType = de.getVariableExpression().getType().getPlainNodeReference(); de.setRightExpression(new VariableExpression("this")); changeBaseScriptType(de, cNode, baseScriptType); }
public void visitDeclarationExpression(DeclarationExpression expression) { // visit right side first to avoid the usage of a // variable before its declaration expression.getRightExpression().visit(this); if (expression.isMultipleAssignmentDeclaration()) { TupleExpression list = expression.getTupleExpression(); for (Expression e : list.getExpressions()) { declare((VariableExpression) e); } } else { declare(expression.getVariableExpression()); } }
private DeclarationExpression optimizeConstantInitialization( final BinaryExpression originalDeclaration, final Token operation, final ConstantExpression constant, final Expression leftExpression, final ClassNode declarationType) { ConstantExpression cexp = new ConstantExpression( convertConstant((Number) constant.getValue(), ClassHelper.getWrapper(declarationType)), true); cexp.setType(declarationType); cexp.setSourcePosition(constant); DeclarationExpression result = new DeclarationExpression(leftExpression, operation, cexp); result.setSourcePosition(originalDeclaration); result.copyNodeMetaData(originalDeclaration); return result; }
protected void addError(String msg, ASTNode expr) { int line = expr.getLineNumber(); int col = expr.getColumnNumber(); // GRECLIPSE int start = expr.getStart(); int end = expr.getEnd() - 1; if (expr instanceof ClassNode) { // assume we have a class declaration ClassNode cn = (ClassNode) expr; if (cn.getNameEnd() > 0) { start = cn.getNameStart(); end = cn.getNameEnd(); } else if (cn.getComponentType() != null) { // avoid extra whitespace after closing ] end--; } } else if (expr instanceof DeclarationExpression) { // assume that we just want to underline the variable declaration DeclarationExpression decl = (DeclarationExpression) expr; Expression lhs = decl.getLeftExpression(); start = lhs.getStart(); // avoid extra space before = if a variable end = lhs instanceof VariableExpression ? start + lhs.getText().length() - 1 : lhs.getEnd() - 1; } // end SourceUnit source = getSourceUnit(); source .getErrorCollector() .addErrorAndContinue( // GRECLIPSE: start new SyntaxErrorMessage( new PreciseSyntaxException(msg + '\n', line, col, start, end), source) // end ); }
private void setScriptURIOnDeclaration( final DeclarationExpression de, final AnnotationNode node) { if (de.isMultipleAssignmentDeclaration()) { addError( "Annotation " + MY_TYPE_NAME + " not supported with multiple assignment notation.", de); return; } if (!(de.getRightExpression() instanceof EmptyExpression)) { addError("Annotation " + MY_TYPE_NAME + " not supported with variable assignment.", de); return; } URI uri = getSourceURI(node); if (uri == null) { addError("Unable to get the URI for the source of this script!", de); } else { // Set the RHS to '= URI.create("string for this URI")'. // That may throw an IllegalArgumentExpression wrapping the URISyntaxException. de.setRightExpression(getExpression(uri)); } }
@Test public void transformationOfAnnotationOnLocalVariable() { ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); this.moduleNode.addClass(classNode); DeclarationExpression declarationExpression = new DeclarationExpression( new VariableExpression("test"), null, new ConstantExpression("test")); declarationExpression.addAnnotation(this.grabAnnotation); BlockStatement code = new BlockStatement( Arrays.asList((Statement) new ExpressionStatement(declarationExpression)), new VariableScope()); MethodNode methodNode = new MethodNode( "test", 0, new ClassNode(Void.class), new Parameter[0], new ClassNode[0], code); classNode.addMethod(methodNode); assertGrabAnnotationHasBeenTransformed(); }
@Override public void visitDeclarationExpression(DeclarationExpression expression) { super.visitDeclarationExpression(expression); if (expression.isMultipleAssignmentDeclaration()) return; checkInvalidDeclarationModifier(expression, ACC_ABSTRACT, "abstract"); checkInvalidDeclarationModifier(expression, ACC_NATIVE, "native"); checkInvalidDeclarationModifier(expression, ACC_PRIVATE, "private"); checkInvalidDeclarationModifier(expression, ACC_PROTECTED, "protected"); checkInvalidDeclarationModifier(expression, ACC_PUBLIC, "public"); checkInvalidDeclarationModifier(expression, ACC_STATIC, "static"); checkInvalidDeclarationModifier(expression, ACC_STRICT, "strictfp"); checkInvalidDeclarationModifier(expression, ACC_SYNCHRONIZED, "synchronized"); checkInvalidDeclarationModifier(expression, ACC_TRANSIENT, "transient"); checkInvalidDeclarationModifier(expression, ACC_VOLATILE, "volatile"); }
@Override public void visitDeclarationExpression(DeclarationExpression expression) { // LOG.debug "Transforming expression '${expression}':" if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) { // LOG.debug " start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber // - 1]}" expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]); } if (expression.getLastLineNumber() > 0 && expression.getLastLineNumber() < lineNumbers.length) { // LOG.debug " end from ${expression.lastLineNumber} to // ${lineNumbers[expression.lastLineNumber - 1]}" expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]); } super.visitDeclarationExpression(expression); }
/** * Don't treat the LHS of a declaration as something we can wrap, just the RHS. * * @param expression */ @Override public void visitDeclarationExpression(DeclarationExpression expression) { expression.getRightExpression().visit(this); }
private void checkInvalidDeclarationModifier( DeclarationExpression expression, int modifier, String modName) { if ((expression.getVariableExpression().getModifiers() & modifier) != 0) { addError("Modifier '" + modName + "' not allowed here.", expression); } }