Package lombok.ast.grammar

Source Code of lombok.ast.grammar.ExpressionsActions

/*
* Copyright (C) 2010 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package lombok.ast.grammar;

import java.util.List;

import lombok.ast.ArrayAccess;
import lombok.ast.ArrayCreation;
import lombok.ast.ArrayDimension;
import lombok.ast.ArrayInitializer;
import lombok.ast.BinaryExpression;
import lombok.ast.Cast;
import lombok.ast.ClassLiteral;
import lombok.ast.ConstructorInvocation;
import lombok.ast.DanglingNodes;
import lombok.ast.Expression;
import lombok.ast.Identifier;
import lombok.ast.InlineIfExpression;
import lombok.ast.InstanceOf;
import lombok.ast.MethodInvocation;
import lombok.ast.Node;
import lombok.ast.Position;
import lombok.ast.Select;
import lombok.ast.Super;
import lombok.ast.This;
import lombok.ast.TypeReference;
import lombok.ast.TypeReferencePart;
import lombok.ast.UnaryExpression;
import lombok.ast.UnaryOperator;
import lombok.ast.VariableReference;

public class ExpressionsActions extends SourceActions {
  public ExpressionsActions(Source source) {
    super(source);
  }
 
  public Node createLeftAssociativeBinaryExpression(
      org.parboiled.Node<Node> head,
      List<org.parboiled.Node<Node>> operatorsNodes,
      List<String> operators,
      List<org.parboiled.Node<Node>> tail) {
   
    Node currentLeft = head.getValue();
   
    for (int i = 0; i < operators.size(); i++) {
      currentLeft = new BinaryExpression()
          .rawLeft(currentLeft)
          .rawRight(tail.get(i).getValue()).rawOperator(operators.get(i));
      source.registerStructure(currentLeft, operatorsNodes.get(i));
      positionSpan(currentLeft, head, tail.get(i));
    }
   
    return currentLeft;
  }
 
  public Node createAssignmentExpression(Node lhs, String operator, Node rhs) {
    if (rhs == null && operator == null) return lhs;
    return posify(new BinaryExpression().rawLeft(lhs).rawRight(rhs).rawOperator(operator));
  }
 
  public Node createInlineIfExpression(
      Node head, org.parboiled.Node<Node> operator1Node,
      org.parboiled.Node<Node> operator2Node, Node tail1, Node tail2) {
   
    if (tail1 == null || tail2 == null) return head;
   
    InlineIfExpression result = new InlineIfExpression()
        .rawCondition(head).rawIfTrue(tail1).rawIfFalse(tail2);
    source.registerStructure(result, operator1Node);
    source.registerStructure(result, operator2Node);
    return posify(result);
  }
 
  public Node createUnaryPrefixExpression(Node operand, org.parboiled.Node<Node> opNode, String symbol) {
    if (opNode == null) return operand;
   
    if (!opNode.getChildren().isEmpty() && "cast".equals(opNode.getChildren().get(0).getLabel())) {
      return posify(new Cast().rawOperand(operand).rawTypeReference(opNode.getValue()));
    } else {
      if (symbol != null) symbol = symbol.trim();
      if (!symbol.isEmpty()) {
        UnaryOperator op = UnaryOperator.fromSymbol(symbol, false);
        UnaryExpression expr = new UnaryExpression().rawOperand(operand);
        if (op != null) expr.astOperator(op);
        return posify(expr);
      }
    }
   
    return operand;
  }
 
  public Node createUnaryPrefixExpressions(
      org.parboiled.Node<Node> operand,
      List<org.parboiled.Node<Node>> operators,
      List<String> operatorTexts) {
   
    if (operators == null || operators.isEmpty()) return operand.getValue();
   
    Node current = operand.getValue();
    for (int i = operators.size() - 1; i >= 0; i--) {
      org.parboiled.Node<Node> operator = operators.get(i);
      Node prev = current;
      if (operator == null) continue;
      if (!operator.getChildren().isEmpty() && "cast".equals(operator.getChildren().get(0).getLabel())) {
        current = new Cast().rawOperand(current).rawTypeReference(operator.getValue());
      } else {
        String symbol = operatorTexts.get(i);
        if (symbol == null) continue;
        symbol = symbol.trim();
        if (symbol.isEmpty()) continue;
       
        UnaryOperator op = UnaryOperator.fromSymbol(symbol, false);
        UnaryExpression expr = new UnaryExpression().rawOperand(current);
        if (op != null) expr.astOperator(op);
        current = expr;
      }
     
      if (prev != null && !prev.getPosition().isUnplaced() && prev != current && current != null) {
        positionSpan(current, operator, operand);
      }
    }
   
    return current;
  }
 
  public Node createUnaryPostfixExpression(Node operand, List<org.parboiled.Node<Node>> nodes, List<String> operators) {
    if (operators == null) return operand;
   
    Node current = operand;
    for (int i = 0; i < operators.size(); i++) {
      String op = operators.get(i);
      if (op == null) continue;
      op = op.trim();
      Node prev = current;
      if (op.equals("++")) current = new UnaryExpression().rawOperand(current).astOperator(UnaryOperator.POSTFIX_INCREMENT);
      else if (op.equals("--")) current = new UnaryExpression().rawOperand(current).astOperator(UnaryOperator.POSTFIX_DECREMENT);
      org.parboiled.Node<Node> p = nodes.get(i);
      if (prev != null && !prev.getPosition().isUnplaced() && p != null) {
        current.setPosition(new Position(prev.getPosition().getStart(), p.getEndIndex()));
      }
    }
    return current;
  }
 
  public Node createInstanceOfExpression(Node operand, Node type) {
    if (type == null) return operand;
    return posify(new InstanceOf().rawObjectReference(operand).rawTypeReference(type));
  }
 
  public Node createQualifiedConstructorInvocation(
      Node constructorTypeArgs,
      org.parboiled.Node<Node> identifier, org.parboiled.Node<Node> classTypeArgs,
      Node methodArguments, Node classBody) {
   
    TypeReferencePart classTypeArgs0;
    boolean classTypeArgsCorrect = false;
    Node identifierNode = identifier == null ? null : identifier.getValue();
    if (classTypeArgs != null && classTypeArgs.getValue() instanceof TypeReferencePart) {
      classTypeArgs0 = (TypeReferencePart)classTypeArgs.getValue();
      classTypeArgsCorrect = true;
    } else {
      classTypeArgs0 = new TypeReferencePart();
      if (identifierNode != null) {
        classTypeArgs0.setPosition(identifierNode.getPosition());
      }
    }
   
    TypeReference typeReference = new TypeReference().astParts().addToEnd(
        classTypeArgs0.astIdentifier(createIdentifierIfNeeded(identifierNode, currentPos())));
    if (!classTypeArgsCorrect) {
      if (identifier != null && identifier.getValue() != null) {
        typeReference.setPosition(identifier.getValue().getPosition());
      }
    } else {
      positionSpan(typeReference, identifier, classTypeArgs);
    }
   
    ConstructorInvocation constructorInvocation = new ConstructorInvocation()
        .rawTypeReference(typeReference)
        .rawAnonymousClassBody(classBody);
   
    if (constructorTypeArgs instanceof TemporaryNode.TypeArguments) {
      for (Node arg : ((TemporaryNode.TypeArguments)constructorTypeArgs).arguments) {
        constructorInvocation.rawConstructorTypeArguments().addToEnd(arg);
      }
    }
   
    if (methodArguments instanceof TemporaryNode.MethodArguments) {
      for (Node arg : ((TemporaryNode.MethodArguments)methodArguments).arguments) {
        constructorInvocation.rawArguments().addToEnd(arg);
      }
    }
   
    return posify(constructorInvocation);
  }
 
  public Node createChainOfQualifiedConstructorInvocations(
      org.parboiled.Node<Node> qualifier,
      List<org.parboiled.Node<Node>> constructorInvocations) {
    Node current = qualifier.getValue();
   
    if (constructorInvocations == null) return current;
   
    for (org.parboiled.Node<Node> pNode : constructorInvocations) {
      Node n = pNode.getValue();
      if (n instanceof ConstructorInvocation) {
        current = ((ConstructorInvocation)n).rawQualifier(current);
        positionSpan(current, qualifier, pNode);
      } else DanglingNodes.addDanglingNode(current, n);
    }
   
    return current;
  }
 
  public Node createMethodInvocationOperation(org.parboiled.Node<Node> dot, Node typeArguments, Node name, Node arguments) {
    MethodInvocation mi = new MethodInvocation().astName(createIdentifierIfNeeded(name, currentPos()));
   
    if (typeArguments instanceof TemporaryNode.TypeArguments) {
      for (Node arg : ((TemporaryNode.TypeArguments)typeArguments).arguments) {
        mi.rawMethodTypeArguments().addToEnd(arg);
      }
    } else DanglingNodes.addDanglingNode(mi, typeArguments);
   
    if (arguments instanceof TemporaryNode.MethodArguments) {
      for (Node arg : ((TemporaryNode.MethodArguments)arguments).arguments) {
        mi.rawArguments().addToEnd(arg);
      }
    } else DanglingNodes.addDanglingNode(mi, arguments);
   
    source.registerStructure(mi, dot);
   
    return posify(mi);
  }
 
  public Node createSelectOperation(Node identifier) {
    return posify(new Select().astIdentifier(createIdentifierIfNeeded(identifier, currentPos())));
  }
 
  public Node createArrayAccessOperation(Node indexExpression) {
    return posify(new ArrayAccess().rawIndexExpression(indexExpression));
  }
 
  public Node createLevel1Expression(org.parboiled.Node<Node> operand, List<org.parboiled.Node<Node>> operations) {
    Node current = operand.getValue();
    if (operations == null) return current;
   
    for (org.parboiled.Node<Node> pNode : operations) {
      Node o = pNode.getValue();
     
      if (o instanceof ArrayAccess) {
        current = ((ArrayAccess)o).rawOperand(current);
      } else if (o instanceof MethodInvocation) {
        current = ((MethodInvocation)o).rawOperand(current);
      } else if (o instanceof Select) {
        current = ((Select)o).rawOperand(current);
      } else {
        DanglingNodes.addDanglingNode(current, o);
      }
     
      positionSpan(o, operand, pNode);
    }
    return current;
  }
 
  public Node createPrimary(Node identifier, Node methodArguments) {
    Identifier id = createIdentifierIfNeeded(identifier, currentPos());
   
    if (methodArguments instanceof TemporaryNode.MethodArguments) {
      MethodInvocation invoke = new MethodInvocation().astName(id);
      for (Node arg : ((TemporaryNode.MethodArguments)methodArguments).arguments) {
        invoke.rawArguments().addToEnd(arg);
      }
      return posify(invoke);
    } else {
      VariableReference ref = new VariableReference().astIdentifier(id);
      DanglingNodes.addDanglingNode(ref, methodArguments);
      return posify(ref);
    }
  }
 
  public Node createUnqualifiedConstructorInvocation(Node constructorTypeArgs, Node type, Node args, Node anonymousClassBody) {
    ConstructorInvocation result = new ConstructorInvocation()
        .rawTypeReference(type)
        .rawAnonymousClassBody(anonymousClassBody);
   
    if (constructorTypeArgs instanceof TemporaryNode.TypeArguments) {
      for (Node arg : ((TemporaryNode.TypeArguments)constructorTypeArgs).arguments) {
        result.rawConstructorTypeArguments().addToEnd(arg);
      }
    }
   
    if (args instanceof TemporaryNode.MethodArguments) {
      for (Node arg : ((TemporaryNode.MethodArguments)args).arguments) {
        result.rawArguments().addToEnd(arg);
      }
    } else DanglingNodes.addDanglingNode(result, args);
   
    return posify(result);
  }
 
  public Node createArrayInitializerExpression(Node head, List<Node> tail) {
    ArrayInitializer ai = new ArrayInitializer();
    if (head != null) ai.rawExpressions().addToEnd(head);
    if (tail != null) for (Node n : tail) if (n != null) ai.rawExpressions().addToEnd(n);
    return posify(ai);
  }
 
  public Node createDimension(Node dimExpr, org.parboiled.Node<Node> arrayOpen) {
    ArrayDimension d = new ArrayDimension().rawDimension(dimExpr);
    if (arrayOpen != null) d.setPosition(new Position(arrayOpen.getStartIndex(), currentPos()));
    return d;
  }
 
  public Node createArrayCreationExpression(Node type, List<Node> dimensions, Node initializer) {
    ArrayCreation ac = new ArrayCreation().rawComponentTypeReference(type).rawInitializer(initializer);
    if (dimensions != null) for (Node d : dimensions) {
      if (d != null) ac.rawDimensions().addToEnd(d);
    }
   
    return posify(ac);
  }
 
  public Node addParens(Node v) {
    if (v instanceof Expression) {
      ((Expression)v).astParensPositions().add(new Position(startPos(), currentPos()));
    }
    return v;
  }
 
  public Node createThisOrSuperOrClass(org.parboiled.Node<Node> dot, String text, Node qualifier) {
    Node result;
    if ("super".equals(text)) result = new Super().rawQualifier(qualifier);
    else if ("class".equals(text)) result = new ClassLiteral().rawTypeReference(qualifier);
    else result = new This().rawQualifier(qualifier);
    if (dot != null) source.registerStructure(result, dot);
    return posify(result);
  }
 
  public boolean checkIfLevel1ExprIsValidForAssignment(Node node) {
    return node instanceof VariableReference || node instanceof Select || node instanceof ArrayAccess;
  }
 
  public boolean checkIfMethodOrConstructorInvocation(Node node) {
    return node instanceof MethodInvocation || node instanceof ConstructorInvocation;
  }
 
  public boolean typeIsAlsoLegalAsExpression(Node type) {
    if (!(type instanceof TypeReference)) return true;
    TypeReference tr = (TypeReference)type;
    if (tr.astArrayDimensions() > 0) return false;
    if (tr.isPrimitive() || tr.isVoid()) return false;
    for (Node part : tr.rawParts()) {
      if (part instanceof TypeReferencePart) {
        if (!((TypeReferencePart)part).rawTypeArguments().isEmpty()) return false;
      }
    }
   
    return true;
  }
}
TOP

Related Classes of lombok.ast.grammar.ExpressionsActions

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.