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

Always load Rascal modules and Java classes of std from the current rascal #2103

Open
wants to merge 5 commits into
base: replace-lib-by-mvn-and-others
Choose a base branch
from

Conversation

sungshik
Copy link
Contributor

@sungshik sungshik commented Dec 17, 2024

Overview

This PR implements the following approach for loading Rascal modules and Java classes of rascal:

  • Rascal modules of rascal inside std are loaded from the "current rascal" (as per resolveCurrentRascalRuntimeJar).
  • Rascal modules of rascal outside std are loaded from the "current project" of the path config.
  • Java classes of rascal, regardless of inside/outside std, are loaded from the "current rascal" (as per resolveCurrentRascalRuntimeJar).

Thus, after this PR:

  • ✔️ Rascal modules and Java classes of rascal inside std must be loaded from the same version. This partly fixes Rascal modules and Java classes of rascal are loaded from different versions rascal-language-servers#538.

  • ⚠️ Rascal modules and Java classes of rascal outside std may be loaded from different versions. However, currently, there are no Rascal modules of rascal outside std that rely on Java classes. Moreover, after the merge of typepal and rascal-core into rascal: (1) there are no Rascal modules of typepal that rely on Java classes; (2) there are a few Rascal modules of rascal-core that rely on Java classes, but the impact seems negligible in the context of this PR.

  • ⚠️ REPLs created in VS Code always load the version of std of the deployed rascal.jar (part of the VS Code extension), which is put on the class path of the REPL's JVM. Even when rascal itself is open in the workspace, changes made to std will not be loaded in the REPL. To test such changes, a standalone Rascal shell needs to be created (but it doesn't have debugging support).

See the comments below for a few more details.

Examples (VS Code)

Create REPL in rascal

Rascal 0.40.8-EXTENSION
Rascal-lsp Unknown
Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/rascal/test/org/rascalmpl/benchmark|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/rascal/test/org/rascalmpl/test/data|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar!/|
JVM library classpath:
    |file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal.jar|
    |mvn://org.rascalmpl--rascal-p2-dependencies-repackaged--0.6.0|
    |mvn://junit--junit--4.13.2|
    ...
    |mvn://com.ibm.icu--icu4j--74.2|
    |file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar|
    |project://rascal/target/classes|

image

Create REPL in typepal (with rascal open in the workspace)

Rascal 0.40.8-EXTENSION
Rascal-lsp Unknown
Module paths:
    |std:///|
    |project://rascal/test/org/rascalmpl/benchmark|
    |project://rascal/test/org/rascalmpl/test/data|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/typepal/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar!/|
JVM library classpath:
    |file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal.jar|
    |mvn://junit--junit--4.13.1|
    ...
    |mvn://com.ibm.icu--icu4j--74.2|
    |file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar|
    |project://typepal/target/classes|

image

Create REPL in typepal (without rascal open in the workspace)

Rascal 0.40.8-EXTENSION
Rascal-lsp Unknown
Module paths:
    |std:///|
    |mvn://org.rascalmpl--rascal--0.40.8-REPOSITORY/test/org/rascalmpl/benchmark|
    |mvn://org.rascalmpl--rascal--0.40.8-REPOSITORY/test/org/rascalmpl/test/data|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/typepal/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar!/|
JVM library classpath:
    |file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal.jar|
    |mvn://junit--junit--4.13.1|
    |mvn://org.hamcrest--hamcrest-core--1.3|
    |file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar|
    |project://typepal/target/classes|

image

Example (RascalShell)

Create REPL in rascal (using a RascalShell in the same rascal)

Version: Not specified
Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/rascal3/rascal/test/org/rascalmpl/benchmark|
    |file:///C:/Users/sung-/Desktop/rascal3/rascal/test/org/rascalmpl/test/data|
JVM library classpath:
    |file:///C:/Users/sung-/Desktop/rascal3/rascal/target/classes|
    |mvn://org.rascalmpl--rascal-p2-dependencies-repackaged--0.6.0|
    |mvn://junit--junit--4.13.2|
    ...
    |mvn://com.ibm.icu--icu4j--74.2|
    |project://rascal/target/classes|
