Skip to content

Commit

Permalink
Can use explicitConstructors and explicitTypes while reading JSON bac…
Browse files Browse the repository at this point in the history
…k as well to improve constructor and type selection accuracy
  • Loading branch information
jurgenvinju committed Sep 12, 2023
1 parent d86c683 commit 4cabf0c
Showing 1 changed file with 45 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.rascalmpl.debug.IRascalMonitor;
import org.rascalmpl.uri.URIUtil;
Expand Down Expand Up @@ -59,6 +60,8 @@ public class JsonValueReader {
private VarHandle posHandler;
private VarHandle lineHandler;
private VarHandle lineStartHandler;
private boolean explicitConstructorNames;
private boolean explicitDataTypes;

/**
* @param vf factory which will be used to construct values
Expand Down Expand Up @@ -105,6 +108,17 @@ protected SimpleDateFormat initialValue() {
return this;
}

public JsonValueReader setExplicitConstructorNames(boolean value) {
this.explicitConstructorNames = value;
return this;
}

public JsonValueReader setExplicitDataTypes(boolean value) {
this.explicitDataTypes = value;
return this;
}


/**
* Read and validate a Json stream as an IValue
* @param in json stream
Expand Down Expand Up @@ -495,7 +509,37 @@ public IValue visitAbstractData(Type type) throws IOException {

assert in.peek() == JsonToken.BEGIN_OBJECT;

Set<Type> alternatives = store.lookupAlternatives(type);
Set<Type> alternatives = null;

// use explicit information in the JSON to select and filter constructors from the TypeStore
// we expect always to have the field _constructor before _type.
if (explicitConstructorNames) {
String consLabel = in.nextName();
if ("_constructor".equals(consLabel)) {
String consName = in.nextString();

alternatives = store.lookupConstructors(consName);

if (explicitDataTypes) {
String dtLabel = in.nextName();

if ("_type".equals(dtLabel)) {
String dtValue = in.nextString();
alternatives = alternatives.stream().filter(t -> t.isAbstractData() && t.getName().equals(dtValue)).collect(Collectors.toSet());
}
else {
throw new IOException("Expected _type field but got " + dtLabel);
}
}
}
else {
throw new IOException("Expected _constructor field but got " + consLabel);
}
}
else {
alternatives = store.lookupAlternatives(type);
}

if (alternatives.size() > 1) {
monitor.warning("selecting arbitrary constructor for " + type, vf.sourceLocation(in.getPath()));
}
Expand Down

0 comments on commit 4cabf0c

Please sign in to comment.