1 /* 2 * Copyright (C) 2007-2010 Júlio Vilmar Gesser. 3 * Copyright (C) 2011, 2013-2016 The JavaParser Team. 4 * 5 * This file is part of JavaParser. 6 * 7 * JavaParser can be used either under the terms of 8 * a) the GNU Lesser General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * b) the terms of the Apache License 12 * 13 * You should have received a copy of both licenses in LICENCE.LGPL and 14 * LICENCE.APACHE. Please refer to those files for details. 15 * 16 * JavaParser is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Lesser General Public License for more details. 20 */ 21 22 package com.github.javaparser; 23 24 import com.github.javaparser.ast.CompilationUnit; 25 import com.github.javaparser.ast.body.AnnotationMemberDeclaration; 26 import com.github.javaparser.ast.body.MethodDeclaration; 27 import com.github.javaparser.ast.expr.ArrayCreationExpr; 28 import com.github.javaparser.ast.expr.CastExpr; 29 import com.github.javaparser.ast.expr.Expression; 30 import com.github.javaparser.ast.expr.LambdaExpr; 31 import com.github.javaparser.ast.stmt.*; 32 import com.github.javaparser.ast.type.ClassOrInterfaceType; 33 import com.github.javaparser.ast.type.IntersectionType; 34 import com.github.javaparser.ast.type.Type; 35 import org.junit.Test; 36 37 import java.io.IOException; 38 import java.nio.file.Path; 39 import java.util.Optional; 40 41 import static com.github.javaparser.ParseStart.COMPILATION_UNIT; 42 import static com.github.javaparser.Providers.provider; 43 import static com.github.javaparser.Range.range; 44 import static com.github.javaparser.utils.CodeGenerationUtils.mavenModuleRoot; 45 import static com.github.javaparser.utils.TestUtils.assertInstanceOf; 46 import static com.github.javaparser.utils.Utils.EOL; 47 import static org.junit.Assert.assertEquals; 48 import static org.junit.Assert.assertTrue; 49 50 public class JavaParserTest { 51 52 @Test rangeOfAnnotationMemberDeclarationIsCorrect()53 public void rangeOfAnnotationMemberDeclarationIsCorrect() { 54 String code = "@interface AD { String foo(); }"; 55 CompilationUnit cu = JavaParser.parse(code); 56 AnnotationMemberDeclaration memberDeclaration = cu.getAnnotationDeclarationByName("AD").get().getMember(0).asAnnotationMemberDeclaration(); 57 assertEquals(true, memberDeclaration.getRange().isPresent()); 58 assertEquals(new Range(new Position(1, 17), new Position(1, 29)), memberDeclaration.getRange().get()); 59 } 60 61 @Test rangeOfAnnotationMemberDeclarationWithArrayTypeIsCorrect()62 public void rangeOfAnnotationMemberDeclarationWithArrayTypeIsCorrect() { 63 String code = "@interface AD { String[] foo(); }"; 64 CompilationUnit cu = JavaParser.parse(code); 65 AnnotationMemberDeclaration memberDeclaration = cu.getAnnotationDeclarationByName("AD").get().getMember(0).asAnnotationMemberDeclaration(); 66 assertEquals(true, memberDeclaration.getRange().isPresent()); 67 assertEquals(new Range(new Position(1, 17), new Position(1, 31)), memberDeclaration.getRange().get()); 68 } 69 70 @Test rangeOfArrayCreationLevelWithExpressionIsCorrect()71 public void rangeOfArrayCreationLevelWithExpressionIsCorrect() { 72 String code = "new int[123][456]"; 73 ArrayCreationExpr expression = JavaParser.parseExpression(code); 74 Optional<Range> range; 75 76 range = expression.getLevels().get(0).getRange(); 77 assertEquals(true, range.isPresent()); 78 assertEquals(new Range(new Position(1, 8), new Position(1, 12)), range.get()); 79 80 range = expression.getLevels().get(1).getRange(); 81 assertEquals(true, range.isPresent()); 82 assertEquals(new Range(new Position(1, 13), new Position(1, 17)), range.get()); 83 } 84 85 @Test rangeOfArrayCreationLevelWithoutExpressionIsCorrect()86 public void rangeOfArrayCreationLevelWithoutExpressionIsCorrect() { 87 String code = "new int[][]"; 88 ArrayCreationExpr expression = JavaParser.parseExpression(code); 89 Optional<Range> range; 90 91 range = expression.getLevels().get(0).getRange(); 92 assertEquals(true, range.isPresent()); 93 assertEquals(new Range(new Position(1, 8), new Position(1, 9)), range.get()); 94 95 range = expression.getLevels().get(1).getRange(); 96 assertEquals(true, range.isPresent()); 97 assertEquals(new Range(new Position(1, 10), new Position(1, 11)), range.get()); 98 } 99 100 @Test parseErrorContainsLocation()101 public void parseErrorContainsLocation() { 102 ParseResult<CompilationUnit> result = new JavaParser().parse(COMPILATION_UNIT, provider("class X { // blah")); 103 104 Problem problem = result.getProblem(0); 105 assertEquals(range(1, 9, 1, 17), problem.getLocation().get().toRange().get()); 106 assertEquals("Parse error. Found <EOF>, expected one of \";\" \"<\" \"@\" \"abstract\" \"boolean\" \"byte\" \"char\" \"class\" \"default\" \"double\" \"enum\" \"exports\" \"final\" \"float\" \"int\" \"interface\" \"long\" \"module\" \"native\" \"open\" \"opens\" \"private\" \"protected\" \"provides\" \"public\" \"requires\" \"short\" \"static\" \"strictfp\" \"synchronized\" \"to\" \"transient\" \"transitive\" \"uses\" \"void\" \"volatile\" \"with\" \"{\" \"}\" <IDENTIFIER>", problem.getMessage()); 107 assertInstanceOf(ParseException.class, problem.getCause().get()); 108 } 109 110 @Test parseIntersectionType()111 public void parseIntersectionType() { 112 String code = "(Runnable & Serializable) (() -> {})"; 113 Expression expression = JavaParser.parseExpression(code); 114 Type type = expression.asCastExpr().getType(); 115 116 assertTrue(type instanceof IntersectionType); 117 IntersectionType intersectionType = type.asIntersectionType(); 118 assertEquals(2, intersectionType.getElements().size()); 119 assertTrue(intersectionType.getElements().get(0) instanceof ClassOrInterfaceType); 120 assertEquals("Runnable", intersectionType.getElements().get(0).asClassOrInterfaceType().getNameAsString()); 121 assertTrue(intersectionType.getElements().get(1) instanceof ClassOrInterfaceType); 122 assertEquals("Serializable", intersectionType.getElements().get(1).asClassOrInterfaceType().getNameAsString()); 123 } 124 125 @Test rangeOfIntersectionType()126 public void rangeOfIntersectionType() { 127 String code = "class A {" + EOL 128 + " Object f() {" + EOL 129 + " return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL 130 + "}}"; 131 CompilationUnit cu = JavaParser.parse(code); 132 MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration(); 133 ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt(); 134 CastExpr castExpr = returnStmt.getExpression().get().asCastExpr(); 135 Type type = castExpr.getType(); 136 assertEquals(range(3, 13, 3, 54), type.getRange().get()); 137 } 138 139 @Test rangeOfCast()140 public void rangeOfCast() { 141 String code = "class A {" + EOL 142 + " Object f() {" + EOL 143 + " return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL 144 + "}}"; 145 CompilationUnit cu = JavaParser.parse(code); 146 MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration(); 147 ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt(); 148 CastExpr castExpr = returnStmt.getExpression().get().asCastExpr(); 149 assertEquals(range(3, 12, 3, 101), castExpr.getRange().get()); 150 } 151 152 @Test rangeOfCastNonIntersection()153 public void rangeOfCastNonIntersection() { 154 String code = "class A {" + EOL 155 + " Object f() {" + EOL 156 + " return (Comparator<Map.Entry<K, V>> )(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL 157 + "}}"; 158 CompilationUnit cu = JavaParser.parse(code); 159 MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration(); 160 ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt(); 161 CastExpr castExpr = returnStmt.getExpression().get().asCastExpr(); 162 assertEquals(range(3, 12, 3, 101), castExpr.getRange().get()); 163 } 164 165 @Test rangeOfLambda()166 public void rangeOfLambda() { 167 String code = "class A {" + EOL 168 + " Object f() {" + EOL 169 + " return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL 170 + "}}"; 171 CompilationUnit cu = JavaParser.parse(code); 172 MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration(); 173 ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt(); 174 CastExpr castExpr = returnStmt.getExpression().get().asCastExpr(); 175 LambdaExpr lambdaExpr = castExpr.getExpression().asLambdaExpr(); 176 assertEquals(range(3, 56, 3, 101), lambdaExpr.getRange().get()); 177 assertEquals(GeneratedJavaParserConstants.LPAREN, lambdaExpr.getTokenRange().get().getBegin().getKind()); 178 assertEquals(GeneratedJavaParserConstants.RPAREN, lambdaExpr.getTokenRange().get().getEnd().getKind()); 179 } 180 181 @Test rangeOfLambdaBody()182 public void rangeOfLambdaBody() { 183 String code = "class A {" + EOL 184 + " Object f() {" + EOL 185 + " return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL 186 + "}}"; 187 CompilationUnit cu = JavaParser.parse(code); 188 MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration(); 189 ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt(); 190 CastExpr castExpr = returnStmt.getExpression().get().asCastExpr(); 191 LambdaExpr lambdaExpr = castExpr.getExpression().asLambdaExpr(); 192 Statement lambdaBody = lambdaExpr.getBody(); 193 assertEquals(range(3, 68, 3, 101), lambdaBody.getRange().get()); 194 } 195 196 @Test testNotStoringTokens()197 public void testNotStoringTokens() { 198 JavaParser javaParser = new JavaParser(new ParserConfiguration().setStoreTokens(false)); 199 ParseResult<CompilationUnit> result = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{}")); 200 assertEquals(false, result.getTokens().isPresent()); 201 } 202 203 @Test(expected = ParseProblemException.class) trailingCodeIsAnError()204 public void trailingCodeIsAnError() { 205 JavaParser.parseBlock("{} efijqoifjqefj"); 206 } 207 208 @Test trailingWhitespaceIsIgnored()209 public void trailingWhitespaceIsIgnored() { 210 BlockStmt blockStmt = JavaParser.parseBlock("{} // hello"); 211 assertEquals("{}", blockStmt.getTokenRange().get().toString()); 212 } 213 214 @Test everyTokenHasACategory()215 public void everyTokenHasACategory() throws IOException { 216 final int tokenCount = GeneratedJavaParserConstants.tokenImage.length; 217 Path tokenTypesPath = mavenModuleRoot(JavaParserTest.class).resolve("../javaparser-core/src/main/java/com/github/javaparser/TokenTypes.java"); 218 CompilationUnit tokenTypesCu = JavaParser.parse(tokenTypesPath); 219 // -1 to take off the default: case. 220 int switchEntries = tokenTypesCu.findAll(SwitchEntryStmt.class).size()-1; 221 // The amount of "case XXX:" in TokenTypes.java should be equal to the amount of tokens JavaCC knows about: 222 assertEquals(tokenCount, switchEntries); 223 } 224 225 @Test parsingInitializedAndUnitializedVarsInForStmt()226 public void parsingInitializedAndUnitializedVarsInForStmt() { 227 ForStmt forStmt = JavaParser.parseStatement("for(int a,b=0;;){}").asForStmt(); 228 assertEquals(1, forStmt.getInitialization().size()); 229 assertEquals(true, forStmt.getInitialization().get(0).isVariableDeclarationExpr()); 230 assertEquals(2, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().size()); 231 assertEquals("a", forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(0).getNameAsString()); 232 assertEquals("b", forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(1).getNameAsString()); 233 assertEquals(false, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(0).getInitializer().isPresent()); 234 assertEquals(true, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(1).getInitializer().isPresent()); 235 } 236 237 @Test parsingInitializedAndUnitializedVarsInForStmtComplexCase()238 public void parsingInitializedAndUnitializedVarsInForStmtComplexCase() { 239 // See issue 1281 240 ForStmt forStmt = JavaParser.parseStatement("for(int i, j = array2.length - 1;;){}").asForStmt(); 241 assertEquals(1, forStmt.getInitialization().size()); 242 assertEquals(true, forStmt.getInitialization().get(0).isVariableDeclarationExpr()); 243 assertEquals(2, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().size()); 244 assertEquals("i", forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(0).getNameAsString()); 245 assertEquals("j", forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(1).getNameAsString()); 246 assertEquals(false, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(0).getInitializer().isPresent()); 247 assertEquals(true, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(1).getInitializer().isPresent()); 248 } 249 } 250