[INFO]    /C:/Users/sung-/Desktop/rascal3/rascal/pom.xml:0:0: Using Rascal standard library at |file:///C:/Users/sung-/Desktop/rascal3/rascal/target/classes|. Version: Not specified.

Create REPL in rascal (using a RascalShell in a different rascal)

Version: Not specified
Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/rascal/test/org/rascalmpl/benchmark|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/rascal/test/org/rascalmpl/test/data|
JVM library classpath:
    |file:///C:/Users/sung-/Desktop/rascal3/rascal/target/classes|
    |mvn://org.rascalmpl--rascal-p2-dependencies-repackaged--0.6.0|
    |mvn://junit--junit--4.13.2|
    ...
    |mvn://com.ibm.icu--icu4j--74.2|
    |project://rascal/target/classes|
[INFO]    /C:/Users/sung-/Desktop/rascal-which-version/projects/rascal/pom.xml:0:0: Using Rascal standard library at |file:///C:/Users/sung-/Desktop/rascal3/rascal/target/classes|. Version: Not specified.
[INFO]    /C:/Users/sung-/Desktop/rascal-which-version/projects/rascal/pom.xml:0:0: Ignoring Rascal standard library at |project://rascal/target/classes| (self-application)

Create REPL in typepal

Version: Not specified
Module paths:
    |std:///|
    |mvn://org.rascalmpl--rascal--0.40.8-REPOSITORY/test/org/rascalmpl/benchmark|
    |mvn://org.rascalmpl--rascal--0.40.8-REPOSITORY/test/org/rascalmpl/test/data|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/typepal/src|
JVM library classpath:
    |file:///C:/Users/sung-/Desktop/rascal3/rascal/target/classes|
    |mvn://junit--junit--4.13.1|
    |mvn://org.hamcrest--hamcrest-core--1.3|
    |project://typepal/target/classes|
[INFO]    /C:/Users/sung-/Desktop/rascal-which-version/projects/typepal/pom.xml:0:0: Using Rascal standard library at |file:///C:/Users/sung-/Desktop/rascal3/rascal/target/classes|. Version: Not specified.
[INFO]    /C:/Users/sung-/Desktop/rascal-which-version/projects/typepal/pom.xml:0:0: Ignoring Rascal standard library at |mvn://org.rascalmpl--rascal--0.40.8-REPOSITORY| (dependency in POM)

Copy link
Contributor Author

@sungshik sungshik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more details

Comment on lines +59 to +74
<resource>
<targetPath>test/org/rascalmpl/benchmark</targetPath>
<directory>test/org/rascalmpl/benchmark</directory>
<excludes>
<exclude>**/*.java</exclude>
<exclude>**/*.class</exclude>
</excludes>
</resource>
<resource>
<targetPath>test/org/rascalmpl/test/data</targetPath>
<directory>test/org/rascalmpl/test/data</directory>
<excludes>
<exclude>**/*.java</exclude>
<exclude>**/*.class</exclude>
</excludes>
</resource>
Copy link
Contributor Author

@sungshik sungshik Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just temporary here for testing. I'll remove it again before merging (assuming we don't really want to package this?).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, indeed, let's not.

@@ -535,15 +545,17 @@ public static PathConfig fromSourceProjectRascalManifest(ISourceLocation manifes
}

