NameLogicTest.java
/*
* Copyright (C) 2015-2016 Federico Tomassetti
* Copyright (C) 2017-2024 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.symbolsolver.resolution.naming;
import static com.github.javaparser.symbolsolver.resolution.naming.NameRole.DECLARATION;
import static com.github.javaparser.symbolsolver.resolution.naming.NameRole.REFERENCE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.github.javaparser.ParseStart;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.expr.Name;
import com.github.javaparser.ast.modules.ModuleDeclaration;
import com.github.javaparser.ast.stmt.ReturnStmt;
import org.junit.jupiter.api.Test;
class NameLogicTest extends AbstractNameLogicTest {
private void assertNameInCodeIsSyntactically(
String code, String name, NameCategory nameCategory, ParseStart parseStart) {
Node nameNode = getNameInCode(code, name, parseStart);
assertEquals(nameCategory, NameLogic.syntacticClassificationAccordingToContext(nameNode));
}
@Test
void requiresModuleName() {
assertNameInCodeIsSyntactically(
"module com.mydeveloperplanet.jpmshello {\n" + " requires java.base;\n"
+ " requires java.xml;\n"
+ " requires com.mydeveloperplanet.jpmshi;\n"
+ "}\n",
"java.xml",
NameCategory.MODULE_NAME,
ParseStart.MODULE_DECLARATION);
}
@Test
void exportsModuleName() {
assertNameInCodeIsSyntactically(
"module my.module{\n" + " exports my.packag to other.module, another.module;\n" + "}",
"other.module",
NameCategory.MODULE_NAME,
ParseStart.MODULE_DECLARATION);
}
@Test
void opensModuleName() {
assertNameInCodeIsSyntactically(
"module client.modul{\n" + " opens some.client.packag to framework.modul;\n"
+ " requires framework.modul2;\n"
+ "}",
"framework.modul",
NameCategory.MODULE_NAME,
ParseStart.MODULE_DECLARATION);
}
@Test
void exportsPackageName() {
assertNameInCodeIsSyntactically(
"module common.widget{\n" + " exports com.logicbig;\n" + "}",
"com.logicbig",
NameCategory.PACKAGE_NAME,
ParseStart.MODULE_DECLARATION);
}
@Test
void opensPackageName() {
assertNameInCodeIsSyntactically(
"module foo {\n" + " opens com.example.bar;\n" + "}",
"com.example.bar",
NameCategory.PACKAGE_NAME,
ParseStart.MODULE_DECLARATION);
}
@Test
void packageNameInPackageName() {
assertNameInCodeIsSyntactically(
"module foo {\n" + " opens com.example.bar;\n" + "}",
"com.example",
NameCategory.PACKAGE_NAME,
ParseStart.MODULE_DECLARATION);
}
@Test
void usesTypeName() {
assertNameInCodeIsSyntactically(
"module modi.mod {\n" + " uses modi.api;\n" + "}",
"modi.api",
NameCategory.TYPE_NAME,
ParseStart.MODULE_DECLARATION);
}
@Test
void providesTypeName() {
assertNameInCodeIsSyntactically(
"module foo {\n" + " provides com.modi.api.query.Query with ModuleQuery;\n" + "}",
"com.modi.api.query.Query",
NameCategory.TYPE_NAME,
ParseStart.MODULE_DECLARATION);
}
@Test
void singleTypeImportTypeName() {
assertNameInCodeIsSyntactically("import a.b.c;", "a.b.c", NameCategory.TYPE_NAME, ParseStart.COMPILATION_UNIT);
}
@Test
void singleStaticTypeImportTypeName() {
assertNameInCodeIsSyntactically(
"import static a.B.c;", "a.B", NameCategory.TYPE_NAME, ParseStart.COMPILATION_UNIT);
}
@Test
void singleStaticImportOnDemandTypeName() {
assertNameInCodeIsSyntactically(
"import static a.B.*;", "a.B", NameCategory.TYPE_NAME, ParseStart.COMPILATION_UNIT);
}
@Test
void constructorDeclarationTypeName() {
assertNameInCodeIsSyntactically("A() { }", "A", NameCategory.TYPE_NAME, ParseStart.CLASS_BODY);
}
@Test
void annotationTypeName() {
assertNameInCodeIsSyntactically(
"@Anno class A {} ", "Anno", NameCategory.TYPE_NAME, ParseStart.COMPILATION_UNIT);
}
@Test
void classLiteralTypeName() {
assertNameInCodeIsSyntactically(
"Class<?> c = String.class;", "String", NameCategory.TYPE_NAME, ParseStart.STATEMENT);
}
@Test
void thisExprTypeName() {
assertNameInCodeIsSyntactically(
"Object o = String.this;", "String", NameCategory.TYPE_NAME, ParseStart.STATEMENT);
}
@Test
void qualifiedSuperFieldAccessTypeName() {
assertNameInCodeIsSyntactically(
"Object o = MyClass.super.myField;", "MyClass", NameCategory.TYPE_NAME, ParseStart.STATEMENT);
}
@Test
void qualifiedSuperCallTypeName() {
assertNameInCodeIsSyntactically(
"Object o = MyClass.super.myCall();", "MyClass", NameCategory.TYPE_NAME, ParseStart.STATEMENT);
}
@Test
void qualifiedSuperMethodReferenceTypeName() {
assertNameInCodeIsSyntactically(
"Object o = MyClass.super::myMethod;", "MyClass", NameCategory.TYPE_NAME, ParseStart.STATEMENT);
}
@Test
void extendsClauseTypeName() {
assertNameInCodeIsSyntactically(
"class Foo extends bar.MyClass { }",
"bar.MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void implementsClauseTypeName() {
assertNameInCodeIsSyntactically(
"class Foo implements bar.MyClass { }",
"bar.MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void returnTypeTypeName() {
assertNameInCodeIsSyntactically(
"class Foo { bar.MyClass myMethod() {} }",
"bar.MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void qualifiedAnnotationMemberTypeTypeName() {
assertNameInCodeIsSyntactically(
"@interface MyAnno { bar.MyClass myMember(); }",
"bar.MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void unqualifiedAnnotationMemberTypeTypeName() {
assertNameInCodeIsSyntactically(
"@interface MyAnno { MyClass myMember(); }",
"MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void throwClauseMethodTypeName() {
assertNameInCodeIsSyntactically(
"class Foo { void myMethod() throws bar.MyClass {} }",
"bar.MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void qualifiedThrowClauseConstructorTypeName() {
assertNameInCodeIsSyntactically(
"class Foo { Foo() throws bar.MyClass {} }",
"bar.MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void unualifiedThrowClauseConstructorTypeName() {
assertNameInCodeIsSyntactically(
"class Foo { Foo() throws MyClass {} }",
"MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void qualifiedFieldTypeTypeName() {
assertNameInCodeIsSyntactically(
"class Foo { bar.MyClass myField; }",
"bar.MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void fieldTypeTypeNameSecondAttempt() {
assertNameInCodeIsSyntactically(
"public class JavaParserInterfaceDeclaration extends AbstractTypeDeclaration implements InterfaceDeclaration {\n"
+ "private TypeSolver typeSolver; }",
"TypeSolver",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void unqualifiedFieldTypeTypeName() {
assertNameInCodeIsSyntactically(
"class Foo { MyClass myField; }", "MyClass", NameCategory.TYPE_NAME, ParseStart.COMPILATION_UNIT);
}
@Test
void qualifiedFormalParameterOfMethodTypeName() {
assertNameInCodeIsSyntactically(
"class Foo { void myMethod(bar.MyClass param) {} }",
"bar.MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void unqualifiedFormalParameterOfMethodTypeName() {
assertNameInCodeIsSyntactically(
"class Foo { void myMethod(MyClass param) {} }",
"MyClass",
NameCategory.TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void receiverParameterOfMethodTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod(Foo this) {}", "Foo", NameCategory.TYPE_NAME, ParseStart.CLASS_BODY);
}
@Test
void variableDeclarationTypeTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { Foo myVar; }", "Foo", NameCategory.TYPE_NAME, ParseStart.CLASS_BODY);
}
@Test
void exceptionParameterTypeTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { try { } catch(Foo e) { } }", "Foo", NameCategory.TYPE_NAME, ParseStart.CLASS_BODY);
}
@Test
void explicitParameterTypeInConstructorCallTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { new Call<Foo>(); }", "Foo", NameCategory.TYPE_NAME, ParseStart.CLASS_BODY);
}
@Test
void explicitParameterTypeInMethodCallTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { new Call().<Foo>myMethod(); }",
"Foo",
NameCategory.TYPE_NAME,
ParseStart.CLASS_BODY);
}
@Test
void instantiationCallTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { new Foo(); }", "Foo", NameCategory.TYPE_NAME, ParseStart.CLASS_BODY);
}
@Test
void instantiationCallOfAnonymousTypeTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { new Foo() { void method() { } } ; }",
"Foo",
NameCategory.TYPE_NAME,
ParseStart.CLASS_BODY);
}
@Test
void arrayCreationExpressionTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { new Foo[0]; }", "Foo", NameCategory.TYPE_NAME, ParseStart.CLASS_BODY);
}
@Test
void castTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { Object o = (Foo)someField; }", "Foo", NameCategory.TYPE_NAME, ParseStart.CLASS_BODY);
}
@Test
void instanceOfTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { if (myValue instanceof Foo) { }; }",
"Foo",
NameCategory.TYPE_NAME,
ParseStart.CLASS_BODY);
}
@Test
void instanceOfPatternTypeName() {
// Note: Requires JDK14
assertNameInCodeIsSyntactically(
"void myMethod() { if (myValue instanceof Foo f) { }; }",
"Foo",
NameCategory.TYPE_NAME,
ParseStart.CLASS_BODY);
}
@Test
void methodReferenceTypeName() {
assertNameInCodeIsSyntactically(
"void myMethod() { Object o = Foo::myMethod; }", "Foo", NameCategory.TYPE_NAME, ParseStart.CLASS_BODY);
}
@Test
void qualifiedConstructorSuperClassInvocationExpressionName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { anExpression.super(); } } ",
"anExpression",
NameCategory.EXPRESSION_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void qualifiedClassInstanceCreationExpressionName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { anExpression.new MyClass(); } } ",
"anExpression",
NameCategory.EXPRESSION_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void arrayReferenceExpressionName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { anExpression[0]; } } ",
"anExpression",
NameCategory.EXPRESSION_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void postfixExpressionName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { anExpression++; } } ",
"anExpression",
NameCategory.EXPRESSION_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void leftHandAssignmentExpressionName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { anExpression = 2; } } ",
"anExpression",
NameCategory.EXPRESSION_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void variableAccessInTryWithResourceExpressionName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { try (anExpression) { }; } } ",
"anExpression",
NameCategory.EXPRESSION_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void variableAccessInTryWithResourceWothTypeExpressionName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { try (Object o = anExpression) { }; } } ",
"anExpression",
NameCategory.EXPRESSION_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void methodInvocationMethodName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { myMethod(); } } ",
"myMethod",
NameCategory.METHOD_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void leftOfQualifiedTypeNamePackageOrTypeName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { new myQualified.path.to.TypeName(); } } ",
"myQualified.path.to",
NameCategory.PACKAGE_OR_TYPE_NAME,
ParseStart.COMPILATION_UNIT);
assertNameInCodeIsSyntactically(
"class Bar { Bar() { new myQualified.path.to.TypeName(); } } ",
"myQualified.path",
NameCategory.PACKAGE_OR_TYPE_NAME,
ParseStart.COMPILATION_UNIT);
assertNameInCodeIsSyntactically(
"class Bar { Bar() { new myQualified.path.to.TypeName(); } } ",
"myQualified",
NameCategory.PACKAGE_OR_TYPE_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void typeImportOnDemandPackageOrTypeName() {
assertNameInCodeIsSyntactically(
"import a.B.*;", "a.B", NameCategory.PACKAGE_OR_TYPE_NAME, ParseStart.COMPILATION_UNIT);
}
@Test
void leftOfExpressionNameAmbiguousName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { a.b.c.anExpression[0]; } } ",
"a.b.c",
NameCategory.AMBIGUOUS_NAME,
ParseStart.COMPILATION_UNIT);
assertNameInCodeIsSyntactically(
"class Bar { Bar() { a.b.c.anExpression[0]; } } ",
"a.b",
NameCategory.AMBIGUOUS_NAME,
ParseStart.COMPILATION_UNIT);
assertNameInCodeIsSyntactically(
"class Bar { Bar() { a.b.c.anExpression[0]; } } ",
"a",
NameCategory.AMBIGUOUS_NAME,
ParseStart.COMPILATION_UNIT);
}
@Test
void leftOfMethodCallAmbiguousName() {
assertNameInCodeIsSyntactically(
"class Bar { Bar() { a.b.c.aMethod(); } } ",
"a.b.c",
NameCategory.AMBIGUOUS_NAME,
ParseStart.COMPILATION_UNIT);
}
private void assertNameInCodeHasRole(String code, String name, NameRole nameRole, ParseStart parseStart) {
Node nameNode = getNameInCode(code, name, parseStart);
assertEquals(nameRole, NameLogic.classifyRole(nameNode));
}
private void assertIsSimpleName(String code, String name, ParseStart parseStart) {
Node nameNode = getNameInCode(code, name, parseStart);
assertTrue(NameLogic.isSimpleName(nameNode));
}
private void assertIsQualifiedName(String code, String name, ParseStart parseStart) {
Node nameNode = getNameInCode(code, name, parseStart);
assertTrue(NameLogic.isQualifiedName(nameNode));
}
@Test
void identifyNamesInSimpleExamples() {
String code = "package a.b.c; class A { void foo(int param) { return a.b.c.D.e; } }";
CompilationUnit cu = StaticJavaParser.parse(code);
assertEquals(false, NameLogic.isAName(cu));
assertEquals(false, NameLogic.isAName(cu.getPackageDeclaration().get()));
Name packageName = cu.getPackageDeclaration().get().getName();
assertEquals(true, NameLogic.isAName(packageName));
assertEquals(true, NameLogic.isAName(packageName.getQualifier().get()));
assertEquals(
true,
NameLogic.isAName(
packageName.getQualifier().get().getQualifier().get()));
ClassOrInterfaceDeclaration classA = cu.getType(0).asClassOrInterfaceDeclaration();
assertEquals(false, NameLogic.isAName(classA));
assertEquals(true, NameLogic.isAName(classA.getName()));
MethodDeclaration methodFoo = classA.getMethods().get(0);
assertEquals(false, NameLogic.isAName(methodFoo));
assertEquals(true, NameLogic.isAName(methodFoo.getName()));
assertEquals(false, NameLogic.isAName(methodFoo.getParameter(0)));
assertEquals(true, NameLogic.isAName(methodFoo.getParameter(0).getName()));
assertEquals(false, NameLogic.isAName(methodFoo.getParameter(0).getType()));
assertEquals(false, NameLogic.isAName(methodFoo.getType()));
ReturnStmt returnStmt = methodFoo.getBody().get().getStatements().get(0).asReturnStmt();
assertEquals(false, NameLogic.isAName(returnStmt));
assertEquals(true, NameLogic.isAName(returnStmt.getExpression().get()));
FieldAccessExpr fieldAccessExpr = returnStmt.getExpression().get().asFieldAccessExpr();
assertEquals(true, NameLogic.isAName(fieldAccessExpr.getScope())); // a.b.c.D
assertEquals(
true,
NameLogic.isAName(fieldAccessExpr.getScope().asFieldAccessExpr().getScope())); // a.b.c
assertEquals(
true,
NameLogic.isAName(fieldAccessExpr
.getScope()
.asFieldAccessExpr()
.getScope()
.asFieldAccessExpr()
.getScope())); // a.b
assertEquals(
true,
NameLogic.isAName(fieldAccessExpr
.getScope()
.asFieldAccessExpr()
.getScope()
.asFieldAccessExpr()
.getScope()
.asFieldAccessExpr()
.getScope())); // a
}
@Test
void identifyNameRolesInSimpleExamples() {
String code = "package a.b.c; class A { void foo(int param) { return a.b.c.D.e; } }";
CompilationUnit cu = StaticJavaParser.parse(code);
Name packageName = cu.getPackageDeclaration().get().getName();
assertEquals(DECLARATION, NameLogic.classifyRole(packageName));
assertEquals(
DECLARATION, NameLogic.classifyRole(packageName.getQualifier().get()));
assertEquals(
DECLARATION,
NameLogic.classifyRole(
packageName.getQualifier().get().getQualifier().get()));
ClassOrInterfaceDeclaration classA = cu.getType(0).asClassOrInterfaceDeclaration();
assertEquals(DECLARATION, NameLogic.classifyRole(classA.getName()));
MethodDeclaration methodFoo = classA.getMethods().get(0);
assertEquals(DECLARATION, NameLogic.classifyRole(methodFoo.getName()));
assertEquals(
DECLARATION, NameLogic.classifyRole(methodFoo.getParameter(0).getName()));
ReturnStmt returnStmt = methodFoo.getBody().get().getStatements().get(0).asReturnStmt();
assertEquals(
REFERENCE, NameLogic.classifyRole(returnStmt.getExpression().get())); // a.b.c.D.e
FieldAccessExpr fieldAccessExpr = returnStmt.getExpression().get().asFieldAccessExpr();
assertEquals(REFERENCE, NameLogic.classifyRole(fieldAccessExpr.getScope())); // a.b.c.D
assertEquals(
REFERENCE,
NameLogic.classifyRole(
fieldAccessExpr.getScope().asFieldAccessExpr().getScope())); // a.b.c
assertEquals(
REFERENCE,
NameLogic.classifyRole(fieldAccessExpr
.getScope()
.asFieldAccessExpr()
.getScope()
.asFieldAccessExpr()
.getScope())); // a.b
assertEquals(
REFERENCE,
NameLogic.classifyRole(fieldAccessExpr
.getScope()
.asFieldAccessExpr()
.getScope()
.asFieldAccessExpr()
.getScope()
.asFieldAccessExpr()
.getScope())); // a
}
@Test
void nameAsStringModuleName() {
ModuleDeclaration md = parse(
"module com.mydeveloperplanet.jpmshello {\n" + " requires java.base;\n"
+ " requires java.xml;\n"
+ " requires com.mydeveloperplanet.jpmshi;\n"
+ "}\n",
ParseStart.MODULE_DECLARATION);
assertEquals("com.mydeveloperplanet.jpmshello", NameLogic.nameAsString(md.getName()));
}
@Test
void nameAsStringClassName() {
CompilationUnit cu = parse("class Foo extends bar.MyClass { }", ParseStart.COMPILATION_UNIT);
assertEquals("Foo", NameLogic.nameAsString(cu.getType(0).getName()));
}
@Test
void qualifiedModuleName() {
assertIsQualifiedName(
"module com.mydeveloperplanet.jpmshello {\n" + " requires java.base;\n"
+ " requires java.xml;\n"
+ " requires com.mydeveloperplanet.jpmshi;\n"
+ "}\n",
"com.mydeveloperplanet.jpmshello",
ParseStart.MODULE_DECLARATION);
}
@Test
void simpleNameUnqualifiedAnnotationMemberTypeTypeName() {
assertIsSimpleName("@interface MyAnno { MyClass myMember(); }", "MyClass", ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleModuleName() {
assertNameInCodeHasRole(
"module com.mydeveloperplanet.jpmshello {\n" + " requires java.base;\n"
+ " requires java.xml;\n"
+ " requires com.mydeveloperplanet.jpmshi;\n"
+ "}\n",
"com.mydeveloperplanet.jpmshello",
DECLARATION,
ParseStart.MODULE_DECLARATION);
}
@Test
void classifyRoleRequiresModuleName() {
assertNameInCodeHasRole(
"module com.mydeveloperplanet.jpmshello {\n" + " requires java.base;\n"
+ " requires java.xml;\n"
+ " requires com.mydeveloperplanet.jpmshi;\n"
+ "}\n",
"java.xml",
REFERENCE,
ParseStart.MODULE_DECLARATION);
}
@Test
void classifyRoleExportsModuleName() {
assertNameInCodeHasRole(
"module my.module{\n" + " exports my.packag to other.module, another.module;\n" + "}",
"other.module",
REFERENCE,
ParseStart.MODULE_DECLARATION);
}
@Test
void classifyRoleOpensModuleName() {
assertNameInCodeHasRole(
"module client.modul{\n" + " opens some.client.packag to framework.modul;\n"
+ " requires framework.modul2;\n"
+ "}",
"framework.modul",
REFERENCE,
ParseStart.MODULE_DECLARATION);
}
@Test
void classifyRoleExportsPackageName() {
assertNameInCodeHasRole(
"module common.widget{\n" + " exports com.logicbig;\n" + "}",
"com.logicbig",
REFERENCE,
ParseStart.MODULE_DECLARATION);
}
@Test
void classifyRoleOpensPackageName() {
assertNameInCodeHasRole(
"module foo {\n" + " opens com.example.bar;\n" + "}",
"com.example.bar",
REFERENCE,
ParseStart.MODULE_DECLARATION);
}
@Test
void classifyRolePackageNameInPackageName() {
assertNameInCodeHasRole(
"module foo {\n" + " opens com.example.bar;\n" + "}",
"com.example",
REFERENCE,
ParseStart.MODULE_DECLARATION);
}
@Test
void classifyRoleUsesTypeName() {
assertNameInCodeHasRole(
"module modi.mod {\n" + " uses modi.api;\n" + "}",
"modi.api",
REFERENCE,
ParseStart.MODULE_DECLARATION);
}
@Test
void classifyRoleProvidesTypeName() {
assertNameInCodeHasRole(
"module foo {\n" + " provides com.modi.api.query.Query with ModuleQuery;\n" + "}",
"com.modi.api.query.Query",
REFERENCE,
ParseStart.MODULE_DECLARATION);
}
@Test
void classifyRoleSingleTypeImportTypeName() {
assertNameInCodeHasRole("import a.b.c;", "a.b.c", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleSingleStaticTypeImportTypeName() {
assertNameInCodeHasRole("import static a.B.c;", "a.B", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleSingleStaticImportOnDemandTypeName() {
assertNameInCodeHasRole("import static a.B.*;", "a.B", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleConstructorDeclarationTypeName() {
assertNameInCodeHasRole("A() { }", "A", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleAnnotationTypeName() {
assertNameInCodeHasRole("@Anno class A {} ", "Anno", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleClassName() {
assertNameInCodeHasRole("@Anno class A {} ", "A", DECLARATION, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleClassLiteralTypeName() {
assertNameInCodeHasRole("Class<?> c = String.class;", "String", REFERENCE, ParseStart.STATEMENT);
}
@Test
void classifyRoleThisExprTypeName() {
assertNameInCodeHasRole("Object o = String.this;", "String", REFERENCE, ParseStart.STATEMENT);
}
@Test
void classifyRoleQualifiedSuperFieldAccessTypeName() {
assertNameInCodeHasRole("Object o = MyClass.super.myField;", "MyClass", REFERENCE, ParseStart.STATEMENT);
}
@Test
void classifyRoleQualifiedSuperCallTypeName() {
assertNameInCodeHasRole("Object o = MyClass.super.myCall();", "MyClass", REFERENCE, ParseStart.STATEMENT);
}
@Test
void classifyRoleQualifiedSuperMethodReferenceTypeName() {
assertNameInCodeHasRole("Object o = MyClass.super::myMethod;", "MyClass", REFERENCE, ParseStart.STATEMENT);
}
@Test
void classifyRoleExtendsClauseTypeName() {
assertNameInCodeHasRole(
"class Foo extends bar.MyClass { }", "bar.MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleImplementsClauseTypeName() {
assertNameInCodeHasRole(
"class Foo implements bar.MyClass { }", "bar.MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleReturnTypeTypeName() {
assertNameInCodeHasRole(
"class Foo { bar.MyClass myMethod() {} }", "bar.MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleQualifiedAnnotationMemberTypeTypeName() {
assertNameInCodeHasRole(
"@interface MyAnno { bar.MyClass myMember(); }", "bar.MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleAnnotationName() {
assertNameInCodeHasRole(
"@interface MyAnno { bar.MyClass myMember(); }", "MyAnno", DECLARATION, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleUnqualifiedAnnotationMemberTypeTypeName() {
assertNameInCodeHasRole(
"@interface MyAnno { MyClass myMember(); }", "MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleThrowClauseMethodTypeName() {
assertNameInCodeHasRole(
"class Foo { void myMethod() throws bar.MyClass {} }",
"bar.MyClass",
REFERENCE,
ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleQualifiedThrowClauseConstructorTypeName() {
assertNameInCodeHasRole(
"class Foo { Foo() throws bar.MyClass {} }", "bar.MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleUnualifiedThrowClauseConstructorTypeName() {
assertNameInCodeHasRole(
"class Foo { Foo() throws MyClass {} }", "MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleQualifiedFieldTypeTypeName() {
assertNameInCodeHasRole(
"class Foo { bar.MyClass myField; }", "bar.MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleFieldTypeTypeNameSecondAttempt() {
assertNameInCodeHasRole(
"public class JavaParserInterfaceDeclaration extends AbstractTypeDeclaration implements InterfaceDeclaration {\n"
+ "private TypeSolver typeSolver; }",
"TypeSolver",
REFERENCE,
ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleUnqualifiedFieldTypeTypeName() {
assertNameInCodeHasRole("class Foo { MyClass myField; }", "MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleFieldName() {
assertNameInCodeHasRole("class Foo { MyClass myField; }", "myField", DECLARATION, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleQualifiedFormalParameterOfMethodTypeName() {
assertNameInCodeHasRole(
"class Foo { void myMethod(bar.MyClass param) {} }",
"bar.MyClass",
REFERENCE,
ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleUnqualifiedFormalParameterOfMethodTypeName() {
assertNameInCodeHasRole(
"class Foo { void myMethod(MyClass param) {} }", "MyClass", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleMethodName() {
assertNameInCodeHasRole(
"class Foo { void myMethod(MyClass param) {} }", "myMethod", DECLARATION, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleReceiverParameterOfMethodTypeName() {
assertNameInCodeHasRole("void myMethod(Foo this) {}", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleVariableDeclarationTypeTypeName() {
assertNameInCodeHasRole("void myMethod() { Foo myVar; }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleExceptionParameterTypeTypeName() {
assertNameInCodeHasRole(
"void myMethod() { try { } catch(Foo e) { } }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleExceptionParameterName() {
assertNameInCodeHasRole(
"void myMethod() { try { } catch(Foo e) { } }", "e", DECLARATION, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleExplicitParameterTypeInConstructorCallTypeName() {
assertNameInCodeHasRole("void myMethod() { new Call<Foo>(); }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleExplicitParameterTypeInMethodCallTypeName() {
assertNameInCodeHasRole(
"void myMethod() { new Call().<Foo>myMethod(); }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleInstantiationCallTypeName() {
assertNameInCodeHasRole("void myMethod() { new Foo(); }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleInstantiationCallOfAnonymousTypeTypeName() {
assertNameInCodeHasRole(
"void myMethod() { new Foo() { void method() { } } ; }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleArrayCreationExpressionTypeName() {
assertNameInCodeHasRole("void myMethod() { new Foo[0]; }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleCastTypeName() {
assertNameInCodeHasRole(
"void myMethod() { Object o = (Foo)someField; }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleInstanceOfTypeName() {
assertNameInCodeHasRole(
"void myMethod() { if (myValue instanceof Foo) { }; }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleInstanceOfPatternTypeName() {
// Note: Requires JDK14
assertNameInCodeHasRole(
"void myMethod() { if (myValue instanceof Foo f) { }; }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleMethodReferenceTypeName() {
assertNameInCodeHasRole(
"void myMethod() { Object o = Foo::myMethod; }", "Foo", REFERENCE, ParseStart.CLASS_BODY);
}
@Test
void classifyRoleQualifiedConstructorSuperClassInvocationExpressionName() {
assertNameInCodeHasRole(
"class Bar { Bar() { anExpression.super(); } } ",
"anExpression",
REFERENCE,
ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleQualifiedClassInstanceCreationExpressionName() {
assertNameInCodeHasRole(
"class Bar { Bar() { anExpression.new MyClass(); } } ",
"anExpression",
REFERENCE,
ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleArrayReferenceExpressionName() {
assertNameInCodeHasRole(
"class Bar { Bar() { anExpression[0]; } } ", "anExpression", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRolePostfixExpressionName() {
assertNameInCodeHasRole(
"class Bar { Bar() { anExpression++; } } ", "anExpression", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleLeftHandAssignmentExpressionName() {
assertNameInCodeHasRole(
"class Bar { Bar() { anExpression = 2; } } ", "anExpression", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleVariableAccessInTryWithResourceExpressionName() {
assertNameInCodeHasRole(
"class Bar { Bar() { try (anExpression) { }; } } ",
"anExpression",
REFERENCE,
ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleVariableAccessInTryWithResourceWithTypeExpressionName() {
assertNameInCodeHasRole(
"class Bar { Bar() { try (Object o = anExpression) { }; } } ",
"anExpression",
REFERENCE,
ParseStart.COMPILATION_UNIT);
}
@Test
void classifyTryWithResourceName() {
assertNameInCodeHasRole(
"class Bar { Bar() { try (Object o = anExpression) { }; } } ",
"o",
DECLARATION,
ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleMethodInvocationMethodName() {
assertNameInCodeHasRole(
"class Bar { Bar() { myMethod(); } } ", "myMethod", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleLeftOfQualifiedTypeNamePackageOrTypeName() {
assertNameInCodeHasRole(
"class Bar { Bar() { new myQualified.path.to.TypeName(); } } ",
"myQualified.path.to",
REFERENCE,
ParseStart.COMPILATION_UNIT);
assertNameInCodeHasRole(
"class Bar { Bar() { new myQualified.path.to.TypeName(); } } ",
"myQualified.path",
REFERENCE,
ParseStart.COMPILATION_UNIT);
assertNameInCodeHasRole(
"class Bar { Bar() { new myQualified.path.to.TypeName(); } } ",
"myQualified",
REFERENCE,
ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleTypeImportOnDemandPackageOrTypeName() {
assertNameInCodeHasRole("import a.B.*;", "a.B", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleLeftOfExpressionNameAmbiguousName() {
assertNameInCodeHasRole(
"class Bar { Bar() { a.b.c.anExpression[0]; } } ", "a.b.c", REFERENCE, ParseStart.COMPILATION_UNIT);
assertNameInCodeHasRole(
"class Bar { Bar() { a.b.c.anExpression[0]; } } ", "a.b", REFERENCE, ParseStart.COMPILATION_UNIT);
assertNameInCodeHasRole(
"class Bar { Bar() { a.b.c.anExpression[0]; } } ", "a", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void classifyRoleLeftOfMethodCallAmbiguousName() {
assertNameInCodeHasRole(
"class Bar { Bar() { a.b.c.aMethod(); } } ", "a.b.c", REFERENCE, ParseStart.COMPILATION_UNIT);
}
@Test
void defaultValueTypeName() {
assertNameInCodeIsSyntactically(
"@RequestForEnhancement(\n" + " id = 2868724,\n"
+ " synopsis = \"Provide time-travel functionality\",\n"
+ " engineer = \"Mr. Peabody\",\n"
+ " date = anExpression"
+ ")\n"
+ "public static void travelThroughTime(Date destination) { }",
"anExpression",
NameCategory.AMBIGUOUS_NAME,
ParseStart.CLASS_BODY);
}
@Test
void classifyRoleDefaultValueTypeName() {
assertNameInCodeHasRole(
"@RequestForEnhancement(\n" + " id = 2868724,\n"
+ " synopsis = \"Provide time-travel functionality\",\n"
+ " engineer = \"Mr. Peabody\",\n"
+ " date = anExpression"
+ ")\n"
+ "public static void travelThroughTime(Date destination) { }",
"anExpression",
REFERENCE,
ParseStart.CLASS_BODY);
}
@Test
void classifyRoleDefaultValueDeclaration() {
assertNameInCodeHasRole(
"@RequestForEnhancement(\n" + " id = 2868724,\n"
+ " synopsis = \"Provide time-travel functionality\",\n"
+ " engineer = \"Mr. Peabody\",\n"
+ " date = anExpression"
+ ")\n"
+ "public static void travelThroughTime(Date destination) { }",
"date",
DECLARATION,
ParseStart.CLASS_BODY);
}
}