Skip to content

Commit

Permalink
fix: Search for packages in all available Java modules (INRIA#3771)
Browse files Browse the repository at this point in the history
  • Loading branch information
slarse authored Feb 2, 2021
1 parent 3c3949b commit 6e8c5b8
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 5 deletions.
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

0 comments on commit 6e8c5b8

Please sign in to comment.