Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/error recovery robust field projection #2073

Draft
wants to merge 5 commits into
base: feat/error-recovery
Choose a base branch
from
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
17 changes: 17 additions & 0 deletions src/org/rascalmpl/interpreter/result/ConcreteSyntaxResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
return ResultFactory.bool(Names.name(name).equals(consName), ctx);
}
}

return ResultFactory.bool(false, ctx);
}

Expand Down Expand Up @@ -145,6 +146,22 @@
}
}
}
else if (ProductionAdapter.isError(prod)) {
var eprod = ProductionAdapter.getErrorProd(prod);
int dot = ProductionAdapter.getErrorDot(prod);
IList syms = ProductionAdapter.getSymbols(eprod);
String tmp = Names.name(name);

Check warning on line 153 in src/org/rascalmpl/interpreter/result/ConcreteSyntaxResult.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/result/ConcreteSyntaxResult.java#L150-L153

Added lines #L150 - L153 were not covered by tests

// only look before the dot.
for (int i = 0; i < dot; i++) {
var sym = syms.get(i);

Check warning on line 157 in src/org/rascalmpl/interpreter/result/ConcreteSyntaxResult.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/result/ConcreteSyntaxResult.java#L157

Added line #L157 was not covered by tests
if (SymbolAdapter.isLabel((IConstructor) sym)) {
if (SymbolAdapter.getLabel((IConstructor) sym).equals(tmp)) {
return ResultFactory.bool(true, ctx);

Check warning on line 160 in src/org/rascalmpl/interpreter/result/ConcreteSyntaxResult.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/interpreter/result/ConcreteSyntaxResult.java#L160

Added line #L160 was not covered by tests
}
}
}
}
}
return super.has(name);
}
Expand Down
20 changes: 17 additions & 3 deletions src/org/rascalmpl/values/parsetrees/ProductionAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.rascalmpl.values.parsetrees;

import io.usethesource.vallang.IConstructor;
import io.usethesource.vallang.IInteger;
import io.usethesource.vallang.IList;
import io.usethesource.vallang.IListWriter;
import io.usethesource.vallang.INode;
Expand All @@ -37,10 +38,15 @@
* @return a constructor name if present or null otherwise
*/
public static String getConstructorName(IConstructor tree) {
IConstructor def = getDefined(tree);
if (isDefault(tree)) {
IConstructor def = getDefined(tree);

if (SymbolAdapter.isLabel(def)) {
return SymbolAdapter.getLabel(def);
if (SymbolAdapter.isLabel(def)) {
return SymbolAdapter.getLabel(def);
}
}
else if (isError(tree)) {
return "recovered";

Check warning on line 49 in src/org/rascalmpl/values/parsetrees/ProductionAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/ProductionAdapter.java#L49

Added line #L49 was not covered by tests
}

return null;
Expand Down Expand Up @@ -206,4 +212,12 @@
}
return false;
}

public static int getErrorDot(IConstructor prod) {
return ((IInteger) prod.get("dot")).intValue();

Check warning on line 217 in src/org/rascalmpl/values/parsetrees/ProductionAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/ProductionAdapter.java#L217

Added line #L217 was not covered by tests
}

public static IConstructor getErrorProd(IConstructor prod) {
return (IConstructor) prod.get("prod");

Check warning on line 221 in src/org/rascalmpl/values/parsetrees/ProductionAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/ProductionAdapter.java#L221

Added line #L221 was not covered by tests
}
}
47 changes: 47 additions & 0 deletions src/org/rascalmpl/values/parsetrees/TreeAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.fusesource.jansi.Ansi.Color;
import org.rascalmpl.exceptions.ImplementationError;
import org.rascalmpl.interpreter.utils.LimitedResultWriter;
import org.rascalmpl.values.IRascalValueFactory;
import org.rascalmpl.values.RascalValueFactory;
import org.rascalmpl.values.ValueFactoryFactory;
import org.rascalmpl.values.parsetrees.visitors.TreeVisitor;
Expand Down Expand Up @@ -139,6 +140,9 @@
/**
* This function assumes that getLabeledField does not return null for the same parameters!
*/
// TODO @PieterOlivier I guess we could extend this the way we also extended the getLabeledField.
// if the field is still on the parsed side of the dot then we're fine. Otherwise we could
// think about shifting the dot if we put in correct trees at the right places?
jurgenvinju marked this conversation as resolved.
Show resolved Hide resolved
public static ITree putLabeledField(ITree tree, String field, ITree repl) {
if (isAppl(tree)) {
IConstructor prod = TreeAdapter.getProduction(tree);
Expand Down Expand Up @@ -190,6 +194,28 @@
return null;
}
}
else if (ProductionAdapter.isError(prod)) {
var eprod = ProductionAdapter.getErrorProd(prod);
int dot = ProductionAdapter.getErrorDot(prod);
int index = SymbolAdapter.indexOfLabel(ProductionAdapter.getSymbols(eprod), field);
IList args = getArgs(tree);

Check warning on line 201 in src/org/rascalmpl/values/parsetrees/TreeAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L198-L201

Added lines #L198 - L201 were not covered by tests

if (index != -1) {
if (index < dot) {
// changing the normal part of the tree
return setArgs(tree, args.put(index, repl));

Check warning on line 206 in src/org/rascalmpl/values/parsetrees/TreeAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L206

Added line #L206 was not covered by tests
}
else if (index == dot) {
// extending the accepted part of the tree by one field
eprod = prod.set("prod", IRascalValueFactory.getInstance().integer(dot + 1));
return setProduction(setArgs(tree, args.append(repl)), eprod);

Check warning on line 211 in src/org/rascalmpl/values/parsetrees/TreeAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L210-L211

Added lines #L210 - L211 were not covered by tests
}
else {
// otherwise we return null which indicates the field does not exist.
return null;

Check warning on line 215 in src/org/rascalmpl/values/parsetrees/TreeAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L215

Added line #L215 was not covered by tests
}
}
}
}

return null;
Expand Down Expand Up @@ -266,6 +292,27 @@
return null;
}
}
else if (ProductionAdapter.isError(prod)) {
int dot = ProductionAdapter.getErrorDot(prod);
IConstructor eprod = ProductionAdapter.getErrorProd(prod);
IList syms = ProductionAdapter.getSymbols(eprod);
int index = SymbolAdapter.indexOfLabel(syms, field);

Check warning on line 299 in src/org/rascalmpl/values/parsetrees/TreeAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L296-L299

Added lines #L296 - L299 were not covered by tests

if (index != -1) {
IConstructor sym = (IConstructor) syms.get(index);
sym = SymbolAdapter.stripLabelsAndConditions(sym);

Check warning on line 303 in src/org/rascalmpl/values/parsetrees/TreeAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L302-L303

Added lines #L302 - L303 were not covered by tests

if (dot <= index) {
// we have parsed the field so we can just return it.
// this is a likely scenario
return new FieldResult(sym, (ITree) tree.getArgs().get(index));

Check warning on line 308 in src/org/rascalmpl/values/parsetrees/TreeAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L308

Added line #L308 was not covered by tests
}
else {
// we simply don't have that field yet. too bad.
return null;

Check warning on line 312 in src/org/rascalmpl/values/parsetrees/TreeAdapter.java

View check run for this annotation

Codecov / codecov/patch

src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L312

Added line #L312 was not covered by tests
}
}
}
}

return null;
Expand Down
Loading