/* * 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 void sortByBeginPosition(List nodes){ sortByBeginPosition(nodes, false); } public static void sortByBeginPosition(List 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 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