Add back ranges property (#363)

* Add back ranges property

* Correctly adjust range in flow plugin

* Make it an option
This commit is contained in:
Henry Zhu 2017-03-01 10:57:06 -05:00 committed by GitHub
parent aec4beff0c
commit f1e2cca767
10 changed files with 504 additions and 12 deletions

View File

@ -9,7 +9,8 @@ export const defaultOptions: {
allowImportExportEverywhere: boolean,
allowSuperOutsideMethod: boolean,
plugins: Array<string>,
strictMode: any
strictMode: any,
ranges: boolean,
} = {
// Source type ("script" or "module") for different semantics
sourceType: "script",
@ -30,6 +31,15 @@ export const defaultOptions: {
plugins: [],
// TODO
strictMode: null,
// Nodes have their start and end characters offsets recorded in
// `start` and `end` properties (directly on the node, rather than
// the `loc` object, which holds line/column data. To also add a
// [semi-standardized][range] `range` property holding a `[start,
// end]` array with the same numbers, set the `ranges` option to
// `true`.
//
// [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
ranges: false,
};
// Interpret and default an options object

View File

@ -1,5 +1,5 @@
import Parser from "./index";
import { SourceLocation } from "../util/location";
import { SourceLocation, type Position } from "../util/location";
// Start an AST node, attaching a start offset.
@ -7,12 +7,13 @@ const pp = Parser.prototype;
const commentKeys = ["leadingComments", "trailingComments", "innerComments"];
class Node {
constructor(pos?: number, loc?: number, filename?: string) {
constructor(parser?: Parser, pos?: number, loc?: Position) {
this.type = "";
this.start = pos;
this.end = 0;
this.loc = new SourceLocation(loc);
if (filename) this.loc.filename = filename;
if (parser && parser.options.ranges) this.range = [pos, 0];
if (parser && parser.filename) this.loc.filename = parser.filename;
}
type: string;
@ -34,17 +35,18 @@ class Node {
}
pp.startNode = function () {
return new Node(this.state.start, this.state.startLoc, this.filename);
return new Node(this, this.state.start, this.state.startLoc);
};
pp.startNodeAt = function (pos, loc) {
return new Node(pos, loc, this.filename);
return new Node(this, pos, loc);
};
function finishNodeAt(node, type, pos, loc) {
node.type = type;
node.end = pos;
node.loc.end = loc;
if (this.options.ranges) node.range[1] = pos;
this.processComment(node);
return node;
}
@ -60,3 +62,15 @@ pp.finishNode = function (node, type) {
pp.finishNodeAt = function (node, type, pos, loc) {
return finishNodeAt.call(this, node, type, pos, loc);
};
/**
* Reset the start location of node to the start location of locationNode
*/
pp.resetStartLocationFromNode = function (node, locationNode) {
node.start = locationNode.start;
node.loc.start = locationNode.loc.start;
if (this.options.ranges) node.range[0] = locationNode.range[0];
return node;
};

View File

@ -1381,8 +1381,7 @@ export default function (instance) {
arrowExpression = inner.apply(this, args);
arrowExpression.typeParameters = typeParameters;
arrowExpression.start = typeParameters.start;
arrowExpression.loc.start = typeParameters.loc.start;
this.resetStartLocationFromNode(arrowExpression, typeParameters);
} catch (err) {
throw jsxError || err;
}

View File

@ -4,14 +4,14 @@ import { lineBreakG } from "./whitespace";
// `startLoc` and `endLoc` properties.
export class Position {
constructor(line, col) {
constructor(line: number, col: number) {
this.line = line;
this.column = col;
}
}
export class SourceLocation {
constructor(start, end) {
constructor(start: Position, end?: Position) {
this.start = start;
this.end = end;
}

View File

@ -0,0 +1,3 @@
var a = 1;
var b = a + 1;

View File

@ -0,0 +1,207 @@
{
"type": "File",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 14
}
},
"program": {
"type": "Program",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 14
}
},
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 10
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 9
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "a"
},
"name": "a"
},
"init": {
"type": "NumericLiteral",
"start": 8,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 9
}
},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
],
"kind": "var"
},
{
"type": "VariableDeclaration",
"start": 12,
"end": 26,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 14
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 16,
"end": 25,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"line": 3,
"column": 13
}
},
"id": {
"type": "Identifier",
"start": 16,
"end": 17,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"line": 3,
"column": 5
},
"identifierName": "b"
},
"name": "b"
},
"init": {
"type": "BinaryExpression",
"start": 20,
"end": 25,
"loc": {
"start": {
"line": 3,
"column": 8
},
"end": {
"line": 3,
"column": 13
}
},
"left": {
"type": "Identifier",
"start": 20,
"end": 21,
"loc": {
"start": {
"line": 3,
"column": 8
},
"end": {
"line": 3,
"column": 9
},
"identifierName": "a"
},
"name": "a"
},
"operator": "+",
"right": {
"type": "NumericLiteral",
"start": 24,
"end": 25,
"loc": {
"start": {
"line": 3,
"column": 12
},
"end": {
"line": 3,
"column": 13
}
},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
}
],
"kind": "var"
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
var a = 1;
var b = a + 1;

View File

@ -0,0 +1,255 @@
{
"type": "File",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 14
}
},
"range": [
0,
26
],
"program": {
"type": "Program",
"start": 0,
"end": 26,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 14
}
},
"range": [
0,
26
],
"sourceType": "script",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 10
}
},
"range": [
0,
10
],
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 9
}
},
"range": [
4,
9
],
"id": {
"type": "Identifier",
"start": 4,
"end": 5,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 5
},
"identifierName": "a"
},
"range": [
4,
5
],
"name": "a"
},
"init": {
"type": "NumericLiteral",
"start": 8,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 9
}
},
"range": [
8,
9
],
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
],
"kind": "var"
},
{
"type": "VariableDeclaration",
"start": 12,
"end": 26,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 14
}
},
"range": [
12,
26
],
"declarations": [
{
"type": "VariableDeclarator",
"start": 16,
"end": 25,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"line": 3,
"column": 13
}
},
"range": [
16,
25
],
"id": {
"type": "Identifier",
"start": 16,
"end": 17,
"loc": {
"start": {
"line": 3,
"column": 4
},
"end": {
"line": 3,
"column": 5
},
"identifierName": "b"
},
"range": [
16,
17
],
"name": "b"
},
"init": {
"type": "BinaryExpression",
"start": 20,
"end": 25,
"loc": {
"start": {
"line": 3,
"column": 8
},
"end": {
"line": 3,
"column": 13
}
},
"range": [
20,
25
],
"left": {
"type": "Identifier",
"start": 20,
"end": 21,
"loc": {
"start": {
"line": 3,
"column": 8
},
"end": {
"line": 3,
"column": 9
},
"identifierName": "a"
},
"range": [
20,
21
],
"name": "a"
},
"operator": "+",
"right": {
"type": "NumericLiteral",
"start": 24,
"end": 25,
"loc": {
"start": {
"line": 3,
"column": 12
},
"end": {
"line": 3,
"column": 13
}
},
"range": [
24,
25
],
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
}
],
"kind": "var"
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
{
"ranges": true
}

View File

@ -61,8 +61,6 @@ function save(test, ast) {
function runTest(test, parseFunction) {
var opts = test.options;
opts.locations = true;
opts.ranges = true;
if (opts.throws && test.expect.code) {
throw new Error("File expected.json exists although options specify throws. Remove expected.json.");