From 58767ad6cccb667c0c95ab905c8d95ad2a39630f Mon Sep 17 00:00:00 2001 From: Andrew Bwogi Date: Mon, 2 Aug 2021 10:09:57 +0200 Subject: [PATCH] set correct names to modules in JDTBatchCompiler --- .../compiler/jdt/JDTBatchCompiler.java | 32 +++++++++++++++-- .../java/spoon/test/module/TestModule.java | 36 ++++++++++++++++++- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/main/java/spoon/support/compiler/jdt/JDTBatchCompiler.java b/src/main/java/spoon/support/compiler/jdt/JDTBatchCompiler.java index ccce8f522b1..8bf5cf3727c 100644 --- a/src/main/java/spoon/support/compiler/jdt/JDTBatchCompiler.java +++ b/src/main/java/spoon/support/compiler/jdt/JDTBatchCompiler.java @@ -77,7 +77,7 @@ public CompilationUnit[] getCompilationUnits() { for (CompilationUnit compilationUnit : this.compilationUnits) { char[] charName = compilationUnit.getFileName(); boolean isModuleInfo = CharOperation.endsWith(charName, JDTConstants.MODULE_INFO_FILE_NAME); - if (isModuleInfo == (round == 0)) { // 1st round: modules, 2nd round others (to ensure populating pathToModCU well in time) + if (isModuleInfo == (round == 0)) { // 1st round: modules, 2nd round others (to ensure populating pathToModName well in time) String fileName = new String(charName); if (isModuleInfo) { @@ -95,8 +95,7 @@ public CompilationUnit[] getCompilationUnits() { if (this.module == null) { compilationUnit.module = CharOperation.subarray(modulePath, lastSlash, modulePath.length); } else { - //TODO the module name parsed by JDK compiler is in `this.modNames`, consider using that instead? - compilationUnit.module = this.module.name(); + compilationUnit.module = getModuleName(compilationUnit).toCharArray(); } pathToModName.put(String.valueOf(modulePath), compilationUnit.module); @@ -116,6 +115,33 @@ public CompilationUnit[] getCompilationUnits() { return compilationUnits; } + private String getModuleName(CompilationUnit compilationUnit) { + StringBuilder sb = new StringBuilder(); + int index = 0; + while (!sb.toString().equals("module") && index != -1) { + sb.setLength(0); + index = nextToken(compilationUnit, index, sb); + } + sb.setLength(0); + nextToken(compilationUnit, index, sb); + return sb.toString(); + } + + private int nextToken(CompilationUnit cu, int start, StringBuilder sb) { + int index = PositionBuilder.findNextNonWhitespace(cu.contents, cu.contents.length, start); + if (index == -1) { + return -1; + } + for (int i = index; i < cu.contents.length; i++) { + if (Character.isWhitespace(cu.contents[i]) || cu.contents[i] == '{') { + return i + 1; + } else { + sb.append(cu.contents[i]); + } + } + return -1; + } + public void setCompilationUnits(CompilationUnit[] compilationUnits) { this.compilationUnits = compilationUnits; } diff --git a/src/test/java/spoon/test/module/TestModule.java b/src/test/java/spoon/test/module/TestModule.java index 95166517907..cb867273169 100644 --- a/src/test/java/spoon/test/module/TestModule.java +++ b/src/test/java/spoon/test/module/TestModule.java @@ -16,6 +16,7 @@ */ package spoon.test.module; +import org.eclipse.jdt.internal.compiler.batch.CompilationUnit; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Ignore; @@ -24,6 +25,11 @@ import org.junit.jupiter.api.condition.JRE; import spoon.Launcher; import spoon.SpoonException; +import spoon.SpoonModelBuilder; +import spoon.compiler.SpoonFile; +import spoon.compiler.builder.ComplianceOptions; +import spoon.compiler.builder.JDTBuilderImpl; +import spoon.compiler.builder.SourceOptions; import spoon.reflect.CtModel; import spoon.reflect.code.CtComment; import spoon.reflect.declaration.CtClass; @@ -36,14 +42,18 @@ import spoon.reflect.declaration.CtType; import spoon.reflect.declaration.CtUsedService; import spoon.reflect.reference.CtModuleReference; -import spoon.reflect.visitor.filter.NamedElementFilter; import spoon.reflect.visitor.filter.TypeFilter; +import spoon.support.compiler.jdt.JDTBasedSpoonCompiler; +import spoon.support.compiler.jdt.JDTBatchCompiler; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.Collections; +import java.util.ArrayList; +import java.util.Arrays; import java.util.stream.Stream; import static org.junit.Assert.assertEquals; @@ -284,6 +294,30 @@ public void testGetModuleAfterChangingItsName() { assertSame(module, moduleNewName); } + @Test + public void testModuleNames() { + // contract: JDTBatchCompiler sets correct names to modules + Launcher launcher = new Launcher(); + launcher.getEnvironment().setComplianceLevel(9); + launcher.addInputResource("./src/test/resources/spoon/test/module/code-multiple-modules"); + launcher.buildModel(); + JDTBasedSpoonCompiler spoonCompiler = (JDTBasedSpoonCompiler) launcher.getModelBuilder(); + + JDTBatchCompiler batchCompiler = new JDTBatchCompiler(spoonCompiler); + SpoonModelBuilder.InputType.FILES.initializeCompiler(batchCompiler); + List sourceFiles = Collections.unmodifiableList(spoonCompiler.getSource().getAllJavaFiles()); + String[] args = new JDTBuilderImpl() + .complianceOptions(new ComplianceOptions().compliance(9)) + .sources(new SourceOptions().sources(sourceFiles)) + .build(); + batchCompiler.configure(args); + + CompilationUnit[] cu = batchCompiler.getCompilationUnits(); + List list = new ArrayList<>(Arrays.asList(new String[]{String.copyValueOf(cu[0].module),String.copyValueOf(cu[1].module)})); + assertTrue(list.contains("foo")); + assertTrue(list.contains("bar")); + } + @org.junit.jupiter.api.Test @DisabledForJreRange(max = JRE.JAVA_8) public void testSimpleModuleCanBeBuilt() {