| /* |
| * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser. |
| * Copyright (C) 2011, 2013-2016 The JavaParser Team. |
| * |
| * This file is part of JavaParser. |
| * |
| * JavaParser can be used either under the terms of |
| * a) the GNU Lesser General Public License as published by |
| * the Free Software Foundation, either version 3 of the License, or |
| * (at your option) any later version. |
| * b) the terms of the Apache License |
| * |
| * You should have received a copy of both licenses in LICENCE.LGPL and |
| * LICENCE.APACHE. Please refer to those files for details. |
| * |
| * JavaParser is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU Lesser General Public License for more details. |
| */ |
| |
| package com.github.javaparser.utils; |
| |
| import static java.lang.Integer.signum; |
| |
| import java.util.Collections; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import com.github.javaparser.ast.Node; |
| import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; |
| import com.github.javaparser.ast.body.FieldDeclaration; |
| import com.github.javaparser.ast.body.MethodDeclaration; |
| import com.github.javaparser.ast.expr.AnnotationExpr; |
| import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations; |
| import com.github.javaparser.ast.nodeTypes.NodeWithElementType; |
| import com.github.javaparser.ast.nodeTypes.NodeWithType; |
| |
| public final class PositionUtils { |
| |
| private PositionUtils() { |
| // prevent instantiation |
| } |
| |
| public static <T extends Node> void sortByBeginPosition(List<T> nodes){ |
| sortByBeginPosition(nodes, false); |
| } |
| |
| public static <T extends Node> void sortByBeginPosition(List<T> nodes, final boolean ignoringAnnotations){ |
| Collections.sort(nodes, (o1, o2) -> PositionUtils.compare(o1, o2, ignoringAnnotations)); |
| } |
| |
| public static boolean areInOrder(Node a, Node b){ |
| return areInOrder(a, b, false); |
| } |
| |
| public static boolean areInOrder(Node a, Node b, boolean ignoringAnnotations){ |
| return compare(a, b, ignoringAnnotations) <= 0; |
| } |
| |
| private static int compare(Node a, Node b, boolean ignoringAnnotations) { |
| if (ignoringAnnotations) { |
| int signLine = signum(beginLineWithoutConsideringAnnotation(a) - beginLineWithoutConsideringAnnotation(b)); |
| if (signLine == 0) { |
| return signum(beginColumnWithoutConsideringAnnotation(a) - beginColumnWithoutConsideringAnnotation(b)); |
| } else { |
| return signLine; |
| } |
| } |
| |
| int signLine = signum( a.getBegin().line - b.getBegin().line ); |
| if (signLine == 0) { |
| return signum(a.getBegin().column - b.getBegin().column); |
| } else { |
| return signLine; |
| } |
| } |
| |
| public static AnnotationExpr getLastAnnotation(Node node) { |
| if (node instanceof NodeWithAnnotations){ |
| List<AnnotationExpr> annotations = new LinkedList<>(); |
| annotations.addAll(((NodeWithAnnotations<?>) node).getAnnotations()); |
| if (annotations.isEmpty()){ |
| return null; |
| } |
| sortByBeginPosition(annotations); |
| return annotations.get(annotations.size()-1); |
| } else { |
| return null; |
| } |
| } |
| |
| private static int beginLineWithoutConsideringAnnotation(Node node) { |
| return beginNodeWithoutConsideringAnnotations(node).getBegin().line; |
| } |
| |
| |
| private static int beginColumnWithoutConsideringAnnotation(Node node) { |
| return beginNodeWithoutConsideringAnnotations(node).getBegin().column; |
| } |
| |
| private static Node beginNodeWithoutConsideringAnnotations(Node node) { |
| if (node instanceof MethodDeclaration || node instanceof FieldDeclaration) { |
| NodeWithElementType<?> casted = (NodeWithElementType<?>) node; |
| return casted.getElementType(); |
| } else if (node instanceof ClassOrInterfaceDeclaration) { |
| ClassOrInterfaceDeclaration casted = (ClassOrInterfaceDeclaration) node; |
| return casted.getNameExpr(); |
| } else { |
| return node; |
| } |
| } |
| |
| public static boolean nodeContains(Node container, Node contained, boolean ignoringAnnotations){ |
| if (!ignoringAnnotations || PositionUtils.getLastAnnotation(container)==null){ |
| return container.contains(contained); |
| } |
| if (!container.contains(contained)){ |
| return false; |
| } |
| // if the node is contained, but it comes immediately after the annotations, |
| // let's not consider it contained |
| if (container instanceof NodeWithAnnotations){ |
| int bl = beginLineWithoutConsideringAnnotation(container); |
| int bc = beginColumnWithoutConsideringAnnotation(container); |
| if (bl>contained.getBegin().line) return false; |
| if (bl==contained.getBegin().line && bc>contained.getBegin().column) return false; |
| if (container.getEnd().line<contained.getEnd().line) return false; |
| // TODO < or <= ? |
| return !(container.getEnd().line == contained.getEnd().line && container.getEnd().column < contained.getEnd().column); |
| } |
| return true; |
| } |
| |
| } |