if (libProjectName != null) {
if (reg.exists(projectLoc) && dep != rascalProject) {
if (reg.exists(projectLoc)) {
Copy link
Contributor Author

@sungshik sungshik Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This conditional was simplified to: either the dependency project is open in the workspace, or it's not. Special case for rascal isn't needed anymore at this level.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some doubts about this. The function is recursive so we might end up following a pom dependency to a rascal project that is open. What exactly happens in this case?

I think what should happen is we indeed only depend on the deployed rascal jar, but additionally to this we should not add the compiler and tutor and typepal to the source path of the current project. So this should require some extra code/conditionals.

Copy link
Contributor Author

@sungshik sungshik Dec 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: I just re-read your other comment in more detail, and I think it already confirms my understand of what I thought you meant is correct.

Hm, good question! I think you're right. But, I'll try to rephrase your point with some examples to see if I really understand. It's a bit of a lengthy response, but I need to make sure I'm not going to implement the wrong thing 😉.

Suppose, post-merge, the rascal project has the following source folders (names adopted from another comment by Jurgen):

  • src/org/rascalmpl/tutor
  • src/org/rascalmpl/typepal
  • src/org/rascalmpl/compiler

Current implementation of this PR

Approach: All non-std source folders of rascal are added to the module path.

If a REPL is created for project a in VS Code, and rascal is open in the workspace, then:

Module paths:
    |std:///|
    |project://rascal/src/org/rascalmpl/tutor|
    |project://rascal/src/org/rascalmpl/typepal|
    |project://rascal/src/org/rascalmpl/compiler|
    |file:///C:/Users/sung-/Desktop/a/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-1.0.0/assets/jars/rascal-lsp.jar!/|

If a REPL is created for project a in VS Code, and rascal isn't open in the workspace, then:

Module paths:
    |std:///|
    |mvn://org.rascalmpl--rascal--1.0.0/src/org/rascalmpl/tutor|
    |mvn://org.rascalmpl--rascal--1.0.0/src/org/rascalmpl/typepal|
    |mvn://org.rascalmpl--rascal--1.0.0/src/org/rascalmpl/compiler|
    |file:///C:/Users/sung-/Desktop/a/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-1.0.0/assets/jars/rascal-lsp.jar!/|

Suggested implementation by Jurgen

REPLs created for non-rascal projects

Approach: No non-std source folders of rascal are added to the module path. The rationale is that "normal" users don't need tutor, typepal, and compiler, so it's unnecessary (perhaps even confusing) to make them accessible in the REPL.

If a REPL is created for project a in VS Code, and rascal is open in the workspace, then:

Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/a/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-1.0.0/assets/jars/rascal-lsp.jar!/|

If a REPL is created for project a in VS Code, and rascal isn't open in the workspace, then:

Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/a/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-1.0.0/assets/jars/rascal-lsp.jar!/|

I.e., Whether or not rascal is open in the workspace has no impact on the module path of REPLs created for "normal" projects.

REPLs created for rascal

Approach: All non-std source folders of rascal are added to the module path.

Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/rascal/src/org/rascalmpl/tutor|
    |file:///C:/Users/sung-/Desktop/rascal/src/org/rascalmpl/typepal|
    |file:///C:/Users/sung-/Desktop/rascal/src/org/rascalmpl/compiler|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar!/|

@@ -683,12 +701,16 @@ private static void addLibraryToSourcePath(URIResolverRegistry reg, IListWriter
}
}

if (!foundSrc) {
if (!foundSrc && !projectName.equals("rascal")) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this extra condition needed?

rascal has three source roots:

  • src/org/rascalmpl/library
  • test/org/rascalmpl/benchmark
  • test/org/rascalmpl/test/data

The test/** roots aren't normally* packaged in the jar, though, so foundSrc becomes false in the previous loop, and the jar root is unnecessarily appended (which may look confusing to the user).

Before this PR, this code was never reached (in the case of rascal) due to an early return (see the removed code in the diff, lines 666-671 in the old file), so it wasn't an issue. After this PR, the early return is gone, so the extra condition is needed here to avoid the append.

(*) I've made changes to pom.xml in this PR to package all source roots, but that's just for testing and probably will be reverted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm confused, but they shouldn't be packaged in the jar (as that is what maven defines), but still show up in the search path of the interpreter?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's right. We will also be having more new source locations shortly:

  • src/org/rascalmpl/tutor
  • src/org/rascalmp/typepal
  • src/org/rascalmpl/compiler

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm confused, but they shouldn't be packaged in the jar (as that is what maven defines)

Correct, the test/** source roots aren't packaged in the jar.

but still show up in the search path of the interpreter?

Per line 689, the source roots to be included in the path config aren't taken from the jar but from RASCAL.MF:

for (String src : manifest.getSourceRoots(jar)) {

Copy link
Member

@DavyLandman DavyLandman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, how about you @jurgenvinju ?

// Thus, Rascal modules and Java classes of `rascal` inside `std` are
// guaranteed to be consistently loaded from the same version.
try {
srcsWriter.append(URIUtil.rootLocation("std"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way to not use std ? Or is there no way to figure out what's the rascal.jar that's on the class path?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible to get the loc of the current rascal jar using PathConfig.getCurrentRascalRuntime(), however it's best to use std:// since the .tpl files for the standard library will be containing those references. So for interpreter stacktraces and debugging information and such to line up with the information that the summary for the LSP uses, we should also use std://

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's just that for the end user, it's unclear where std came from. it would have been nice to show: hey, it came from.../vscode-extension/.../rascal.jar or whereever. I like the explicitness of that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we add std:/// to the module path, but we print the physical location in the terminal? Like this:

Module paths:
    |std:///| at |file:///C:/Users/sung-/Desktop/rascal3/rascal/target/classes|
    |mvn://org.rascalmpl--rascal--0.40.8-REPOSITORY/test/org/rascalmpl/benchmark|
    |mvn://org.rascalmpl--rascal--0.40.8-REPOSITORY/test/org/rascalmpl/test/data|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/typepal/src|

It's only a few extra code in printInterpreterConfigurationStatus (prototyped the changes already, but not committed yet; let's first (dis)agree).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be fine with that.

// The project we depend on is available in the current workspace.
// so we configure for using the current state of that project.
PathConfig childConfig = fromSourceProjectRascalManifest(projectLoc, mode);

switch (mode) {
case INTERPRETER:
srcsWriter.appendAll(childConfig.getSrcs());
libsWriter.append(childConfig.getBin());
if (dep != rascalProject) { // Never load Java classes from a non-current `rascal`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what fails if you do load java classes from a rascal project? as in, the class loader will most likely ignore them? but it has less special cases to this code?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens is that there will be two sources for all runtime classes including vallang and the interpreter and the library components written in Java. Creating new classes might work while adding or changing methods will not. Most likely if the two versions start to become different there will be ClassNotFound and such exceptions thrown by the JavaBridge.

What I find most disturbing is that it becomes much less transparant what the linkage is between Rascal code and Java code to the programmer.

One of the consequences of loading from the latest target folder of the rascal project is failing to bootstrap the tutor due to the above exceptions. Also many tests will fail.

@@ -683,12 +701,16 @@ private static void addLibraryToSourcePath(URIResolverRegistry reg, IListWriter
}
}

if (!foundSrc) {
if (!foundSrc && !projectName.equals("rascal")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm confused, but they shouldn't be packaged in the jar (as that is what maven defines), but still show up in the search path of the interpreter?

@sungshik sungshik requested a review from jurgenvinju December 17, 2024 13:39
@sungshik sungshik marked this pull request as ready for review December 17, 2024 13:39
@jurgenvinju
Copy link
Member

Java classes of rascal, regardless of inside/outside std, are loaded from the current rascal.

I'm not completely clear on what this sentence means. "current rascal" is supposed to mean the released rascal jar that we are currently running, and not the current source code project named "rascal". Is this right?

Copy link
Member

@jurgenvinju jurgenvinju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is very nice and will work great for the people developing the compiler code, tutor code and typepal code that will be part of the rascal project.

There is one case that we are not covering yet. If a project depends on a rascal jar via the pom, and the rascal project is open in the workspace, then currently the source code of the compiler, tutor, and typepal, benchmarks and testdata will be added to the interpreter's source path for the current not-rascal project.

I think we need to plug that leak otherwise all rascal projects will be flooded with lots and lots of unnecessary modules. Only |std://| should be on the path for a project that depends on rascal.

Also watch out for double dependencies on |std:///|. That makes the interpreter much slower when modules are imported with a typo or which don't exist yet.

@jurgenvinju
Copy link
Member

jurgenvinju commented Dec 17, 2024

With respect to generating documentation for the rascal project, we might need some more thinking. However, that can be solved in the rascal-maven-plugin Java code perhaps? There is it important that the tutor can execute new Java functions while runing rascal-shell repl simulations, so we should have the "inverted" configuration. The only way I can think of doing that is to let the maven plugin start a new VM with vallang and the rascal target folder on its classpath.

So while we are thinking about that, for the current PR please be adviced that mvn rascal:tutor will fail when/after java methods and their classes are added, edited or removed.

@jurgenvinju
Copy link
Member

I saw this, is it out of date?

Create REPL in rascal

Rascal 0.40.8-EXTENSION
Rascal-lsp Unknown
Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/rascal/test/org/rascalmpl/benchmark|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/rascal/test/org/rascalmpl/test/data|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar!/|
JVM library classpath:
    |file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal.jar|
    |mvn://org.rascalmpl--rascal-p2-dependencies-repackaged--0.6.0|
    |mvn://junit--junit--4.13.2|
    ...
    |mvn://com.ibm.icu--icu4j--74.2|
    |file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar|
    |project://rascal/target/classes|

The latter |project://rascal/target/classes| should not be there. It should be purely this one: |file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal.jar|

@jurgenvinju
Copy link
Member

jurgenvinju commented Dec 17, 2024

Also, as the rascal.jar shades all of its dependencies, they should not be taken from the pom.xml. In fact the only thing on the classpath should be the rascal.jar from the current installation. So these dependencies should not be added if we are configuring for the rascal project itself:

mvn://org.rascalmpl--rascal-p2-dependencies-repackaged--0.6.0|
    |mvn://junit--junit--4.13.2|
    ...
    |mvn://com.ibm.icu--icu4j--74.2|

This would make actual dependencies on jar versions more transparant, and also prevent possible ClassNotFound exceptions etc, by removing duplicates from the classpath.

Copy link
Contributor Author

@sungshik sungshik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Responses to comments by Davy and Jurgen

// Thus, Rascal modules and Java classes of `rascal` inside `std` are
// guaranteed to be consistently loaded from the same version.
try {
srcsWriter.append(URIUtil.rootLocation("std"));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we add std:/// to the module path, but we print the physical location in the terminal? Like this:

Module paths:
    |std:///| at |file:///C:/Users/sung-/Desktop/rascal3/rascal/target/classes|
    |mvn://org.rascalmpl--rascal--0.40.8-REPOSITORY/test/org/rascalmpl/benchmark|
    |mvn://org.rascalmpl--rascal--0.40.8-REPOSITORY/test/org/rascalmpl/test/data|
    |file:///C:/Users/sung-/Desktop/rascal-which-version/projects/typepal/src|

It's only a few extra code in printInterpreterConfigurationStatus (prototyped the changes already, but not committed yet; let's first (dis)agree).

@@ -535,15 +545,17 @@ public static PathConfig fromSourceProjectRascalManifest(ISourceLocation manifes
}

if (libProjectName != null) {
if (reg.exists(projectLoc) && dep != rascalProject) {
if (reg.exists(projectLoc)) {
Copy link
Contributor Author

@sungshik sungshik Dec 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: I just re-read your other comment in more detail, and I think it already confirms my understand of what I thought you meant is correct.

Hm, good question! I think you're right. But, I'll try to rephrase your point with some examples to see if I really understand. It's a bit of a lengthy response, but I need to make sure I'm not going to implement the wrong thing 😉.

Suppose, post-merge, the rascal project has the following source folders (names adopted from another comment by Jurgen):

  • src/org/rascalmpl/tutor
  • src/org/rascalmpl/typepal
  • src/org/rascalmpl/compiler

Current implementation of this PR

Approach: All non-std source folders of rascal are added to the module path.

If a REPL is created for project a in VS Code, and rascal is open in the workspace, then:

Module paths:
    |std:///|
    |project://rascal/src/org/rascalmpl/tutor|
    |project://rascal/src/org/rascalmpl/typepal|
    |project://rascal/src/org/rascalmpl/compiler|
    |file:///C:/Users/sung-/Desktop/a/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-1.0.0/assets/jars/rascal-lsp.jar!/|

If a REPL is created for project a in VS Code, and rascal isn't open in the workspace, then:

Module paths:
    |std:///|
    |mvn://org.rascalmpl--rascal--1.0.0/src/org/rascalmpl/tutor|
    |mvn://org.rascalmpl--rascal--1.0.0/src/org/rascalmpl/typepal|
    |mvn://org.rascalmpl--rascal--1.0.0/src/org/rascalmpl/compiler|
    |file:///C:/Users/sung-/Desktop/a/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-1.0.0/assets/jars/rascal-lsp.jar!/|

Suggested implementation by Jurgen

REPLs created for non-rascal projects

Approach: No non-std source folders of rascal are added to the module path. The rationale is that "normal" users don't need tutor, typepal, and compiler, so it's unnecessary (perhaps even confusing) to make them accessible in the REPL.

If a REPL is created for project a in VS Code, and rascal is open in the workspace, then:

Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/a/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-1.0.0/assets/jars/rascal-lsp.jar!/|

If a REPL is created for project a in VS Code, and rascal isn't open in the workspace, then:

Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/a/src|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-1.0.0/assets/jars/rascal-lsp.jar!/|

I.e., Whether or not rascal is open in the workspace has no impact on the module path of REPLs created for "normal" projects.

REPLs created for rascal

Approach: All non-std source folders of rascal are added to the module path.

Module paths:
    |std:///|
    |file:///C:/Users/sung-/Desktop/rascal/src/org/rascalmpl/tutor|
    |file:///C:/Users/sung-/Desktop/rascal/src/org/rascalmpl/typepal|
    |file:///C:/Users/sung-/Desktop/rascal/src/org/rascalmpl/compiler|
    |jar+file:///C:/Users/sung-/.vscode/extensions/usethesource.rascalmpl-0.12.0-head/assets/jars/rascal-lsp.jar!/|

@@ -683,12 +701,16 @@ private static void addLibraryToSourcePath(URIResolverRegistry reg, IListWriter
}
}

if (!foundSrc) {
if (!foundSrc && !projectName.equals("rascal")) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm confused, but they shouldn't be packaged in the jar (as that is what maven defines)

Correct, the test/** source roots aren't packaged in the jar.

but still show up in the search path of the interpreter?

Per line 689, the source roots to be included in the path config aren't taken from the jar but from RASCAL.MF:

for (String src : manifest.getSourceRoots(jar)) {

@sungshik
Copy link
Contributor Author

Java classes of rascal, regardless of inside/outside std, are loaded from the current rascal.

I'm not completely clear on what this sentence means. "current rascal" is supposed to mean the released rascal jar that we are currently running, and not the current source code project named "rascal". Is this right?

Correct. It's the thing returned by resolveCurrentRascalRuntimeJar.

@sungshik
Copy link
Contributor Author

Thank you, @jurgenvinju, for your detailed comments 🙂. I think I addressed most of them, except three, which I'll summarize here:

  1. Generating documentation: A special path config is needed to make sure tutor code can execute new Java classes in the REPL.
  2. Duplicate libs on the class path: When a REPL is created for rascal, both the deployed jar and the target folder of the open project are on the class path (in that order). Only the deployed jar should be there.
  3. Rascal's own dependencies on the class path: Better to not put Rascal's own dependencies on the class path, because it's shading them anyway.

I think I'd prefer to address these issues in separate PRs, as they're not entirely related to std (what this PR was intended to be about). My proposal is to do one PR for point 1, and one PR for points 2+3 (which I'll start working on immediately after the current PR). So, the plan would be:

  • Finish this PR by fixing the remaining issue about omitting tutor, typepal, and compiler from module path
  • Prepare new PR for class path fixes (issues 2+3)
  • Prepare new PR for tutor fixes (issue 1)

@jurgenvinju
Copy link
Member

Excellent! I think PR 1 is only possible from a combination of the project here (with the tutor merged here) and the rascal-maben-plugin (to start a nested JVM process with the right Classpath).

Note that the current main head does not work anymore in the rascal-maven-plugin context. @rodinaarssen and I are looking to fix that shortly.

@sungshik
Copy link
Contributor Author

I was updating this branch to implement Jurgen's suggestions, but then I realized it can be done with much fewer changes relative to the base branch. So, I prepared a new PR:

I'll keep the "attempt 1"-PR open for now, but please have a look at that other PR for the latest version of this work. The first comment of that PR briefly explains the differences between the PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants