Skip to content

Instantly share code, notes, and snippets.

@headius
Created May 29, 2024 18:24
Show Gist options
  • Save headius/0bf47e90d121b48293d64e7a513bdc99 to your computer and use it in GitHub Desktop.
Save headius/0bf47e90d121b48293d64e7a513bdc99 to your computer and use it in GitHub Desktop.
diff --git a/core/src/main/java/org/jruby/ParseResult.java b/core/src/main/java/org/jruby/ParseResult.java
index febaa15f82..216450f580 100644
--- a/core/src/main/java/org/jruby/ParseResult.java
+++ b/core/src/main/java/org/jruby/ParseResult.java
@@ -9,6 +9,9 @@ public interface ParseResult {
DynamicScope getDynamicScope();
int getLine();
String getFile();
+ default String getBaseName() {
+ return getFile();
+ }
int getCoverageMode();
Object getAST();
Encoding getEncoding();
diff --git a/core/src/main/java/org/jruby/Ruby.java b/core/src/main/java/org/jruby/Ruby.java
index 9abb22f057..eba2877a2f 100644
--- a/core/src/main/java/org/jruby/Ruby.java
+++ b/core/src/main/java/org/jruby/Ruby.java
@@ -2944,6 +2944,10 @@ public final class Ruby implements Constantizable {
static boolean loaded = false;
public void loadFile(String scriptName, InputStream in, boolean wrap) {
+ loadFile(scriptName, scriptName, in, wrap);
+ }
+
+ public void loadFile(String scriptName, String baseName, InputStream in, boolean wrap) {
IRubyObject self = wrap ? getTopSelf().rbClone() : getTopSelf();
if (!wrap && Options.COMPILE_CACHE_CLASSES.load()) {
@@ -2960,7 +2964,7 @@ public final class Ruby implements Constantizable {
try {
ParseResult parseResult;
context.preNodeEval(self);
- parseResult = getParserManager().parseFile(scriptName, 0, in, setupSourceEncoding(UTF8Encoding.INSTANCE));
+ parseResult = getParserManager().parseFile(scriptName, baseName, 0, in, setupSourceEncoding(UTF8Encoding.INSTANCE));
// toss an anonymous module into the search path
if (wrap) wrapWithModule((RubyBasicObject) self, parseResult);
@@ -2983,6 +2987,10 @@ public final class Ruby implements Constantizable {
}
public void compileAndLoadFile(String filename, InputStream in, boolean wrap) {
+ compileAndLoadFile(filename, filename, in, wrap);
+ }
+
+ public void compileAndLoadFile(String filename, String baseName, InputStream in, boolean wrap) {
IRubyObject self = wrap ? getTopSelf().rbClone() : getTopSelf();
if (!wrap && Options.COMPILE_CACHE_CLASSES.load()) {
@@ -2994,7 +3002,7 @@ public final class Ruby implements Constantizable {
}
}
- ParseResult parseResult = getParserManager().parseFile(filename, 0, in, setupSourceEncoding(UTF8Encoding.INSTANCE));
+ ParseResult parseResult = getParserManager().parseFile(filename, baseName, 0, in, setupSourceEncoding(UTF8Encoding.INSTANCE));
if (wrap) {
wrapWithModule((RubyBasicObject) self, parseResult);
diff --git a/core/src/main/java/org/jruby/ast/RootNode.java b/core/src/main/java/org/jruby/ast/RootNode.java
index e77b9bba90..6972234166 100644
--- a/core/src/main/java/org/jruby/ast/RootNode.java
+++ b/core/src/main/java/org/jruby/ast/RootNode.java
@@ -51,19 +51,29 @@ public class RootNode extends Node implements ParseResult {
private final StaticScope staticScope;
private final Node bodyNode;
private final String file;
+ private final String baseName;
private final int coverageMode;
public RootNode(int line, DynamicScope scope, Node bodyNode, String file) {
- this(line, scope, bodyNode, file, CoverageData.NONE);
+ this(line, scope, bodyNode, file, file, CoverageData.NONE);
+ }
+
+ public RootNode(int line, DynamicScope scope, Node bodyNode, String file, String baseName) {
+ this(line, scope, bodyNode, file, baseName, CoverageData.NONE);
}
public RootNode(int line, DynamicScope scope, Node bodyNode, String file, int coverageMode) {
+ this(line, scope, bodyNode, file, file, coverageMode);
+ }
+
+ public RootNode(int line, DynamicScope scope, Node bodyNode, String file, String baseName, int coverageMode) {
super(line, bodyNode.containsVariableAssignment());
-
+
this.scope = scope;
this.staticScope = scope.getStaticScope();
this.bodyNode = bodyNode;
this.file = file;
+ this.baseName = baseName;
this.coverageMode = coverageMode;
staticScope.setFile(file);
@@ -101,6 +111,10 @@ public class RootNode extends Node implements ParseResult {
return file;
}
+ public String getBaseName() {
+ return baseName;
+ }
+
@Override
public int getCoverageMode() {
return coverageMode;
diff --git a/core/src/main/java/org/jruby/ir/IRScope.java b/core/src/main/java/org/jruby/ir/IRScope.java
index 426829beb9..c612096636 100644
--- a/core/src/main/java/org/jruby/ir/IRScope.java
+++ b/core/src/main/java/org/jruby/ir/IRScope.java
@@ -386,6 +386,10 @@ public abstract class IRScope implements ParseResult {
return getRootLexicalScope().getFile();
}
+ public String getBaseName() {
+ return getRootLexicalScope().getBaseName();
+ }
+
@Deprecated
public int getLineNumber() {
return lineNumber;
diff --git a/core/src/main/java/org/jruby/ir/IRScriptBody.java b/core/src/main/java/org/jruby/ir/IRScriptBody.java
index ed2e23ead4..1f6a4d000c 100644
--- a/core/src/main/java/org/jruby/ir/IRScriptBody.java
+++ b/core/src/main/java/org/jruby/ir/IRScriptBody.java
@@ -7,11 +7,17 @@ import org.jruby.runtime.DynamicScope;
public class IRScriptBody extends IRScope {
private DynamicScope toplevelScope;
private String fileName;
+ private String baseName;
public IRScriptBody(IRManager manager, String sourceName, StaticScope staticScope) {
+ this(manager, sourceName, sourceName, staticScope);
+ }
+
+ public IRScriptBody(IRManager manager, String sourceName, String baseName, StaticScope staticScope) {
super(manager, null, null, 0, staticScope);
this.toplevelScope = null;
this.fileName = sourceName;
+ this.baseName = baseName;
if (staticScope != null) {
staticScope.setIRScope(this);
@@ -55,6 +61,10 @@ public class IRScriptBody extends IRScope {
return fileName;
}
+ public String getBaseName() {
+ return baseName;
+ }
+
public String getId() {
return fileName;
}
diff --git a/core/src/main/java/org/jruby/ir/builder/IRBuilder.java b/core/src/main/java/org/jruby/ir/builder/IRBuilder.java
index 28d99b93f7..4ddaf818bd 100644
--- a/core/src/main/java/org/jruby/ir/builder/IRBuilder.java
+++ b/core/src/main/java/org/jruby/ir/builder/IRBuilder.java
@@ -160,7 +160,7 @@ public abstract class IRBuilder<U, V, W, X, Y, Z> {
public static InterpreterContext buildRoot(IRManager manager, ParseResult rootNode) {
String file = rootNode.getFile();
- IRScriptBody script = new IRScriptBody(manager, file == null ? "(anon)" : file, rootNode.getStaticScope());
+ IRScriptBody script = new IRScriptBody(manager, file == null ? "(anon)" : file, rootNode.getBaseName(), rootNode.getStaticScope());
//System.out.println("Building " + file);
return manager.getBuilderFactory().topIRBuilder(manager, script, rootNode).buildRootInner(rootNode);
diff --git a/core/src/main/java/org/jruby/ir/targets/JVMVisitor.java b/core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
index 47fd91849e..b7588bed39 100644
--- a/core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
+++ b/core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
@@ -133,13 +133,13 @@ public class JVMVisitor extends IRVisitor {
}
public Class compile(IRScope scope, ClassDefiningClassLoader jrubyClassLoader) {
- file = scope.getFile();
+ file = scope.getBaseName();
JVMVisitorMethodContext context = new JVMVisitorMethodContext();
return defineFromBytecode(scope, compileToBytecode(scope, context), jrubyClassLoader);
}
public byte[] compileToBytecode(IRScope scope, JVMVisitorMethodContext context) {
- file = scope.getFile();
+ file = scope.getBaseName();
codegenScope(scope, context);
return code();
}
@@ -163,8 +163,8 @@ public class JVMVisitor extends IRVisitor {
}
public Class defineFromBytecode(IRScope scope, byte[] code, ClassDefiningClassLoader jrubyClassLoader, boolean setScopes) {
- file = scope.getFile();
- Class result = jrubyClassLoader.defineClass(c(JVM.scriptToClass(file)), code);
+ file = scope.getBaseName();
+ Class result = jrubyClassLoader.defineClass(c(JVM.scriptToClass(scope.getFile())), code);
if (setScopes) {
for (Map.Entry<String, StaticScope> entry : staticScopeMap.entrySet()) {
@@ -415,7 +415,7 @@ public class JVMVisitor extends IRVisitor {
Signature signature = signatureFor(script, false);
// Note: no index attached because there should be at most one script body per .class
- jvm.pushscript(this, clsName, script.getFile());
+ jvm.pushscript(this, clsName, script.getBaseName());
defineRunMethod(script, scopeName, scopeField, clsName, signature);
@@ -517,7 +517,7 @@ public class JVMVisitor extends IRVisitor {
protected void emitMethodJIT(IRMethod method, JVMVisitorMethodContext context) {
String clsName = jvm.scriptToClass(method.getFile());
String name = JavaNameMangler.encodeNumberedScopeForBacktrace(method, methodIndex++);
- jvm.pushscript(this, clsName, method.getFile());
+ jvm.pushscript(this, clsName, method.getBaseName());
emitWithSignatures(method, context, name);
@@ -528,7 +528,7 @@ public class JVMVisitor extends IRVisitor {
protected void emitBlockJIT(IRClosure closure, JVMVisitorMethodContext context) {
String clsName = jvm.scriptToClass(closure.getFile());
String name = JavaNameMangler.encodeNumberedScopeForBacktrace(closure, methodIndex++);
- jvm.pushscript(this, clsName, closure.getFile());
+ jvm.pushscript(this, clsName, closure.getBaseName());
emitScope(closure, name, CLOSURE_SIGNATURE, false, true);
@@ -572,7 +572,7 @@ public class JVMVisitor extends IRVisitor {
String name = JavaNameMangler.encodeNumberedScopeForBacktrace(method, methodIndex++);
String clsName = jvm.scriptToClass(method.getFile());
- jvm.pushscript(this, clsName, method.getFile());
+ jvm.pushscript(this, clsName, method.getBaseName());
Signature signature = signatureFor(method, false);
emitScope(method, name, signature, false, true);
diff --git a/core/src/main/java/org/jruby/lexer/ByteListLexerSource.java b/core/src/main/java/org/jruby/lexer/ByteListLexerSource.java
index 8bf8d6270b..44379a7d35 100644
--- a/core/src/main/java/org/jruby/lexer/ByteListLexerSource.java
+++ b/core/src/main/java/org/jruby/lexer/ByteListLexerSource.java
@@ -33,6 +33,11 @@ public class ByteListLexerSource extends LexerSource {
super(sourceName, line, list);
this.completeSource = in;
}
+
+ public ByteListLexerSource(String sourceName, String baseName, int line, ByteList in, RubyArray list) {
+ super(sourceName, baseName, line, list);
+ this.completeSource = in;
+ }
@Override
public Encoding getEncoding() {
diff --git a/core/src/main/java/org/jruby/lexer/LexerSource.java b/core/src/main/java/org/jruby/lexer/LexerSource.java
index 9d273c0c7a..eb27f96c7e 100644
--- a/core/src/main/java/org/jruby/lexer/LexerSource.java
+++ b/core/src/main/java/org/jruby/lexer/LexerSource.java
@@ -47,13 +47,21 @@ public abstract class LexerSource {
// The name of this source (e.g. a filename: foo.rb)
private final String name; // mri: parser_ruby_sourcefile
+ // The base name of the file, excluding the path where it was found (load path, cwd, etc)
+ private final String baseName;
+
// Offset specified where to add to actual offset
private int lineOffset;
protected RubyArray scriptLines;
public LexerSource(String sourceName, int lineOffset, RubyArray scriptLines) {
+ this(sourceName, sourceName, lineOffset, scriptLines);
+ }
+
+ public LexerSource(String sourceName, String baseName, int lineOffset, RubyArray scriptLines) {
this.name = sourceName;
+ this.baseName = baseName;
this.lineOffset = lineOffset;
this.scriptLines = scriptLines;
}
@@ -66,6 +74,10 @@ public abstract class LexerSource {
return name;
}
+ public String getBaseName() {
+ return baseName;
+ }
+
public int getLineOffset() {
return lineOffset;
}
diff --git a/core/src/main/java/org/jruby/lexer/LexingCommon.java b/core/src/main/java/org/jruby/lexer/LexingCommon.java
index 4334ae7426..03dfcd8319 100644
--- a/core/src/main/java/org/jruby/lexer/LexingCommon.java
+++ b/core/src/main/java/org/jruby/lexer/LexingCommon.java
@@ -300,6 +300,10 @@ public abstract class LexingCommon {
return src.getFilename();
}
+ public String getBaseName() {
+ return src.getBaseName();
+ }
+
public int getHeredocIndent() {
return heredoc_indent;
}
diff --git a/core/src/main/java/org/jruby/parser/Parser.java b/core/src/main/java/org/jruby/parser/Parser.java
index 6fd0bce03b..bc7647b1bd 100644
--- a/core/src/main/java/org/jruby/parser/Parser.java
+++ b/core/src/main/java/org/jruby/parser/Parser.java
@@ -37,6 +37,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
+import java.util.Locale;
import org.jcodings.Encoding;
import org.jruby.ParseResult;
@@ -87,11 +88,16 @@ public class Parser {
protected ParseResult parse(String fileName, int lineNumber, InputStream in, Encoding encoding,
DynamicScope existingScope, ParserType type) {
+ return parse(fileName, fileName, lineNumber, in, encoding, existingScope, type);
+ }
+
+ protected ParseResult parse(String fileName, String baseName, int lineNumber, InputStream in, Encoding encoding,
+ DynamicScope existingScope, ParserType type) {
RubyArray list = getLines(type == EVAL, fileName, -1);
if (in instanceof LoadServiceResourceInputStream) {
ByteList source = new ByteList(((LoadServiceResourceInputStream) in).getBytes(), encoding);
- LexerSource lexerSource = new ByteListLexerSource(fileName, lineNumber, source, list);
+ LexerSource lexerSource = new ByteListLexerSource(fileName, baseName, lineNumber, source, list);
return parse(lexerSource, existingScope, type);
} else {
boolean requiresClosing = false;
@@ -263,7 +269,7 @@ public class Parser {
if (printing) whileBody.add(new FCallNode(line, runtime.newSymbol("print"), new ArrayNode(line, dollarUnderscore), null));
- return new RootNode(line, oldRoot.getDynamicScope(), newBody, oldRoot.getFile());
+ return new RootNode(line, oldRoot.getDynamicScope(), newBody, oldRoot.getFile(), oldRoot.getBaseName());
}
}
diff --git a/core/src/main/java/org/jruby/parser/ParserManager.java b/core/src/main/java/org/jruby/parser/ParserManager.java
index 22a8fc100a..2dcf06aae3 100644
--- a/core/src/main/java/org/jruby/parser/ParserManager.java
+++ b/core/src/main/java/org/jruby/parser/ParserManager.java
@@ -111,6 +111,10 @@ public class ParserManager {
* @return the parsed Ruby
*/
public ParseResult parseMainFile(String fileName, int lineNumber, InputStream in, Encoding encoding, DynamicScope scope, ParserType type) {
+ return parseMainFile(fileName, fileName, lineNumber, in, encoding, scope, type);
+ }
+
+ public ParseResult parseMainFile(String fileName, String baseName, int lineNumber, InputStream in, Encoding encoding, DynamicScope scope, ParserType type) {
long nanos = 0;
parserStats.addLoadParse();
@@ -119,7 +123,7 @@ public class ParserManager {
if (RubyInstanceConfig.IR_READING) {
result = loadFileFromIRPersistence(fileName, lineNumber, in, encoding, scope, type);
} else {
- result = parser.parse(fileName, lineNumber, in, encoding, scope, type);
+ result = parser.parse(fileName, baseName, lineNumber, in, encoding, scope, type);
}
if (PARSER_TIMING) parserStats.addParseTime(System.nanoTime() - nanos);
@@ -136,7 +140,11 @@ public class ParserManager {
* @return
*/
public ParseResult parseFile(String fileName, int lineNumber, InputStream in, Encoding encoding) {
- return parseMainFile(fileName, lineNumber, in, encoding, null, NORMAL);
+ return parseFile(fileName, fileName, lineNumber, in, encoding);
+ }
+
+ public ParseResult parseFile(String fileName, String baseName, int lineNumber, InputStream in, Encoding encoding) {
+ return parseMainFile(fileName, baseName, lineNumber, in, encoding, null, NORMAL);
}
private ParseResult loadFileFromIRPersistence(String fileName, int lineNumber, InputStream in, Encoding encoding,
diff --git a/core/src/main/java/org/jruby/parser/RubyParserBase.java b/core/src/main/java/org/jruby/parser/RubyParserBase.java
index a0de2fa602..d2fa25eae0 100644
--- a/core/src/main/java/org/jruby/parser/RubyParserBase.java
+++ b/core/src/main/java/org/jruby/parser/RubyParserBase.java
@@ -502,7 +502,7 @@ public abstract class RubyParserBase {
CoverageData.NONE :
coverageData.getMode();
- return new RootNode(line, result.getScope(), topOfAST, lexer.getFile(), coverageMode);
+ return new RootNode(line, result.getScope(), topOfAST, lexer.getFile(), lexer.getBaseName(), coverageMode);
}
/* MRI: block_append */
diff --git a/core/src/main/java/org/jruby/runtime/load/LibrarySearcher.java b/core/src/main/java/org/jruby/runtime/load/LibrarySearcher.java
index 96500bb034..8c4fd64869 100644
--- a/core/src/main/java/org/jruby/runtime/load/LibrarySearcher.java
+++ b/core/src/main/java/org/jruby/runtime/load/LibrarySearcher.java
@@ -920,9 +920,9 @@ public class LibrarySearcher {
LoadServiceResourceInputStream ris = prepareInputStream(runtime);
if (runtime.getInstanceConfig().getCompileMode().shouldPrecompileAll()) {
- runtime.compileAndLoadFile(scriptName, ris, wrap);
+ runtime.compileAndLoadFile(scriptName, searchName, ris, wrap);
} else {
- runtime.loadFile(scriptName, ris, wrap);
+ runtime.loadFile(scriptName, searchName, ris, wrap);
}
}
@@ -1036,6 +1036,8 @@ public class LibrarySearcher {
return null;
}
+ String baseName = pathMaker.apply(target);
+
if (fullPath.exists()) {
String canonicalPath = fullPath.canonicalPath();
String absolutePath = fullPath.absolutePath();
@@ -1047,7 +1049,7 @@ public class LibrarySearcher {
DebugLog.Resource.logFound(fullPath);
- return new FoundLibrary(target, expandedAbsolute, libraryMaker.apply(target, expandedAbsolute, fullPath));
+ return new FoundLibrary(pathMaker.apply(target), expandedAbsolute, libraryMaker.apply(baseName, expandedAbsolute, fullPath));
}
}
@@ -1055,7 +1057,7 @@ public class LibrarySearcher {
String resolvedName = absolutePath;
- return new FoundLibrary(target, resolvedName, libraryMaker.apply(target, resolvedName, fullPath));
+ return new FoundLibrary(target, resolvedName, libraryMaker.apply(baseName, resolvedName, fullPath));
}
return null;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment