Comments (7)
It's very strange that we get the raw
value correct but the range incorrect. Especially since we're just using PEG.js's line
, column
, and offset
functions. Unfortunately, this is in one of the hairier parts of the code (read: there's a nasty hack to skip counting of context-free-CoffeeScript control characters).
from coffeescriptredux.
Just in case it's helpful to you or anyone else who runs into this, here's what I'm using to fix the ranges. It's probably pretty inefficient but so far it's been sufficient for my needs:
// Visit every node to fix its range, assumes each node has a
// `_parent` property that refers to its parent node. This is intended
// to operate on the result of `toBasicObject()` on the parsed AST.
traverse(ast, function(node) {
if (!node.range) { return; }
if (node._parent) {
node.range[0] += node._parent._offset;
node.range[1] += node._parent._offset;
}
if (node.raw !== source.slice(node.range[0], node.range[1])) {
node._offset = fixRange(node, source);
} else {
node._offset = 0;
}
});
function fixRange(node, source) {
var index = -1;
var expectedStart = node.range[0];
var minimumOffsetIndex = -1;
var minimumOffset = Infinity;
while ((index = source.indexOf(node.raw, index + 1)) >= 0) {
if (minimumOffsetIndex < 0) {
minimumOffsetIndex = index;
minimumOffset = Math.abs(expectedStart - minimumOffsetIndex);
} else {
var thisOffset = Math.abs(expectedStart - index);
if (thisOffset < minimumOffset) {
minimumOffset = thisOffset;
minimumOffsetIndex = index;
}
}
}
if (minimumOffsetIndex < 0) {
throw new Error('unable to find location for node: ' + JSON.stringify(node.raw));
}
node.range[0] = minimumOffsetIndex;
node.range[1] = minimumOffsetIndex + node.raw.length;
return minimumOffsetIndex - expectedStart;
}
from coffeescriptredux.
Actually, it looks like it's even worse. Some nodes that ought to have range
and raw
do not have either, such as when parsing "a#{b}"
:
> parse('"a#{b}"', { raw: true }).toBasicObject().body.statements[0]
{ type: 'ConcatOp',
line: 1,
column: 1,
raw: '"a#{b}"',
range: [ 0, 7 ],
left:
{ type: 'String',
line: 1,
column: 2,
data: 'a' },
right:
{ type: 'Identifier',
line: 1,
column: 5,
raw: 'b',
range: [ 4, 5 ],
data: 'b' } }
from coffeescriptredux.
Okay, I think I've figured out why this is happening. I'm pretty sure it's due to the "context-free-CoffeeScript control characters" you mentioned. When an input string is pre-processed a number of characters are added, so this:
->
a.b
Becomes this:
->
a.b
Those extra characters are what is causing the range
property to be incorrect, as it's reporting the range inside the preprocessed input, not the original input. I can think of a few ways to work around this, but I'm not sure how to fix it. Thoughts, @michaelficarra?
from coffeescriptredux.
Ah yes, now I remember. We fixed that issue in #117 (1f314eb) (though, using an extremely hacky approach). I would not be surprised if it broke when upgrading PEGjs, if not for the fact that we do have tests for it. I still can't think of a better way to solve this problem than the hack from #117.
from coffeescriptredux.
I don't believe the problem is exactly the same. That commit does in fact fix line and column numbers, but doesn't fix offsets. I have a workaround from a commit that links to this issue that basically recomputes the range info based on the line and column numbers.
Am I missing something?
from coffeescriptredux.
Oh you're right, I didn't notice it only fixed line/column but not offset.
Your commit looks awesome! Would we be able to also get rid of that nasty hack in the parser?
edit: In case it wasn't clear, I mean integrating that lookup table in the CSR parser and getting rid of the overridden PEGjs function hack.
from coffeescriptredux.
Related Issues (20)
- CR after line continuation backslash leads to syntax error
- Switch doesn't work with the ternary operator HOT 2
- syntax error in javascript output when last function parameter is both a splat and a property HOT 9
- New line escaping (\) doesn't work in some cases
- What is the equivalent of require('coffee-script').compile(code, options);? HOT 3
- Is function declaration output possible HOT 2
- status? HOT 33
- ES6 support HOT 43
- REPL tests broken under iojs / new nodejs HOT 2
- Existential range slices HOT 1
- Assignment inside iterator scope HOT 1
- Project Status HOT 6
- JSON.parse stack traces break when using register HOT 1
- A static module system proposal for CS HOT 1
- -r command line option doesn't seem to work HOT 5
- feature request: compile to go and php HOT 2
- Confusing behaviour when inheriting from classes with bound methods HOT 1
- What's the state of this project? HOT 3
- Is project dead? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from coffeescriptredux.