Skip to content

Commit

Permalink
added loading of the parser class, but it's not enough because I forg…
Browse files Browse the repository at this point in the history
…ot about the nested classes
  • Loading branch information
jurgenvinju committed Jun 20, 2023
1 parent 5759ad8 commit 7ab7be7
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 11 deletions.
39 changes: 39 additions & 0 deletions src/org/rascalmpl/interpreter/utils/JavaBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*******************************************************************************/
package org.rascalmpl.interpreter.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
Expand All @@ -30,6 +31,7 @@
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;

import org.objectweb.asm.ClassReader;
import org.rascalmpl.ast.Expression;
import org.rascalmpl.ast.FunctionDeclaration;
import org.rascalmpl.ast.KeywordFormal;
Expand All @@ -51,8 +53,10 @@
import org.rascalmpl.interpreter.staticErrors.MissingTag;
import org.rascalmpl.interpreter.staticErrors.NonAbstractJavaFunction;
import org.rascalmpl.interpreter.staticErrors.UndeclaredJavaMethod;
import org.rascalmpl.library.Prelude;
import org.rascalmpl.types.DefaultRascalTypeVisitor;
import org.rascalmpl.types.RascalType;
import org.rascalmpl.uri.URIResolverRegistry;
import org.rascalmpl.util.ListClassLoader;
import org.rascalmpl.values.IRascalValueFactory;
import org.rascalmpl.values.functions.IFunction;
Expand Down Expand Up @@ -108,6 +112,41 @@ public <T> Class<T> compileJava(ISourceLocation loc, String className, String so
return compileJava(loc, className, getClass(), source);
}

public Class<?> loadClass(ISourceLocation loc) throws IOException {
try (InputStream forClassName = URIResolverRegistry.getInstance().getInputStream(loc)) {
ClassReader cr = new ClassReader(forClassName);
String className = cr.getClassName();

Check warning on line 118 in src/org/rascalmpl/interpreter/utils/JavaBridge.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/utils/JavaBridge.java#L116-L118

Added lines #L116 - L118 were not covered by tests

// ad-hoc loader to just get the bytes of _this_ specific file without
// searching in a classpath or anything. It needs access to the parser classes
// as parent.
ClassLoader loader = new ClassLoader(getClass().getClassLoader()) {

Check warning on line 123 in src/org/rascalmpl/interpreter/utils/JavaBridge.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/utils/JavaBridge.java#L123

Added line #L123 was not covered by tests
@Override
protected Class<?> findClass(final String name) throws ClassNotFoundException {
if (!name.equals(className)) {
return super.findClass(name);

Check warning on line 127 in src/org/rascalmpl/interpreter/utils/JavaBridge.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/utils/JavaBridge.java#L127

Added line #L127 was not covered by tests
}
else {
try (InputStream forClass = URIResolverRegistry.getInstance().getInputStream(loc)) {
byte[] bytes = Prelude.consumeInputStream(URIResolverRegistry.getInstance().getInputStream(loc));
return this.defineClass(null, bytes, 0, bytes.length);

Check warning on line 132 in src/org/rascalmpl/interpreter/utils/JavaBridge.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/utils/JavaBridge.java#L130-L132

Added lines #L130 - L132 were not covered by tests
}
catch (IOException e) {
throw new ClassNotFoundException(className);

Check warning on line 135 in src/org/rascalmpl/interpreter/utils/JavaBridge.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/utils/JavaBridge.java#L134-L135

Added lines #L134 - L135 were not covered by tests
}
}
}
};

try {
return (Class<?>) loader.loadClass(className);

Check warning on line 142 in src/org/rascalmpl/interpreter/utils/JavaBridge.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/utils/JavaBridge.java#L142

Added line #L142 was not covered by tests
}
catch (ClassNotFoundException e) {
throw new IOException(e.getMessage(), e);

Check warning on line 145 in src/org/rascalmpl/interpreter/utils/JavaBridge.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/utils/JavaBridge.java#L144-L145

Added lines #L144 - L145 were not covered by tests
}
}
}

