Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/org/rascalmpl/exceptions/RuntimeExceptionFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ public class RuntimeExceptionFactory {
// NotImplemented
public static final Type ParseError = TF.constructor(TS, Exception, "ParseError", TF.sourceLocationType(), "location");

// this comes from lang::json::IO
public static final Type NoOffsetParseError = TF.constructor(TS, Exception, "NoOffsetParseError", TF.sourceLocationType(), "location", TF.integerType(), "line", TF.integerType(), "column");

public static final Type PathNotFound = TF.constructor(TS,Exception,"PathNotFound",TF.sourceLocationType(), "location");

public static final Type PermissionDenied = TF.constructor(TS,Exception,"PermissionDenied",TF.stringType(), "message");
Expand Down Expand Up @@ -684,7 +687,12 @@ public static Throw jsonParseError(ISourceLocation loc, String cause, String pat
.asWithKeywordParameters().setParameter("path", VF.string(path)));
}


public static Throw jsonParseError(ISourceLocation file, int line, int col, String cause, String path) {
return new Throw(VF.constructor(NoOffsetParseError, file, VF.integer(line), VF.integer(col))
.asWithKeywordParameters().setParameter("reason", VF.string(cause))
.asWithKeywordParameters().setParameter("path", VF.string(path)));
}

public static Throw parseError(ISourceLocation loc, AbstractAST ast, StackTrace trace) {
return new Throw(VF.constructor(ParseError, loc), ast != null ? ast.getLocation() : null, trace);
}
Expand Down Expand Up @@ -793,4 +801,6 @@ public static Throw parseErrorRecovery(IValue trigger, ISourceLocation loc) {
public static Throw parseErrorRecoveryNoSuchField(String name, ISourceLocation loc) {
return new Throw(VF.constructor(ParseErrorRecovery, VF.constructor(NoSuchField, VF.string(name)), loc));
}


}
76 changes: 38 additions & 38 deletions src/org/rascalmpl/library/lang/json/IO.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
*
* Contributors:
*
* * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI * Mark Hills - Mark.Hills@cwi.nl (CWI) * Arnold
* Lankamp - Arnold.Lankamp@cwi.nl * Bert Lisser - Bert.Lisser@cwi.nl
* * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
* * Mark Hills - Mark.Hills@cwi.nl (CWI)
* * Arnold - Lankamp - Arnold.Lankamp@cwi.nl
* * Bert Lisser - Bert.Lisser@cwi.nl
*******************************************************************************/
package org.rascalmpl.library.lang.json;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
Expand All @@ -38,7 +41,6 @@
import io.usethesource.vallang.type.Type;
import io.usethesource.vallang.type.TypeStore;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

