Skip to content

Commit

Permalink
rewrote the use of maven libraries for the library search path in Pat…
Browse files Browse the repository at this point in the history
…hConfig
  • Loading branch information
jurgenvinju committed Jun 28, 2023
1 parent d97d5a3 commit dac4a0e
Showing 1 changed file with 93 additions and 81 deletions.
174 changes: 93 additions & 81 deletions src/org/rascalmpl/library/util/PathConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
Expand All @@ -18,8 +19,10 @@

import org.rascalmpl.interpreter.Configuration;
import org.rascalmpl.interpreter.utils.RascalManifest;
import org.rascalmpl.uri.ILogicalSourceLocationResolver;
import org.rascalmpl.uri.URIResolverRegistry;
import org.rascalmpl.uri.URIUtil;
import org.rascalmpl.uri.libraries.RascalLibraryURIResolver;
import org.rascalmpl.values.IRascalValueFactory;
import org.rascalmpl.values.ValueFactoryFactory;

Expand Down Expand Up @@ -455,26 +458,45 @@ public static PathConfig fromSourceProjectRascalManifest(ISourceLocation manifes
Set<String> loaderSchemes = reg.getRegisteredClassloaderSchemes();
IRascalValueFactory vf = IRascalValueFactory.getInstance();
String projectName = manifest.getProjectName(manifestRoot);
Set<String> libNames = new HashSet<>();
IListWriter libsWriter = vf.listWriter();
IListWriter srcsWriter = vf.listWriter();
IListWriter classloaders = vf.listWriter();
Map<String, ISourceLocation> mavenLibs = new HashMap<>();

if (!projectName.equals("rascal")) {
// always add the standard library but not for the project named "rascal"
// which contains the source of the standard library
libsWriter.append(URIUtil.correctLocation("lib", "rascal", ""));
}

// target classes always go first
ISourceLocation target = URIUtil.correctLocation("target", projectName, "/");
classloaders.append(target);

// for the Rascal run-time
classloaders.append(URIUtil.correctLocation("system", "", ""));

IList mavenClasspath = getPomXmlCompilerClasspath(manifestRoot);

// the dependencies in the back
classloaders.appendAll(mavenClasspath);

// this collects Rascal libraries we can find in maven dependencies
for (IValue elem : mavenClasspath) {
ISourceLocation dep = (ISourceLocation) elem;
String libProjectName = manifest.getManifestProjectName(manifest.manifest(dep));

if (libProjectName != null) {
mavenLibs.put(libProjectName, RascalManifest.jarify(dep));
}
}

for (String lib : manifest.getRequiredLibraries(manifestRoot)) {
try {
ISourceLocation jar = lib.startsWith("|") ? parseSourceLocation(lib) : URIUtil.getChildLocation(manifestRoot, lib);
ISourceLocation projectLoc = URIUtil.correctLocation("project", jar.getAuthority(), "/");

// needed to later filter the pom classpath
if (jar.getScheme().equals("lib")) {
libNames.add(jar.getAuthority());
}
assert jar != null;

if (jar.getScheme().equals("lib") && reg.exists(projectLoc)) {
// library dependency to open peer project in the workspace
Expand All @@ -494,65 +516,36 @@ public static PathConfig fromSourceProjectRascalManifest(ISourceLocation manifes
libsWriter.appendAll(childConfig.getLibs());
classloaders.appendAll(childConfig.getClassloaders());
}
else if (jar != null && reg.exists(jar)) {
// library dependency to something on the JVM's classpath but not to a peer project in the workspace

if (mode == RascalConfigMode.INTERPETER) {
// in interpreter mode we try and find the sources inside of the jar
boolean foundSrc = false;
for (String src : manifest.getSourceRoots(jar)) {
ISourceLocation srcLib = URIUtil.getChildLocation(jar, src);
if (reg.exists(srcLib)) {
srcsWriter.append(srcLib);
foundSrc = true;
}
}

if (!foundSrc) {
// if we could not find source roots, we default to the jar root
srcsWriter.append(jar);
else {
ISourceLocation jarLoc = jar;

if (jar.getScheme().equals("lib")) {
String libraryName = jar.getAuthority();
ISourceLocation libraryLoc = mavenLibs.get(libraryName);

if (libraryLoc != null) {
jarLoc = libraryLoc;
reg.registerLogical(new LibResolverForMavenDependencies(libraryName, jarLoc));
}
}
else if (mode == RascalConfigMode.COMPILER) {
// in compiler mode we expect .tpl and .class files at the root of the jar
libsWriter.append(jar);
}
else {
throw new IOException("unknown configuration mode: " + mode);
}

if (loaderSchemes.contains(jar.getScheme())) {
classloaders.append(jar);
}
}
else if (jar != null && reg.exists(jar)) {
// library dependency to something on the JVM's classpath but not to a peer project in the workspace

if (mode == RascalConfigMode.INTERPETER) {
// in interpreter mode we try and find the sources inside of the jar
boolean foundSrc = false;
for (String src : manifest.getSourceRoots(jar)) {
ISourceLocation srcLib = URIUtil.getChildLocation(jar, src);
if (reg.exists(srcLib)) {
srcsWriter.append(srcLib);
foundSrc = true;
}
}
if (!reg.exists(jarLoc)) {
throw new FileNotFoundException(jarLoc.toString());
}

if (!foundSrc) {
// if we could not find source roots, we default to the jar root
srcsWriter.append(jar);
}
}
else if (mode == RascalConfigMode.COMPILER) {
// in compiler mode we expect .tpl and .class files at the root of the jar
libsWriter.append(jar);
}
else {
throw new IOException("unknown configuration mode: " + mode);
switch (mode) {
case COMPILER:
libsWriter.append(jarLoc);
break;
case INTERPETER:
addLibraryToSourcePath(manifest, reg, srcsWriter, jarLoc);
break;
default:
throw new IOException("unknown configuration mode: " + mode);
}

if (loaderSchemes.contains(jar.getScheme())) {
// if this is not a jar file from the pom, its a new place to find classes
if (jar == jarLoc && loaderSchemes.contains(jar.getScheme())) {
classloaders.append(jar);
}
}
Expand All @@ -571,29 +564,6 @@ else if (mode == RascalConfigMode.COMPILER) {
srcsWriter.append(URIUtil.getChildLocation(manifestRoot, srcName));
}

ISourceLocation target = URIUtil.correctLocation("target", projectName, "/");
classloaders.append(target);

// for the Rascal run-time
classloaders.append(URIUtil.correctLocation("system", "", ""));

IList mavenClasspath = getPomXmlCompilerClasspath(manifestRoot);

for (IValue elem : mavenClasspath) {
ISourceLocation dep = (ISourceLocation) elem;

switch (mode) {
case INTERPETER:
addJarToSearchPath(dep, libNames, srcsWriter);
break;
case COMPILER:
addJarToLibraryPath(dep, libNames, libsWriter);
break;
}
}

classloaders.appendAll(mavenClasspath);

return new PathConfig(
srcsWriter.done(),
libsWriter.done(),
Expand All @@ -603,6 +573,48 @@ else if (mode == RascalConfigMode.COMPILER) {
classloaders.done());
}

public static class LibResolverForMavenDependencies implements ILogicalSourceLocationResolver {
private final String libraryName;
private final ISourceLocation jarLoc;

public LibResolverForMavenDependencies(String libraryName, ISourceLocation jarLoc) {
this.libraryName = libraryName;
this.jarLoc = jarLoc;
}

@Override
public ISourceLocation resolve(ISourceLocation input) throws IOException {
return URIUtil.getChildLocation(jarLoc, input.getPath());
}

@Override
public String scheme() {
return "lib";
}

@Override
public String authority() {
return libraryName;
}
}

private static void addLibraryToSourcePath(RascalManifest manifest, URIResolverRegistry reg, IListWriter srcsWriter,
ISourceLocation jar) {
boolean foundSrc = false;
for (String src : manifest.getSourceRoots(jar)) {
ISourceLocation srcLib = URIUtil.getChildLocation(jar, src);
if (reg.exists(srcLib)) {
srcsWriter.append(srcLib);
foundSrc = true;
}
}

if (!foundSrc) {
// if we could not find source roots, we default to the jar root
srcsWriter.append(jar);
}
}

private static void addJarToSearchPath(ISourceLocation jar, Set<String> libNames, IListWriter srcs) {
ISourceLocation prefix = RascalManifest.jarify(jar);

Expand Down

0 comments on commit dac4a0e

Please sign in to comment.