public void compileJava(ISourceLocation loc, String className, String source, OutputStream classBytes) {
compileJava(loc, className, getClass(), source, classBytes);
}

Check warning on line 152 in src/org/rascalmpl/interpreter/utils/JavaBridge.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/utils/JavaBridge.java#L151-L152

Added lines #L151 - L152 were not covered by tests
Expand Down
17 changes: 16 additions & 1 deletion src/org/rascalmpl/library/Prelude.java
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,16 @@ public static String consumeInputStream(Reader in) throws IOException {
}
return res.toString();
}

public static byte[] consumeInputStream(InputStream in) throws IOException {
ByteArrayOutputStream res = new ByteArrayOutputStream();
byte[] chunk = new byte[FILE_BUFFER_SIZE];

Check warning on line 1155 in src/org/rascalmpl/library/Prelude.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/library/Prelude.java#L1154-L1155

Added lines #L1154 - L1155 were not covered by tests
int read;
while ((read = in.read(chunk, 0, chunk.length)) != -1) {
res.write(chunk, 0, read);

Check warning on line 1158 in src/org/rascalmpl/library/Prelude.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/library/Prelude.java#L1158

Added line #L1158 was not covered by tests
}
return res.toByteArray();

Check warning on line 1160 in src/org/rascalmpl/library/Prelude.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/library/Prelude.java#L1160

Added line #L1160 was not covered by tests
}

public IValue md5HashFile(ISourceLocation sloc){
try {
Expand Down Expand Up @@ -2337,7 +2347,12 @@ public void storeParsers(IValue start, ISourceLocation saveLocation) {
}

Check warning on line 2347 in src/org/rascalmpl/library/Prelude.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/library/Prelude.java#L2344-L2347

Added lines #L2344 - L2347 were not covered by tests

public IFunction loadParsers(ISourceLocation savedLocation, IBool allowAmbiguity, IBool hasSideEffects, IBool firstAmbiguity, ISet filters) {
return rascalValues.loadParsers(savedLocation, allowAmbiguity, hasSideEffects, firstAmbiguity, filters);
try {
return rascalValues.loadParsers(savedLocation, allowAmbiguity, hasSideEffects, firstAmbiguity, filters);

Check warning on line 2351 in src/org/rascalmpl/library/Prelude.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/library/Prelude.java#L2351

Added line #L2351 was not covered by tests
}
catch (IOException e) {
throw RuntimeExceptionFactory.io(e.getMessage());

Check warning on line 2354 in src/org/rascalmpl/library/Prelude.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/library/Prelude.java#L2353-L2354

Added lines #L2353 - L2354 were not covered by tests
}
}

// REFLECT -- copy in {@link PreludeCompiled}
Expand Down
3 changes: 2 additions & 1 deletion src/org/rascalmpl/values/IRascalValueFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,9 @@ default void storeParsers(IValue start, ISourceLocation saveLocation) throws IOE

/**
* Reverse of storeParsers and with the same effect as the {@see parsers} method.
* @throws IOException
*/
default IFunction loadParsers(ISourceLocation saveLocation, IBool allowAmbiguity, IBool hasSideEffects, IBool firstAmbiguity, ISet filters) {
default IFunction loadParsers(ISourceLocation saveLocation, IBool allowAmbiguity, IBool hasSideEffects, IBool firstAmbiguity, ISet filters) throws IOException {
throw new UnsupportedOperationException("This Rascal value factory does not support a parser generator that can restore parsers from disk." + getClass());

Check warning on line 127 in src/org/rascalmpl/values/IRascalValueFactory.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/IRascalValueFactory.java#L127

Added line #L127 was not covered by tests
}
}
40 changes: 31 additions & 9 deletions src/org/rascalmpl/values/RascalFunctionValueFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,6 @@ private Class<IGTD<IConstructor, ITree, ISourceLocation>> generateParser(IMap gr
}
}

private void writeParsers(IMap grammar, ISourceLocation target) throws IOException {
try {
getParserGenerator().writeNewParser(new NullRascalMonitor(), URIUtil.rootLocation("parser-generator"), "$GENERATED_PARSER$" + Math.abs(grammar.hashCode()), grammar, target);
}
catch (ExceptionInInitializerError e) {
throw new ImplementationError(e.getMessage(), e);
}
}

protected Class<IGTD<IConstructor, ITree, ISourceLocation>> getParserClass(IMap grammar) {
return parserCache.get(grammar);
}
Expand Down Expand Up @@ -271,6 +262,37 @@ public void storeParsers(IValue reifiedGrammar, ISourceLocation saveLocation) th
getParserGenerator().writeNewParser(new NullRascalMonitor(), URIUtil.rootLocation("parser-generator"), "$GENERATED_PARSER$" + Math.abs(grammar.hashCode()), grammar, saveLocation);
}

