Skip to content
Snippets Groups Projects
Commit 155f8b3c authored by Florian Angerer's avatar Florian Angerer
Browse files

Implemented srcref for block statements.

parent fd4aed3b
No related branches found
No related tags found
No related merge requests found
...@@ -1759,11 +1759,13 @@ public class RSerialize { ...@@ -1759,11 +1759,13 @@ public class RSerialize {
if (outAttrs != null) { if (outAttrs != null) {
SourceSection ss = outAttrs.getSourceReferenceAttributes(); SourceSection ss = outAttrs.getSourceReferenceAttributes();
if (ss != null) { if (ss != null) {
String path = ss.getSource().getURI().getPath(); String path = RSource.getPathInternal(ss.getSource());
REnvironment createSrcfile = RSrcref.createSrcfile(path); if (path != null) {
Object createLloc = RSrcref.createLloc(ss, createSrcfile); REnvironment createSrcfile = RSrcref.createSrcfile(path);
writePairListEntry(RRuntime.R_SRCREF, createLloc); Object createLloc = RSrcref.createLloc(ss, createSrcfile);
writePairListEntry(RRuntime.R_SRCFILE, createSrcfile); writePairListEntry(RRuntime.R_SRCREF, createLloc);
writePairListEntry(RRuntime.R_SRCFILE, createSrcfile);
}
} }
DynamicObject attributes = outAttrs.getExplicitAttributes(); DynamicObject attributes = outAttrs.getExplicitAttributes();
if (attributes != null) { if (attributes != null) {
...@@ -2094,13 +2096,7 @@ public class RSerialize { ...@@ -2094,13 +2096,7 @@ public class RSerialize {
private DynamicObject explicitAttributes; private DynamicObject explicitAttributes;
private SourceSection ss; private SourceSection ss;
OutAttributes(RAttributable obj, SEXPTYPE type) { private OutAttributes(Object obj, SEXPTYPE type) {
explicitAttributes = obj.getAttributes();
initSourceSection(obj, type);
}
OutAttributes(Object obj, SEXPTYPE type) {
if (obj instanceof RAttributable) { if (obj instanceof RAttributable) {
explicitAttributes = ((RAttributable) obj).getAttributes(); explicitAttributes = ((RAttributable) obj).getAttributes();
...@@ -2112,10 +2108,14 @@ public class RSerialize { ...@@ -2112,10 +2108,14 @@ public class RSerialize {
if (type == SEXPTYPE.FUNSXP) { if (type == SEXPTYPE.FUNSXP) {
RFunction fun = (RFunction) obj; RFunction fun = (RFunction) obj;
RSyntaxFunction body = (RSyntaxFunction) fun.getRootNode(); RSyntaxFunction body = (RSyntaxFunction) fun.getRootNode();
SourceSection lazySourceSection = body.getLazySourceSection(); setSourceSection(body);
if (lazySourceSection != RSyntaxNode.LAZY_DEPARSE) { }
ss = lazySourceSection; }
}
private void setSourceSection(RSyntaxElement body) {
SourceSection lazySourceSection = body.getLazySourceSection();
if (lazySourceSection != RSyntaxNode.LAZY_DEPARSE) {
ss = lazySourceSection;
} }
} }
...@@ -2315,7 +2315,6 @@ public class RSerialize { ...@@ -2315,7 +2315,6 @@ public class RSerialize {
@Override @Override
protected Void visit(RSyntaxLookup element) { protected Void visit(RSyntaxLookup element) {
// setSrcrefs(element)
state.setCarAsSymbol(element.getIdentifier()); state.setCarAsSymbol(element.getIdentifier());
return null; return null;
} }
...@@ -2410,7 +2409,27 @@ public class RSerialize { ...@@ -2410,7 +2409,27 @@ public class RSerialize {
private static void serializeFunctionDefinition(State state, RSyntaxFunction function) { private static void serializeFunctionDefinition(State state, RSyntaxFunction function) {
SerializeVisitor visitor = new SerializeVisitor(state); SerializeVisitor visitor = new SerializeVisitor(state);
state.setCar(visitor.visitFunctionFormals(function)); state.setCar(visitor.visitFunctionFormals(function));
state.setCdr(visitor.visitFunctionBody(function)); Object visitFunctionBody = visitor.visitFunctionBody(function);
// convert and attach source section to srcref attribute
if (visitFunctionBody instanceof RAttributable) {
SourceSection lazySourceSection = function.getLazySourceSection();
if (lazySourceSection != null) {
String pathInternal = RSource.getPathInternal(lazySourceSection.getSource());
if (pathInternal != null) {
RAttributable visitFunctionBody2 = (RAttributable) visitFunctionBody;
RList createBlockSrcrefs = RSrcref.createBlockSrcrefs(function);
if (createBlockSrcrefs != null) {
visitFunctionBody2.setAttr(RRuntime.R_SRCREF, createBlockSrcrefs);
visitFunctionBody2.setAttr(RRuntime.R_WHOLE_SRCREF, RSrcref.createLloc(lazySourceSection));
visitFunctionBody2.setAttr(RRuntime.R_SRCFILE, RSrcref.createSrcfile(pathInternal));
}
}
}
}
state.setCdr(visitFunctionBody);
} }
private static Object serializeLanguage(State state, RLanguage lang) { private static Object serializeLanguage(State state, RLanguage lang) {
......
...@@ -18,6 +18,8 @@ import java.nio.file.NoSuchFileException; ...@@ -18,6 +18,8 @@ import java.nio.file.NoSuchFileException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFileAttributes;
import java.util.LinkedList;
import java.util.List;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.Source;
...@@ -25,6 +27,7 @@ import com.oracle.truffle.api.source.SourceSection; ...@@ -25,6 +27,7 @@ import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RIntVector;
import com.oracle.truffle.r.runtime.data.RList;
import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RStringVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
...@@ -32,7 +35,13 @@ import com.oracle.truffle.r.runtime.env.REnvironment; ...@@ -32,7 +35,13 @@ import com.oracle.truffle.r.runtime.env.REnvironment;
import com.oracle.truffle.r.runtime.env.REnvironment.PutException; import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
import com.oracle.truffle.r.runtime.ffi.BaseRFFI; import com.oracle.truffle.r.runtime.ffi.BaseRFFI;
import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode; import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode;
import com.oracle.truffle.r.runtime.nodes.RSyntaxCall;
import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant;
import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction;
import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor;
/** /**
* Utilities for handling R srcref attributes, in particular conversion from {@link Source}, * Utilities for handling R srcref attributes, in particular conversion from {@link Source},
...@@ -103,6 +112,88 @@ public class RSrcref { ...@@ -103,6 +112,88 @@ public class RSrcref {
return createLloc(ss, createSrcfile(path)); return createLloc(ss, createSrcfile(path));
} }
/**
* Creates a block source reference or {@code null} if the function's body is not a block
* statement.<br>
* Srcref for blocks are different in that it is an RList of srcref vectors whereas each element
* corresponds to one syntax call in the block (including the block itself). E.g.
* <p>
* <code> {<br/>
* print('Hello')<br/>
* print(x)<br/>
* }</code>
* </p>
* will result in [[1, 20, 4, 1, 20, 1, 1, 4], [2, 2, 2, 15, 2, 15, 2, 2], [3, 2, 3, 9, 2, 9, 3,
* 3]]
*
* @param function
*/
@TruffleBoundary
public static RList createBlockSrcrefs(RSyntaxFunction function) {
List<Object> blockSrcrefs = new LinkedList<>();
RSyntaxVisitor<Void> v = new RSyntaxVisitor<Void>() {
private int depth = 0;
@Override
public Void visit(RSyntaxCall element) {
if (depth == 0 && !isBlockStatement(element)) {
return null;
}
SourceSection lazySourceSection = element.getLazySourceSection();
if (lazySourceSection != null) {
blockSrcrefs.add(createLloc(lazySourceSection));
}
if (depth == 0) {
RSyntaxElement[] syntaxArguments = element.getSyntaxArguments();
for (int i = 0; i < syntaxArguments.length; i++) {
if (syntaxArguments[i] != null) {
depth++;
accept(syntaxArguments[i]);
depth--;
}
}
}
return null;
}
private boolean isBlockStatement(RSyntaxCall element) {
RSyntaxElement lhs = element.getSyntaxLHS();
if (lhs instanceof RSyntaxLookup) {
return "{".equals(((RSyntaxLookup) lhs).getIdentifier());
}
return false;
}
@Override
public Void visit(RSyntaxConstant element) {
return null;
}
@Override
public Void visit(RSyntaxLookup element) {
return null;
}
@Override
public Void visit(RSyntaxFunction element) {
accept(element.getSyntaxBody());
return null;
}
};
v.accept(function);
if (!blockSrcrefs.isEmpty()) {
return RDataFactory.createList(blockSrcrefs.toArray());
}
return null;
}
@TruffleBoundary @TruffleBoundary
public static Object createLloc(SourceSection src) { public static Object createLloc(SourceSection src) {
if (src == null) { if (src == null) {
...@@ -117,7 +208,8 @@ public class RSrcref { ...@@ -117,7 +208,8 @@ public class RSrcref {
env = RDataFactory.createNewEnv("src"); env = RDataFactory.createNewEnv("src");
env.setClassAttr(RDataFactory.createStringVector(new String[]{"srcfilecopy", RRuntime.R_SRCFILE}, true)); env.setClassAttr(RDataFactory.createStringVector(new String[]{"srcfilecopy", RRuntime.R_SRCFILE}, true));
try { try {
Path path = Paths.get(RSource.getPathInternal(source)); String pathStr = RSource.getPathInternal(source);
Path path = Paths.get(pathStr != null ? pathStr : "");
env.put(SrcrefFields.filename.name(), path.toString()); env.put(SrcrefFields.filename.name(), path.toString());
env.put(SrcrefFields.fixedNewlines.name(), RRuntime.LOGICAL_TRUE); env.put(SrcrefFields.fixedNewlines.name(), RRuntime.LOGICAL_TRUE);
String[] lines = new String[source.getLineCount()]; String[] lines = new String[source.getLineCount()];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment