Fixing issue 916 on URI path interpolation#1802
Conversation
jurgenvinju
commented
Jun 1, 2023
- removes deprecated calls and fixes modules names in tests
- fixes loc splicing does not build URIs the right way (e.g. spaces end up being not encoded when the loc is printed) #916
- added tests for loc splicing does not build URIs the right way (e.g. spaces end up being not encoded when the loc is printed) #916
|
This one was open since 2015, but now more and more people get confused by it. It's probably because of the increased usage of clair which has path interpolation in its source code. Seems like a good time as any to fix it. At least we have some tests for it now. |
DavyLandman
left a comment
There was a problem hiding this comment.
The RascalJUnitTestRunner changes confuse me a bit.
|
|
||
| try { | ||
| // reuse our URI encoders here on the unencoded expression part | ||
| URI tmp = URIUtil.create("x", "", "/" + path.getValue()); |
There was a problem hiding this comment.
Hmm, I was thinking we should deprecate the URI part of URIUtil, can we do this using ISourceLocation?
There was a problem hiding this comment.
possibly, but we also want to deprecate the URI part of ISourceLocation right? We'd have to think about getRawPath additions to ISourceLocation, and friends.
There was a problem hiding this comment.
possibly, but we also want to deprecate the URI part of ISourceLocation right? We'd have to think about getRawPath additions to ISourceLocation, and friends.
There was a problem hiding this comment.
well, to go from URI to ISourceLocation is fine(ish), but I was thinking that maybe we should not write new URI code when we don't need to.
There was a problem hiding this comment.
I don't know how to avoid URI, since I need URI.getRawPath() here.
There was a problem hiding this comment.
ah, okay, yeah that seems hackish, but this might be the place this kind of hackish stuff is needed. Can you write a test that checks that it works on windows? (and keeps working in the future/compiler?)
Maybe we need a special flag to say, run this test only on windows.
There was a problem hiding this comment.
I don't think this has to do with Windows. This is pure strings and URIs. The word "path" triggers thinking about file paths, but we are really not in that part of the code. This interpolation and the + operator will do the same thing exactly, 100% ,whether on Windows or on Mac or on Linux, for the same input and the same code.
| // the order of the tests aren't decided by this list so no need to randomly order them. | ||
| for (AbstractFunction f : tests) { | ||
| modDesc.addChild(Description.createTestDescription(clazz, computeTestName(f.getName(), f.getAst().getLocation()))); | ||
| modDesc.addChild(Description.createTestDescription(module, computeTestName(f.getName(), f.getAst().getLocation()))); |
There was a problem hiding this comment.
No this was an accident
There was a problem hiding this comment.
No this was an accident
The RascalJUnitTestRunner changes confuse me a bit.
well, I was confused when this happened, so that makes total sense again. I accidentally merged this change into the PR. I've tested it and there is no effect, positive or negative, to the test execution other than that the right module names are now shown when a test fails in the reports (also in the XML files).
There was a problem hiding this comment.
that's nice :) okay, well, I'll allow it ;) ;)
| @Override | ||
| public void start(String context, int count) { | ||
| notifier.fireTestRunStarted(module); | ||
| // notifier.fireTestRunStarted(module); |
There was a problem hiding this comment.
are we sure we want to disable these notifications?
There was a problem hiding this comment.
Yes, these are actually not allowed to be called anymore. They've been kept in for binary backwards compatibility but the javaDoc says "do not invoke" literally.
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
| IString path = (IString) ResultFactory.makeResult(TF.stringType(), VF.string(""), __eval) | ||
| .add(expr).getValue(); | ||
|
|
||
| try { |
There was a problem hiding this comment.
this part should also get some comments explaining what is happening.
| test bool correctTempPathResolverOnWindows() = /\\/ !:= resolveLocation(|tmp:///|).path; No newline at end of file | ||
| test bool correctTempPathResolverOnWindows() = /\\/ !:= resolveLocation(|tmp:///|).path; | ||
|
|
||
| test bool encodingIsTheSameForPathAdditionAndTemplateInstantation() |
There was a problem hiding this comment.
can we also make one that tests the behavior on windows?
There was a problem hiding this comment.
there is no OS dependent code in this part of the implementation. I.e. we do not use new File or anything like that or Path.separator.
Perhaps we should? Debatable. But right now we mimick exactly the behavior of the + semantics which also does not depend on OS specifics because it simply uses: getValueFactory().sourceLocation(scheme, authority, newPath, query, fragment);, via the fieldUpdate code on SourceLocationResult.
There was a problem hiding this comment.
x = "c:\x\t.txt";
return |file:///<x>| == |file:///c:/x/t.txt|;something like that should work on windows right?
There was a problem hiding this comment.
I'm pretty sure that it will not. There is no code in scope that will interpret the \ as a path separator, so I'm pretty sure they will just stay where they are.
Also, in this example you'd have to escape the backslashes: x = c:\\x\\t.txt
There was a problem hiding this comment.
So I'd expect it will print: |file:///c:%5Cx%5Ct.txt|, just like the + operator does.
There was a problem hiding this comment.
Yes, confirmed. the + operator and the fixed interpolator both will not interpret windows path separators, even if on windows. It will just be |file:///c:%5Cx%5Ct.txt| where the \ is escaped as %5C per the URI spec.
There was a problem hiding this comment.
ah, okay, I must be missing the case that this fix is solving :) I assumed it was trying to fix this.
There was a problem hiding this comment.
This current fix solves the case where x = " "; |file:///<x>|; would throw a URISyntaxException because there are spaces in the path. Instead it now behaves like |file:///| + x where the output would be |file:///%20%20%20|
The fix you have in mind requires a RAP. I'm open to the suggestion, but we'd have to carefully consider letting OS-dependent semantics into the Rascal language. The issue I have with that is that code that is run for a certain experiment could behave differently if run on another machine, with the same input data. So that's definitely worth another discussion.
There was a problem hiding this comment.
I'd rather put OS-dependent path conversion this under a well-documented library function than hide it under language semantics. Something like: loc parseFilePath(str path, OS forOS=currentOS())
There was a problem hiding this comment.
I'd rather put OS-dependent path conversion under a well-documented library function than hide it under language semantics. Something like: loc parseFilePath(str path, OS forOS=currentOS())
|
The current solution is broken. Another test for
|