diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index a3058cb0a09a66f292e205c3257ab6d90c5aa2f0..765edbe3cc585eec0f1db6134941452aa2b6cbdf 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -2256,7 +2256,7 @@ public class RSerialize { String name = ((RSyntaxLookup) lhs).getIdentifier(); infixFieldAccess = "$".equals(name) || "@".equals(name); } - serializeArguments(arguments, element.getSyntaxSignature(), infixFieldAccess); + serializeArguments(element, arguments, element.getSyntaxSignature(), infixFieldAccess); } return null; } @@ -2269,7 +2269,7 @@ public class RSerialize { return false; } - private void serializeArguments(RSyntaxElement[] arguments, ArgumentsSignature signature, boolean infixFieldAccess) { + private void serializeArguments(RSyntaxCall callElement, RSyntaxElement[] arguments, ArgumentsSignature signature, boolean infixFieldAccess) { state.openPairList(SEXPTYPE.LISTSXP); if (arguments.length == 0) { state.setNull(); @@ -2300,7 +2300,9 @@ public class RSerialize { } state.linkPairList(arguments.length); } - state.setCdr(state.closePairList()); + Object pl = state.closePairList(); + attachSrcref(callElement, pl); + state.setCdr(pl); } @Override @@ -2409,27 +2411,47 @@ public class RSerialize { private static void serializeFunctionDefinition(State state, RSyntaxFunction function) { SerializeVisitor visitor = new SerializeVisitor(state); state.setCar(visitor.visitFunctionFormals(function)); - Object visitFunctionBody = visitor.visitFunctionBody(function); + Object body = 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)); - } + attachSrcref(function, body); + + state.setCdr(body); + } + + /** + * Converts the source section from the syntax element to a srcref attribute and attaches it to + * the serialization object. + * + * @param syntaxElement The syntax element providing the source section. + * @param serObj The object to attribute (most likely a pair list). + */ + private static void attachSrcref(RSyntaxElement syntaxElement, Object serObj) { + SourceSection ss = getFileSourceSection(syntaxElement); + if (ss != null) { + if (serObj instanceof RAttributable) { + String pathInternal = RSource.getPathInternal(ss.getSource()); + RAttributable attributable = (RAttributable) serObj; + attributable.setAttr(RRuntime.R_SRCFILE, RSrcref.createSrcfile(pathInternal)); + RList createBlockSrcrefs = RSrcref.createBlockSrcrefs(syntaxElement); + if (createBlockSrcrefs != null) { + attributable.setAttr(RRuntime.R_SRCREF, createBlockSrcrefs); + attributable.setAttr(RRuntime.R_WHOLE_SRCREF, RSrcref.createLloc(ss)); + } else { + Object createLloc = RSrcref.createLloc(ss); + attributable.setAttr(RRuntime.R_SRCREF, createLloc); + attributable.setAttr(RRuntime.R_WHOLE_SRCREF, RSrcref.createLloc(ss)); } } } + } - state.setCdr(visitFunctionBody); + private static SourceSection getFileSourceSection(RSyntaxElement syntaxElement) { + SourceSection ss = syntaxElement.getLazySourceSection(); + if (ss != null && RSource.getPathInternal(ss.getSource()) != null) { + return ss; + } + return null; } private static Object serializeLanguage(State state, RLanguage lang) { @@ -2543,7 +2565,11 @@ public class RSerialize { RPairList function = (RPairList) cdr; return processFunctionExpression(function.car(), function.cdr(), function.getTag()); } - return RContext.getASTBuilder().call(RSyntaxNode.LAZY_DEPARSE, process(car, true), processArguments(cdr)); + RSyntaxNode call = RContext.getASTBuilder().call(RSyntaxNode.LAZY_DEPARSE, process(car, true), processArguments(cdr)); + if (cdr instanceof RAttributable) { + handleSrcrefAttr((RAttributable) cdr, call); + } + return call; } private static RSyntaxNode processFunctionExpression(Object car, Object cdr, @SuppressWarnings("unused") Object tag) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java index f107a449ad166710cb6d8192d69ab982fde4158d..906133d1dd4ba488fbb275f60d68101ddbcddc15 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java @@ -129,64 +129,11 @@ public class RSrcref { * @param function */ @TruffleBoundary - public static RList createBlockSrcrefs(RSyntaxFunction function) { + public static RList createBlockSrcrefs(RSyntaxElement 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; - } - }; + BlockSrcrefsVisitor v = new BlockSrcrefsVisitor(); v.accept(function); + List<Object> blockSrcrefs = v.blockSrcrefs; if (!blockSrcrefs.isEmpty()) { return RDataFactory.createList(blockSrcrefs.toArray()); @@ -271,7 +218,7 @@ public class RSrcref { int startLine = srcrefVec.getDataAt(0); int startColumn = srcrefVec.getDataAt(1); int startIdx = getLineStartOffset(source, startLine) + startColumn; - int length = getLineStartOffset(source, srcrefVec.getDataAt(2)) + srcrefVec.getDataAt(3) - startIdx; + int length = getLineStartOffset(source, srcrefVec.getDataAt(2)) + srcrefVec.getDataAt(3) - startIdx + 1; return source.createSection(startLine, startColumn, length); } catch (NoSuchFileException e) { RError.warning(RError.SHOW_CALLER, RError.Message.GENERIC, "Missing source file: " + e.getMessage()); @@ -290,4 +237,64 @@ public class RSrcref { throw new IllegalArgumentException(String.format("line %d does not exist in source %s", lineNum, RSource.getPathInternal(source)), e); } } + + private static final class BlockSrcrefsVisitor extends RSyntaxVisitor<Void> { + private List<Object> blockSrcrefs = new LinkedList<>(); + private int depth = 0; + + @Override + public Void visit(RSyntaxCall element) { + + if (depth == 0 && !isBlockStatement(element)) { + return null; + } + + addSrcref(blockSrcrefs, element); + + 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 static void addSrcref(List<Object> blockSrcrefs, RSyntaxElement element) { + SourceSection lazySourceSection = element.getLazySourceSection(); + if (lazySourceSection != null) { + blockSrcrefs.add(createLloc(lazySourceSection)); + } + } + + private static 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) { + addSrcref(blockSrcrefs, element); + return null; + } + + @Override + public Void visit(RSyntaxLookup element) { + addSrcref(blockSrcrefs, element); + return null; + } + + @Override + public Void visit(RSyntaxFunction element) { + accept(element.getSyntaxBody()); + return null; + } + } }