Check warning on line 263 in src/org/rascalmpl/values/RascalFunctionValueFactory.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/RascalFunctionValueFactory.java#L261-L263

Added lines #L261 - L263 were not covered by tests

@Override
public IFunction loadParsers(ISourceLocation saveLocation, IBool allowAmbiguity, IBool hasSideEffects,IBool firstAmbiguity, ISet filters) throws IOException {
RascalTypeFactory rtf = RascalTypeFactory.getInstance();
TypeFactory tf = TypeFactory.getInstance();

Check warning on line 268 in src/org/rascalmpl/values/RascalFunctionValueFactory.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/RascalFunctionValueFactory.java#L267-L268

Added lines #L267 - L268 were not covered by tests

// here the return type is parametrized and instantiated when the parser function is called with the
// given start non-terminal:
Type parameterType = tf.parameterType("U", RascalValueFactory.Tree);

Check warning on line 272 in src/org/rascalmpl/values/RascalFunctionValueFactory.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/RascalFunctionValueFactory.java#L272

Added line #L272 was not covered by tests

Type functionType = tf.functionType(parameterType,
tf.tupleType(rtf.reifiedType(parameterType), tf.valueType(), tf.sourceLocationType()),
tf.tupleEmpty());

Check warning on line 276 in src/org/rascalmpl/values/RascalFunctionValueFactory.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/RascalFunctionValueFactory.java#L274-L276

Added lines #L274 - L276 were not covered by tests



final Class<IGTD<IConstructor, ITree, ISourceLocation>> parser
= (Class<IGTD<IConstructor, ITree, ISourceLocation>>) ctx.getEvaluator()
.__getJavaBridge().loadClass(saveLocation);

Check warning on line 282 in src/org/rascalmpl/values/RascalFunctionValueFactory.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/RascalFunctionValueFactory.java#L280-L282

Added lines #L280 - L282 were not covered by tests

AbstractAST current = ctx.getCurrentAST();

Check warning on line 284 in src/org/rascalmpl/values/RascalFunctionValueFactory.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/RascalFunctionValueFactory.java#L284

Added line #L284 was not covered by tests
ISourceLocation caller = current != null ? current.getLocation() : URIUtil.rootLocation("unknown");

return function(

Check warning on line 287 in src/org/rascalmpl/values/RascalFunctionValueFactory.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/RascalFunctionValueFactory.java#L287

Added line #L287 was not covered by tests
functionType,
new ParametrizedParseFunction(() -> getParserGenerator(),

Check warning on line 289 in src/org/rascalmpl/values/RascalFunctionValueFactory.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/RascalFunctionValueFactory.java#L289

Added line #L289 was not covered by tests
this,
caller,
parser,
allowAmbiguity, hasSideEffects, firstAmbiguity, filters));
}

/**
* This function mimicks `parsers(#start[Module]) inside lang::rascal::\syntax::Rascal.
* so it produces a parse function for the Rascal language, where non-terminal is the
Expand Down

0 comments on commit 7ab7be7

Please sign in to comment.