public class IO {
Expand All @@ -51,63 +53,55 @@ public IO(IRascalValueFactory values, IRascalMonitor monitor) {
this.monitor = monitor;
}

public IValue readJSON(IValue type, ISourceLocation loc, IString dateTimeFormat, IBool lenient, IBool trackOrigins,
IFunction parsers, IMap nulls, IBool explicitConstructorNames, IBool explicitDataTypes) {
private IValue doReadJSON(Reader in,
IValue type, ISourceLocation loc, IString dateTimeFormat, IBool lenient, IBool trackOrigins,
IFunction parsers, IMap nulls, IBool explicitConstructorNames, IBool explicitDataTypes) throws IOException {

TypeStore store = new TypeStore();
Type start = new TypeReifier(values).valueToType((IConstructor) type, store);

if (parsers.getType() instanceof ReifiedType && parsers.getType().getTypeParameters().getFieldType(0).isTop()) {
// ignore the default parser
parsers = null;
}

try (JsonReader in = new JsonReader(URIResolverRegistry.getInstance().getCharacterReader(loc))) {
in.setLenient(lenient.getValue());
try {
return new JsonValueReader(values, store, monitor, loc)
.setCalendarFormat(dateTimeFormat.getValue())
.setParsers(parsers)
.setNulls(unreify(nulls))
.setExplicitConstructorNames(explicitConstructorNames.getValue())
.setExplicitDataTypes(explicitDataTypes.getValue())
.setTrackOrigins(trackOrigins.getValue())
.read(in, start);
}
catch (IOException e) {
throw RuntimeExceptionFactory.io(e);
.setCalendarFormat(dateTimeFormat.getValue())
.setLenient(lenient.getValue())
.setParsers(parsers)
.setNulls(unreify(nulls))
.setExplicitConstructorNames(explicitConstructorNames.getValue())
.setExplicitDataTypes(explicitDataTypes.getValue())
.setTrackOrigins(trackOrigins.getValue())
.read(in, start);
}
catch (NullPointerException e) {
throw RuntimeExceptionFactory.io("NPE in error handling code");
}
}

public IValue readJSON(
IValue type, ISourceLocation loc, IString dateTimeFormat, IBool lenient, IBool trackOrigins,
IFunction parsers, IMap nulls, IBool explicitConstructorNames, IBool explicitDataTypes) {

private Map<Type, IValue> unreify(IMap nulls) {
var tr = new TypeReifier(values);
return nulls.stream().map(t -> (ITuple) t)
.collect(Collectors.toMap(t -> tr.valueToType((IConstructor) t.get(0)), t -> t.get(1)));
try (Reader in = URIResolverRegistry.getInstance().getCharacterReader(loc)) {
return doReadJSON(in, type, loc, dateTimeFormat, lenient, trackOrigins, parsers, nulls, explicitConstructorNames, explicitDataTypes);
}
catch (IOException e) {
throw RuntimeExceptionFactory.io(e);
}
}

public IValue parseJSON(IValue type, IString src, IString dateTimeFormat, IBool lenient, IBool trackOrigins,
IFunction parsers, IMap nulls, IBool explicitConstructorNames, IBool explicitDataTypes) {
TypeStore store = new TypeStore();
Type start = new TypeReifier(values).valueToType((IConstructor) type, store);

try (JsonReader in = new JsonReader(new StringReader(src.getValue()))) {
in.setLenient(lenient.getValue());
return new JsonValueReader(values, store, monitor,null)
.setCalendarFormat(dateTimeFormat.getValue())
.setParsers(parsers)
.setNulls(unreify(nulls))
.setTrackOrigins(trackOrigins.getValue())
.setExplicitConstructorNames(explicitConstructorNames.getValue())
.setExplicitDataTypes(explicitDataTypes.getValue())
.read(in, start);

try (Reader in = new StringReader(src.getValue())) {
return doReadJSON(in, type, null, dateTimeFormat, lenient, trackOrigins, parsers, nulls, explicitConstructorNames, explicitDataTypes);
}
catch (IOException e) {
throw RuntimeExceptionFactory.io(e);
}
catch (NullPointerException e) {
throw RuntimeExceptionFactory.io("NPE");
}
}

public void writeJSON(ISourceLocation loc, IValue value, IBool unpackedLocations, IString dateTimeFormat,
Expand Down Expand Up @@ -162,4 +156,10 @@ public IString asJSON(IValue value, IBool unpackedLocations, IString dateTimeFor
throw RuntimeExceptionFactory.io(e);
}
}

private Map<Type, IValue> unreify(IMap nulls) {
var tr = new TypeReifier(values);
return nulls.stream().map(t -> (ITuple) t)
.collect(Collectors.toMap(t -> tr.valueToType((IConstructor) t.get(0)), t -> t.get(1)));
}
}
9 changes: 8 additions & 1 deletion src/org/rascalmpl/library/lang/json/IO.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,14 @@ import Exception;
* `cause` is a factual diagnosis of what was expected at that position, versus what was found.
* `path` is a path query string into the JSON value from the root down to the leaf where the error was detected.
}
data RuntimeException(str cause="", str path="");
@benefits{
* ((NoOffsetParseError)) is for when accurate offset tracking is turned off. Typically this is _on_
even if `trackOrigins=false`, when we call the json parsers from Rascal.
}
data RuntimeException(str cause="", str path="")
= ParseError(loc location)
| NoOffsetParseError(loc location, int line, int column)
;

private str DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd\'T\'HH:mm:ssZ";

Expand Down
Loading
Loading