From 2dcfbfaf0dee2e4f023666e0af415d408b98e744 Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Mon, 23 Dec 2024 15:08:44 +0100 Subject: [PATCH 1/4] Add placeholder source folder/module for typepal --- META-INF/RASCAL.MF | 2 +- src/org/rascalmpl/typepal/Typepal.rsc | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 src/org/rascalmpl/typepal/Typepal.rsc diff --git a/META-INF/RASCAL.MF b/META-INF/RASCAL.MF index d3977080a63..c43531825ba 100644 --- a/META-INF/RASCAL.MF +++ b/META-INF/RASCAL.MF @@ -1,5 +1,5 @@ Project-Name: rascal -Source: src/org/rascalmpl/library,test/org/rascalmpl/benchmark,test//org/rascalmpl/test/data +Source: src/org/rascalmpl/library,src/org/rascalmpl/typepal,test/org/rascalmpl/benchmark,test//org/rascalmpl/test/data Courses: src/org/rascalmpl/courses diff --git a/src/org/rascalmpl/typepal/Typepal.rsc b/src/org/rascalmpl/typepal/Typepal.rsc new file mode 100644 index 00000000000..12676023bcd --- /dev/null +++ b/src/org/rascalmpl/typepal/Typepal.rsc @@ -0,0 +1,5 @@ +module Typepal + +// TODO: This is intended to be a temporary placeholder module (useful for +// testing `PathConfig` changes). It should be removed when `typepal` has been +// merged into `rascal`. \ No newline at end of file From 24ab304f3baf15b4cc747d09b9465127193f34c4 Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Mon, 23 Dec 2024 15:25:56 +0100 Subject: [PATCH 2/4] Print also physical location of `std` in `printInterpreterConfigurationStatus` --- src/org/rascalmpl/library/util/PathConfig.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/org/rascalmpl/library/util/PathConfig.java b/src/org/rascalmpl/library/util/PathConfig.java index 56c205af84c..d9ce021f1e9 100644 --- a/src/org/rascalmpl/library/util/PathConfig.java +++ b/src/org/rascalmpl/library/util/PathConfig.java @@ -788,7 +788,18 @@ private static String computeMavenCommandName() { */ public void printInterpreterConfigurationStatus(PrintWriter out) { out.println("Module paths:"); - getSrcs().forEach((f) -> out.println(" ".repeat(4) + f)); + getSrcs().forEach(f -> { + var l = (ISourceLocation) f; + var s = " ".repeat(4) + l; + if (l.getScheme().equals("std")) { + try { + s += " at " + URIResolverRegistry.getInstance().logicalToPhysical(l); + } catch (IOException e) { + s += " at unknown physical location"; + } + } + out.println(s); + }); out.println("JVM library classpath:"); getLibsAndTarget().forEach((l) -> out.println(" ".repeat(4) + l)); out.flush(); From 0fa9203556e4fc0a36a11f5e77189cabf0494897 Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Mon, 23 Dec 2024 15:28:53 +0100 Subject: [PATCH 3/4] Specialize computation of module path for `rascal` source folders --- .../rascalmpl/library/util/PathConfig.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/org/rascalmpl/library/util/PathConfig.java b/src/org/rascalmpl/library/util/PathConfig.java index d9ce021f1e9..014336ffb73 100644 --- a/src/org/rascalmpl/library/util/PathConfig.java +++ b/src/org/rascalmpl/library/util/PathConfig.java @@ -16,8 +16,10 @@ import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.function.BiPredicate; import java.util.jar.Manifest; import org.rascalmpl.interpreter.Configuration; @@ -26,6 +28,7 @@ import org.rascalmpl.uri.URIResolverRegistry; import org.rascalmpl.uri.URIUtil; import org.rascalmpl.uri.file.MavenRepositoryURIResolver; +import org.rascalmpl.uri.jar.JarURIResolver; import org.rascalmpl.values.IRascalValueFactory; import org.rascalmpl.values.ValueFactoryFactory; @@ -635,8 +638,34 @@ else if (rascalProject != null) { messages.append(Messages.error(e.getMessage(), getRascalMfLocation(manifestRoot))); } + // The `rascal` project has two special source folders (`.../library` + // and `.../typepal`). The versions of these two folders in the + // "current" `rascal` (as per `resolveCurrentRascalRuntimeJar()`) are + // always included in the module path. All remaining source folders of + // the `rascal` project are always excluded, except when the current + // project happens to be `rascal` itself (in which case they are + // normally included). + ISourceLocation currentRascal = URIUtil.unknownLocation(); + try { + currentRascal = JarURIResolver.jarify(resolveCurrentRascalRuntimeJar()); + } catch (IOException e) { + messages.append(Messages.error(e.getMessage(), manifestRoot)); + } + + var rascalSpecialSrcs = new LinkedHashMap(); // Keep insertion order for predictable output + rascalSpecialSrcs.put(URIUtil.rootLocation("std"),"src/org/rascalmpl/library"); + rascalSpecialSrcs.put(URIUtil.getChildLocation(currentRascal, "org/rascalmpl/typepal"), "src/org/rascalmpl/typepal"); + + BiPredicate isRascalSpecialSrc = (project, src) -> + "rascal".equals(project) && rascalSpecialSrcs.values().contains(src); + + srcsWriter.appendAll(rascalSpecialSrcs.keySet()); for (String srcName : manifest.getSourceRoots(manifestRoot)) { + if (isRascalSpecialSrc.test(projectName, srcName)) { + continue; // Don't append special source folders again + } + var srcFolder = URIUtil.getChildLocation(manifestRoot, srcName); if (!reg.exists(srcFolder) || !reg.isDirectory(srcFolder)) { From 7766602c4dfbd881a2d4560a3882a6623dfeb7aa Mon Sep 17 00:00:00 2001 From: Sung-Shik Jongmans Date: Tue, 24 Dec 2024 11:26:36 +0100 Subject: [PATCH 4/4] Refine approach to add `rascal` source folders to path configs (and move code to separate method) --- .../rascalmpl/library/util/PathConfig.java | 103 ++++++++++++------ 1 file changed, 71 insertions(+), 32 deletions(-) diff --git a/src/org/rascalmpl/library/util/PathConfig.java b/src/org/rascalmpl/library/util/PathConfig.java index 014336ffb73..2e2b87d5301 100644 --- a/src/org/rascalmpl/library/util/PathConfig.java +++ b/src/org/rascalmpl/library/util/PathConfig.java @@ -16,10 +16,9 @@ import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.function.BiPredicate; +import java.util.function.Predicate; import java.util.jar.Manifest; import org.rascalmpl.interpreter.Configuration; @@ -638,41 +637,22 @@ else if (rascalProject != null) { messages.append(Messages.error(e.getMessage(), getRascalMfLocation(manifestRoot))); } - // The `rascal` project has two special source folders (`.../library` - // and `.../typepal`). The versions of these two folders in the - // "current" `rascal` (as per `resolveCurrentRascalRuntimeJar()`) are - // always included in the module path. All remaining source folders of - // the `rascal` project are always excluded, except when the current - // project happens to be `rascal` itself (in which case they are - // normally included). - - ISourceLocation currentRascal = URIUtil.unknownLocation(); try { - currentRascal = JarURIResolver.jarify(resolveCurrentRascalRuntimeJar()); + addRascalToSourcePath(srcsWriter); } catch (IOException e) { - messages.append(Messages.error(e.getMessage(), manifestRoot)); + messages.append(Messages.error(e.getMessage(), getRascalMfLocation(manifestRoot))); } - var rascalSpecialSrcs = new LinkedHashMap(); // Keep insertion order for predictable output - rascalSpecialSrcs.put(URIUtil.rootLocation("std"),"src/org/rascalmpl/library"); - rascalSpecialSrcs.put(URIUtil.getChildLocation(currentRascal, "org/rascalmpl/typepal"), "src/org/rascalmpl/typepal"); - - BiPredicate isRascalSpecialSrc = (project, src) -> - "rascal".equals(project) && rascalSpecialSrcs.values().contains(src); - - srcsWriter.appendAll(rascalSpecialSrcs.keySet()); - for (String srcName : manifest.getSourceRoots(manifestRoot)) { - if (isRascalSpecialSrc.test(projectName, srcName)) { - continue; // Don't append special source folders again - } + if (!projectName.equals("rascal")) { // Don't add `rascal` again + for (String srcName : manifest.getSourceRoots(manifestRoot)) { + var srcFolder = URIUtil.getChildLocation(manifestRoot, srcName); + + if (!reg.exists(srcFolder) || !reg.isDirectory(srcFolder)) { + messages.append(Messages.error("Source folder " + srcFolder + " does not exist.", getRascalMfLocation(rascalProject))); + } - var srcFolder = URIUtil.getChildLocation(manifestRoot, srcName); - - if (!reg.exists(srcFolder) || !reg.isDirectory(srcFolder)) { - messages.append(Messages.error("Source folder " + srcFolder + " does not exist.", getRascalMfLocation(rascalProject))); + srcsWriter.append(srcFolder); } - - srcsWriter.append(srcFolder); } return new PathConfig( @@ -684,6 +664,65 @@ else if (rascalProject != null) { messages.done()); } + /** + * Adds the source folders of the `rascal` project to `srcsWriter`. + * + * For each source folder, there are at most two version to choose from: + * - The version in the "current" `rascal` (as per + * `resolveCurrentRascalRuntimeJar()`). Alway available. + * - The version in the "other" `rascal` (as per the + * `URIResolverRegistry`). Available when `rascal` itself is the main + * project, or when `rascal` is open in the workspace. + * + * The version of each source folder of the `rascal` project to add, is + * chosen based on the kind of that source folder: + * - Kind #1 (e.g., `.../library`, i.e., `|std:///|`): Add the version of + * the source folder in the current `rascal` + * - Kind #2 (e.g., `.../typepal`): Add the version of the source folder + * in the other `rascal` (if available) or the current `rascal` (else) + * - Kind #3 (e.g., `test/...`): Add the version of the source folder in + * the other `rascal` (if available) + * + * Thus, source folders of kinds #1 and #2 are added always, while source + * folders of kind #3 are added only when the `rascal` project itself is + * being developed. + * + * @throws IOException When the current `rascal` can't be resolved + */ + private static void addRascalToSourcePath(IListWriter srcsWriter) throws IOException { + var currentRascalTargetClasses = JarURIResolver.jarify(resolveCurrentRascalRuntimeJar()); + + // Assumption: If `rascal` itself is the main project, or if `rascal` is + // open in the workspace, then its root folder has already been + // registered as `|project://rascal/|` in the resolver registry (so + // checking the project name isn't needed after checking the registry). + var otherRascal = URIUtil.correctLocation("project", "rascal", ""); + var otherRascalExists = URIResolverRegistry.getInstance().exists(otherRascal); + + // Include source folders of kind #1 + srcsWriter.append(URIUtil.rootLocation("std")); + + // Include source folders of kind #2 + if (otherRascalExists) { + srcsWriter.append(URIUtil.getChildLocation(otherRascal, "src/org/rascalmpl/typepal")); + } else { + srcsWriter.append(URIUtil.getChildLocation(currentRascalTargetClasses, "org/rascalmpl/typepal")); + } + + // Include source folders of kind #3 + if (otherRascalExists) { + Predicate isKind3 = s -> + !s.equals("src/org/rascalmpl/library") && + !s.equals("src/org/rascalmpl/typepal"); + + new RascalManifest() + .getSourceRoots(otherRascal) + .stream() + .filter(isKind3) + .forEach(src -> srcsWriter.append(URIUtil.getChildLocation(otherRascal, src))); + } + } + private static void addLibraryToSourcePath(URIResolverRegistry reg, IListWriter srcsWriter, IListWriter messages, ISourceLocation jar) { if (!reg.exists(URIUtil.getChildLocation(jar, RascalManifest.META_INF_RASCAL_MF))) { // skip all the non Rascal libraries @@ -820,7 +859,7 @@ public void printInterpreterConfigurationStatus(PrintWriter out) { getSrcs().forEach(f -> { var l = (ISourceLocation) f; var s = " ".repeat(4) + l; - if (l.getScheme().equals("std")) { + if (l.getScheme().equals("std") || l.getScheme().equals("project")) { try { s += " at " + URIResolverRegistry.getInstance().logicalToPhysical(l); } catch (IOException e) {