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);
  }
  /**
   * 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));
  }
  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 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));
    }
  }
 /**
  * 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);
 }