Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Search for packages in all available Java modules #3771

Merged
Merged
22 changes: 17 additions & 5 deletions src/main/java/spoon/reflect/factory/PackageFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.StringTokenizer;
import spoon.reflect.declaration.CtModule;
import spoon.reflect.declaration.CtPackage;
Expand Down Expand Up @@ -157,13 +158,24 @@ public CtPackage get(String qualifiedName) {
if (qualifiedName.contains(CtType.INNERTTYPE_SEPARATOR)) {
throw new RuntimeException("Invalid package name " + qualifiedName);
}

return factory.getModel().getAllModules().stream()
.map(module -> getPackageFromModule(qualifiedName, module))
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
}

/**
* @param qualifiedName Qualified name of a package.
* @param module A module in which to search for the package.
* @return The package if found in this module, otherwise null.
*/
private static CtPackage getPackageFromModule(String qualifiedName, CtModule module) {
StringTokenizer token = new StringTokenizer(qualifiedName, CtPackage.PACKAGE_SEPARATOR);
CtPackage current = factory.getModel().getRootPackage();
if (token.hasMoreElements()) {
CtPackage current = module.getRootPackage();
while (token.hasMoreElements() && current != null) {
current = current.getPackage(token.nextToken());
while (token.hasMoreElements() && current != null) {
current = current.getPackage(token.nextToken());
}
}

return current;
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/spoon/test/compilationunit/TestCompilationUnit.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
Expand Down Expand Up @@ -132,6 +135,22 @@ public void testCompilationUnitDeclaredTypes() throws IOException {
}
}

@Test
public void testCompilationUnitInNamedModuleHasDeclaredTypes() {
// contract: Compilation units in named modules should have the expected declared types

final Launcher launcher = new Launcher();
launcher.getEnvironment().setComplianceLevel(9);
launcher.addInputResource("./src/test/resources/spoon/test/module/simple_module_with_code");
launcher.buildModel();

CtType<?> expectedType = launcher.getFactory().Type().get("fr.simplemodule.pack.SimpleClass");
CtCompilationUnit cu = launcher.getFactory().CompilationUnit().getOrCreate(expectedType);

assertThat(cu.getDeclaredTypes(), equalTo(Collections.singletonList(expectedType)));
}


@Test
public void testCompilationUnitSourcePosition() throws IOException {
// contract: the CompilationUnit has root source position
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/spoon/test/ctType/CtTypeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.test.ctType.testclasses.X;

import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
Expand All @@ -47,6 +48,7 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static spoon.testing.utils.ModelUtils.buildClass;
import static spoon.testing.utils.ModelUtils.createFactory;
Expand Down Expand Up @@ -248,4 +250,21 @@ public void getUsedTypesWithWildcard() {
type.getUsedTypes(false);
});
}

@Test
public void testTypeDeclarationToReferenceRoundTripInNamedModule() {
// contract: It's possible to go from a type declaration, to a reference, and back to the declaration
// when the declaration is contained within a named module

final Launcher launcher = new Launcher();
launcher.getEnvironment().setComplianceLevel(9);
launcher.addInputResource("./src/test/resources/spoon/test/module/simple_module_with_code");
launcher.buildModel();

CtType<?> typeDecl = launcher.getFactory().Type().get("fr.simplemodule.pack.SimpleClass");
CtTypeReference<?> typeRef = typeDecl.getReference();
CtType<?> reFetchedTypeDecl = typeRef.getTypeDeclaration();

assertSame(reFetchedTypeDecl, typeDecl);
}
}
20 changes: 20 additions & 0 deletions src/test/java/spoon/test/factory/FactoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@
import spoon.test.factory.testclasses.Foo;

import java.lang.reflect.Method;
import java.nio.file.Paths;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
Expand Down Expand Up @@ -170,6 +173,23 @@ public void process(CtType element) {
assertEquals(0, model.getAllTypes().size());
}

@Test
public void testGetPackageFromNamedModule() {
// contract: It should be possible to get a package from a named module

final Launcher launcher = new Launcher();
launcher.getEnvironment().setComplianceLevel(9);
launcher.addInputResource("./src/test/resources/spoon/test/module/simple_module_with_code");
launcher.buildModel();

String packageName = "fr.simplemodule.pack";
CtPackage packageInNamedModule = launcher.getFactory().Package().get(packageName);

assertNotNull(packageInNamedModule);
assertThat(packageInNamedModule.getQualifiedName(), equalTo(packageName));
}


public void testIncrementalModel() {

// contract: one can merge two models together
Expand Down