If AST (#5160)
* updated grammar * updated grammar * tests * location data tests * fix from code review
This commit is contained in:
parent
74e0798f89
commit
806a442894
|
@ -1991,7 +1991,7 @@
|
||||||
LOC(1)(Block.wrap([$1])),
|
LOC(1)(Block.wrap([$1])),
|
||||||
{
|
{
|
||||||
type: $2,
|
type: $2,
|
||||||
statement: true
|
postfix: true
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
o('Expression POST_IF Expression',
|
o('Expression POST_IF Expression',
|
||||||
|
@ -2000,7 +2000,7 @@
|
||||||
LOC(1)(Block.wrap([$1])),
|
LOC(1)(Block.wrap([$1])),
|
||||||
{
|
{
|
||||||
type: $2,
|
type: $2,
|
||||||
statement: true
|
postfix: true
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
@ -2035,7 +2035,7 @@
|
||||||
LOC(1)(Block.wrap([$1])),
|
LOC(1)(Block.wrap([$1])),
|
||||||
{
|
{
|
||||||
type: $2,
|
type: $2,
|
||||||
statement: true
|
postfix: true
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
o('Expression POST_IF ExpressionLine',
|
o('Expression POST_IF ExpressionLine',
|
||||||
|
@ -2044,7 +2044,7 @@
|
||||||
LOC(1)(Block.wrap([$1])),
|
LOC(1)(Block.wrap([$1])),
|
||||||
{
|
{
|
||||||
type: $2,
|
type: $2,
|
||||||
statement: true
|
postfix: true
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
|
|
@ -363,7 +363,11 @@
|
||||||
// as JSON. This is what the `ast` option in the Node API returns.
|
// as JSON. This is what the `ast` option in the Node API returns.
|
||||||
// We try to follow the [Babel AST spec](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md)
|
// We try to follow the [Babel AST spec](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md)
|
||||||
// as closely as possible, for improved interoperability with other tools.
|
// as closely as possible, for improved interoperability with other tools.
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
|
o = Object.assign({}, o);
|
||||||
|
if (level != null) {
|
||||||
|
o.level = level;
|
||||||
|
}
|
||||||
// Every abstract syntax tree node object has four categories of properties:
|
// Every abstract syntax tree node object has four categories of properties:
|
||||||
// - type, stored in the `type` field and a string like `NumberLiteral`.
|
// - type, stored in the `type` field and a string like `NumberLiteral`.
|
||||||
// - location data, stored in the `loc`, `start`, `end` and `range` fields.
|
// - location data, stored in the `loc`, `start`, `end` and `range` fields.
|
||||||
|
@ -373,7 +377,7 @@
|
||||||
// `parsedValue` are all top level fields in the AST node object. We have
|
// `parsedValue` are all top level fields in the AST node object. We have
|
||||||
// separate methods for returning each category, that we merge together here.
|
// separate methods for returning each category, that we merge together here.
|
||||||
return Object.assign({}, {
|
return Object.assign({}, {
|
||||||
type: this.astType()
|
type: this.astType(o)
|
||||||
}, this.astProperties(o), this.astLocationData());
|
}, this.astProperties(o), this.astLocationData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,6 +703,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o) {
|
||||||
|
o.level = LEVEL_TOP;
|
||||||
this.initializeScope(o);
|
this.initializeScope(o);
|
||||||
return super.ast(o);
|
return super.ast(o);
|
||||||
}
|
}
|
||||||
|
@ -1457,8 +1462,8 @@
|
||||||
return [this.makeCode('['), ...this.value.compileToFragments(o, LEVEL_LIST), this.makeCode(']')];
|
return [this.makeCode('['), ...this.value.compileToFragments(o, LEVEL_LIST), this.makeCode(']')];
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
return this.value.ast(o);
|
return this.value.ast(o, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1636,7 +1641,7 @@
|
||||||
astProperties(o) {
|
astProperties(o) {
|
||||||
var ref1, ref2;
|
var ref1, ref2;
|
||||||
return {
|
return {
|
||||||
argument: (ref1 = (ref2 = this.expression) != null ? ref2.ast(o) : void 0) != null ? ref1 : null
|
argument: (ref1 = (ref2 = this.expression) != null ? ref2.ast(o, LEVEL_PAREN) : void 0) != null ? ref1 : null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1673,11 +1678,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
this.checkScope(o);
|
this.checkScope(o);
|
||||||
return new Op(this.keyword, new Return(this.expression).withLocationDataFrom(this.expression != null ? {
|
return new Op(this.keyword, new Return(this.expression).withLocationDataFrom(this.expression != null ? {
|
||||||
locationData: mergeLocationData(this.returnKeyword.locationData, this.expression.locationData)
|
locationData: mergeLocationData(this.returnKeyword.locationData, this.expression.locationData)
|
||||||
} : this.returnKeyword)).withLocationDataFrom(this).ast(o);
|
} : this.returnKeyword)).withLocationDataFrom(this).ast(o, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1990,15 +1995,15 @@
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
if (!this.hasProperties()) {
|
if (!this.hasProperties()) {
|
||||||
// If the `Value` has no properties, the AST node is just whatever this
|
// If the `Value` has no properties, the AST node is just whatever this
|
||||||
// node’s `base` is.
|
// node’s `base` is.
|
||||||
return this.base.ast(o);
|
return this.base.ast(o, level);
|
||||||
}
|
}
|
||||||
// Otherwise, call `Base::ast` which in turn calls the `astType` and
|
// Otherwise, call `Base::ast` which in turn calls the `astType` and
|
||||||
// `astProperties` methods below.
|
// `astProperties` methods below.
|
||||||
return super.ast(o);
|
return super.ast(o, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
astType() {
|
astType() {
|
||||||
|
@ -2019,7 +2024,7 @@
|
||||||
property.name.csx = true;
|
property.name.csx = true;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
object: this.object().ast(o),
|
object: this.object().ast(o, LEVEL_ACCESS),
|
||||||
property: property.ast(o),
|
property: property.ast(o),
|
||||||
computed: property instanceof Index || !(((ref2 = property.name) != null ? ref2.unwrap() : void 0) instanceof PropertyName),
|
computed: property instanceof Index || !(((ref2 = property.name) != null ? ref2.unwrap() : void 0) instanceof PropertyName),
|
||||||
optional: !!property.soak,
|
optional: !!property.soak,
|
||||||
|
@ -2260,13 +2265,13 @@
|
||||||
return fragments;
|
return fragments;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast() {
|
ast(o) {
|
||||||
var attribute, j, len1, ref1, results;
|
var attribute, j, len1, ref1, results;
|
||||||
ref1 = this.attributes;
|
ref1 = this.attributes;
|
||||||
results = [];
|
results = [];
|
||||||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||||
attribute = ref1[j];
|
attribute = ref1[j];
|
||||||
results.push(attribute.ast());
|
results.push(attribute.ast(o));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
@ -2315,7 +2320,7 @@
|
||||||
return !this.tagName.base.value.length;
|
return !this.tagName.base.value.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
var tagName;
|
var tagName;
|
||||||
// The location data spanning the opening element < ... > is captured by
|
// The location data spanning the opening element < ... > is captured by
|
||||||
// the generated Arr which contains the element's attributes
|
// the generated Arr which contains the element's attributes
|
||||||
|
@ -2325,7 +2330,7 @@
|
||||||
if (this.content != null) {
|
if (this.content != null) {
|
||||||
this.closingElementLocationData = mergeAstLocationData(jisonLocationDataToAstLocationData(tagName.closingTagOpeningBracketLocationData), jisonLocationDataToAstLocationData(tagName.closingTagClosingBracketLocationData));
|
this.closingElementLocationData = mergeAstLocationData(jisonLocationDataToAstLocationData(tagName.closingTagOpeningBracketLocationData), jisonLocationDataToAstLocationData(tagName.closingTagClosingBracketLocationData));
|
||||||
}
|
}
|
||||||
return super.ast(o);
|
return super.ast(o, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
astType() {
|
astType() {
|
||||||
|
@ -2601,14 +2606,14 @@
|
||||||
astProperties(o) {
|
astProperties(o) {
|
||||||
var arg;
|
var arg;
|
||||||
return {
|
return {
|
||||||
callee: this.variable.ast(o),
|
callee: this.variable.ast(o, LEVEL_ACCESS),
|
||||||
arguments: (function() {
|
arguments: (function() {
|
||||||
var j, len1, ref1, results;
|
var j, len1, ref1, results;
|
||||||
ref1 = this.args;
|
ref1 = this.args;
|
||||||
results = [];
|
results = [];
|
||||||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||||
arg = ref1[j];
|
arg = ref1[j];
|
||||||
results.push(arg.ast(o));
|
results.push(arg.ast(o, LEVEL_LIST));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}).call(this),
|
}).call(this),
|
||||||
|
@ -2795,11 +2800,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
// Babel doesn’t have an AST node for `Access`, but rather just includes
|
// Babel doesn’t have an AST node for `Access`, but rather just includes
|
||||||
// this Access node’s child `name` Identifier node as the `property` of
|
// this Access node’s child `name` Identifier node as the `property` of
|
||||||
// the `MemberExpression` node.
|
// the `MemberExpression` node.
|
||||||
return this.name.ast(o);
|
return this.name.ast(o, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -2830,13 +2835,13 @@
|
||||||
return this.index.shouldCache();
|
return this.index.shouldCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
// Babel doesn’t have an AST node for `Index`, but rather just includes
|
// Babel doesn’t have an AST node for `Index`, but rather just includes
|
||||||
// this Index node’s child `index` Identifier node as the `property` of
|
// this Index node’s child `index` Identifier node as the `property` of
|
||||||
// the `MemberExpression` node. The fact that the `MemberExpression`’s
|
// the `MemberExpression` node. The fact that the `MemberExpression`’s
|
||||||
// `property` is an Index means that `computed` is `true` for the
|
// `property` is an Index means that `computed` is `true` for the
|
||||||
// `MemberExpression`.
|
// `MemberExpression`.
|
||||||
return this.index.ast(o);
|
return this.index.ast(o, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -3019,8 +3024,8 @@
|
||||||
return [this.makeCode(`.slice(${fragmentsToText(fromCompiled)}${toStr || ''})`)];
|
return [this.makeCode(`.slice(${fragmentsToText(fromCompiled)}${toStr || ''})`)];
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
return this.range.ast(o);
|
return this.range.ast(o, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -3568,7 +3573,7 @@
|
||||||
results = [];
|
results = [];
|
||||||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||||
object = ref1[j];
|
object = ref1[j];
|
||||||
results.push(object.ast(o));
|
results.push(object.ast(o, LEVEL_LIST));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}).call(this)
|
}).call(this)
|
||||||
|
@ -4863,8 +4868,8 @@
|
||||||
astProperties(o) {
|
astProperties(o) {
|
||||||
var ref1, ret;
|
var ref1, ret;
|
||||||
ret = {
|
ret = {
|
||||||
right: this.value.ast(o),
|
right: this.value.ast(o, LEVEL_LIST),
|
||||||
left: this.variable.ast(o)
|
left: this.variable.ast(o, LEVEL_LIST)
|
||||||
};
|
};
|
||||||
if (!this.isDefaultAssignment()) {
|
if (!this.isDefaultAssignment()) {
|
||||||
ret.operator = (ref1 = this.originalContext) != null ? ref1 : '=';
|
ret.operator = (ref1 = this.originalContext) != null ? ref1 : '=';
|
||||||
|
@ -5341,9 +5346,9 @@
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
this.updateOptions(o);
|
this.updateOptions(o);
|
||||||
return super.ast(o);
|
return super.ast(o, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
astType() {
|
astType() {
|
||||||
|
@ -5389,7 +5394,7 @@
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}).call(this),
|
}).call(this),
|
||||||
body: this.body.ast(o),
|
body: this.body.ast(o, LEVEL_TOP),
|
||||||
generator: !!this.isGenerator,
|
generator: !!this.isGenerator,
|
||||||
async: !!this.isAsync,
|
async: !!this.isAsync,
|
||||||
// We never generate named functions, so specify `id` as `null`, which
|
// We never generate named functions, so specify `id` as `null`, which
|
||||||
|
@ -5617,7 +5622,7 @@
|
||||||
|
|
||||||
astProperties(o) {
|
astProperties(o) {
|
||||||
return {
|
return {
|
||||||
argument: this.name.ast(o),
|
argument: this.name.ast(o, LEVEL_OP),
|
||||||
postfix: this.postfix
|
postfix: this.postfix
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -6078,11 +6083,11 @@
|
||||||
return super.toString(idt, this.constructor.name + ' ' + this.operator);
|
return super.toString(idt, this.constructor.name + ' ' + this.operator);
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o, level) {
|
||||||
if (this.isYield() || this.isAwait()) {
|
if (this.isYield() || this.isAwait()) {
|
||||||
this.checkContinuation(o);
|
this.checkContinuation(o);
|
||||||
}
|
}
|
||||||
return super.ast(o);
|
return super.ast(o, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
astType() {
|
astType() {
|
||||||
|
@ -6111,8 +6116,8 @@
|
||||||
|
|
||||||
astProperties(o) {
|
astProperties(o) {
|
||||||
var argument, firstAst, ref1, secondAst;
|
var argument, firstAst, ref1, secondAst;
|
||||||
firstAst = this.first.ast(o);
|
firstAst = this.first.ast(o, LEVEL_OP);
|
||||||
secondAst = (ref1 = this.second) != null ? ref1.ast(o) : void 0;
|
secondAst = (ref1 = this.second) != null ? ref1.ast(o, LEVEL_OP) : void 0;
|
||||||
switch (false) {
|
switch (false) {
|
||||||
case !this.isUnary():
|
case !this.isUnary():
|
||||||
argument = this.isYield() && this.first.unwrap().value === '' ? null : firstAst;
|
argument = this.isYield() && this.first.unwrap().value === '' ? null : firstAst;
|
||||||
|
@ -6290,10 +6295,10 @@
|
||||||
astProperties(o) {
|
astProperties(o) {
|
||||||
var ref1, ref2;
|
var ref1, ref2;
|
||||||
return {
|
return {
|
||||||
block: this.attempt.ast(o),
|
block: this.attempt.ast(o, LEVEL_TOP),
|
||||||
handler: (ref1 = (ref2 = this.catch) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
handler: (ref1 = (ref2 = this.catch) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
||||||
// Include `finally` keyword in location data.
|
// Include `finally` keyword in location data.
|
||||||
finalizer: this.ensure != null ? Object.assign(this.ensure.ast(o), mergeAstLocationData(jisonLocationDataToAstLocationData(this.finallyTag.locationData), this.ensure.astLocationData())) : null
|
finalizer: this.ensure != null ? Object.assign(this.ensure.ast(o, LEVEL_TOP), mergeAstLocationData(jisonLocationDataToAstLocationData(this.finallyTag.locationData), this.ensure.astLocationData())) : null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6355,7 +6360,7 @@
|
||||||
var ref1, ref2;
|
var ref1, ref2;
|
||||||
return {
|
return {
|
||||||
param: (ref1 = (ref2 = this.errorVariable) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
param: (ref1 = (ref2 = this.errorVariable) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
||||||
body: this.recovery.ast(o)
|
body: this.recovery.ast(o, LEVEL_TOP)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6394,7 +6399,7 @@
|
||||||
|
|
||||||
astProperties(o) {
|
astProperties(o) {
|
||||||
return {
|
return {
|
||||||
argument: this.expression.ast(o)
|
argument: this.expression.ast(o, LEVEL_LIST)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6535,7 +6540,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
ast(o) {
|
ast(o) {
|
||||||
return this.body.unwrap().ast(o);
|
return this.body.unwrap().ast(o, LEVEL_PAREN);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -7083,7 +7088,7 @@
|
||||||
astProperties(o) {
|
astProperties(o) {
|
||||||
var ref1, ref2;
|
var ref1, ref2;
|
||||||
return {
|
return {
|
||||||
discriminant: (ref1 = (ref2 = this.subject) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
discriminant: (ref1 = (ref2 = this.subject) != null ? ref2.ast(o, LEVEL_PAREN) : void 0) != null ? ref1 : null,
|
||||||
cases: this.casesAst(o)
|
cases: this.casesAst(o)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7110,8 +7115,8 @@
|
||||||
astProperties(o) {
|
astProperties(o) {
|
||||||
var ref1, ref2, ref3, ref4;
|
var ref1, ref2, ref3, ref4;
|
||||||
return {
|
return {
|
||||||
test: (ref1 = (ref2 = this.test) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
test: (ref1 = (ref2 = this.test) != null ? ref2.ast(o, LEVEL_PAREN) : void 0) != null ? ref1 : null,
|
||||||
consequent: (ref3 = (ref4 = this.block) != null ? ref4.ast(o).body : void 0) != null ? ref3 : [],
|
consequent: (ref3 = (ref4 = this.block) != null ? ref4.ast(o, LEVEL_TOP).body : void 0) != null ? ref3 : [],
|
||||||
trailing: !!this.trailing
|
trailing: !!this.trailing
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7149,13 +7154,13 @@
|
||||||
// because ternaries are already proper expressions, and don’t need conversion.
|
// because ternaries are already proper expressions, and don’t need conversion.
|
||||||
exports.If = If = (function() {
|
exports.If = If = (function() {
|
||||||
class If extends Base {
|
class If extends Base {
|
||||||
constructor(condition, body1, options = {}) {
|
constructor(condition1, body1, options = {}) {
|
||||||
super();
|
super();
|
||||||
|
this.condition = condition1;
|
||||||
this.body = body1;
|
this.body = body1;
|
||||||
this.condition = options.type === 'unless' ? condition.invert() : condition;
|
|
||||||
this.elseBody = null;
|
this.elseBody = null;
|
||||||
this.isChain = false;
|
this.isChain = false;
|
||||||
({soak: this.soak} = options);
|
({soak: this.soak, postfix: this.postfix, type: this.type} = options);
|
||||||
if (this.condition.comments) {
|
if (this.condition.comments) {
|
||||||
moveComments(this.condition, this);
|
moveComments(this.condition, this);
|
||||||
}
|
}
|
||||||
|
@ -7175,10 +7180,14 @@
|
||||||
addElse(elseBody) {
|
addElse(elseBody) {
|
||||||
if (this.isChain) {
|
if (this.isChain) {
|
||||||
this.elseBodyNode().addElse(elseBody);
|
this.elseBodyNode().addElse(elseBody);
|
||||||
|
this.locationData = mergeLocationData(this.locationData, this.elseBodyNode().locationData);
|
||||||
} else {
|
} else {
|
||||||
this.isChain = elseBody instanceof If;
|
this.isChain = elseBody instanceof If;
|
||||||
this.elseBody = this.ensureBlock(elseBody);
|
this.elseBody = this.ensureBlock(elseBody);
|
||||||
this.elseBody.updateLocationDataIfMissing(elseBody.locationData);
|
this.elseBody.updateLocationDataIfMissing(elseBody.locationData);
|
||||||
|
if ((this.locationData != null) && (this.elseBody.locationData != null)) {
|
||||||
|
this.locationData = mergeLocationData(this.locationData, this.elseBody.locationData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -7227,12 +7236,12 @@
|
||||||
child = del(o, 'chainChild');
|
child = del(o, 'chainChild');
|
||||||
exeq = del(o, 'isExistentialEquals');
|
exeq = del(o, 'isExistentialEquals');
|
||||||
if (exeq) {
|
if (exeq) {
|
||||||
return new If(this.condition.invert(), this.elseBodyNode(), {
|
return new If(this.processedCondition().invert(), this.elseBodyNode(), {
|
||||||
type: 'if'
|
type: 'if'
|
||||||
}).compileToFragments(o);
|
}).compileToFragments(o);
|
||||||
}
|
}
|
||||||
indent = o.indent + TAB;
|
indent = o.indent + TAB;
|
||||||
cond = this.condition.compileToFragments(o, LEVEL_PAREN);
|
cond = this.processedCondition().compileToFragments(o, LEVEL_PAREN);
|
||||||
body = this.ensureBlock(this.body).compileToFragments(merge(o, {indent}));
|
body = this.ensureBlock(this.body).compileToFragments(merge(o, {indent}));
|
||||||
ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode(`\n${this.tab}}`));
|
ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode(`\n${this.tab}}`));
|
||||||
if (!child) {
|
if (!child) {
|
||||||
|
@ -7254,7 +7263,7 @@
|
||||||
// Compile the `If` as a conditional operator.
|
// Compile the `If` as a conditional operator.
|
||||||
compileExpression(o) {
|
compileExpression(o) {
|
||||||
var alt, body, cond, fragments;
|
var alt, body, cond, fragments;
|
||||||
cond = this.condition.compileToFragments(o, LEVEL_COND);
|
cond = this.processedCondition().compileToFragments(o, LEVEL_COND);
|
||||||
body = this.bodyNode().compileToFragments(o, LEVEL_LIST);
|
body = this.bodyNode().compileToFragments(o, LEVEL_LIST);
|
||||||
alt = this.elseBodyNode() ? this.elseBodyNode().compileToFragments(o, LEVEL_LIST) : [this.makeCode('void 0')];
|
alt = this.elseBodyNode() ? this.elseBodyNode().compileToFragments(o, LEVEL_LIST) : [this.makeCode('void 0')];
|
||||||
fragments = cond.concat(this.makeCode(" ? "), body, this.makeCode(" : "), alt);
|
fragments = cond.concat(this.makeCode(" ? "), body, this.makeCode(" : "), alt);
|
||||||
|
@ -7269,6 +7278,34 @@
|
||||||
return this.soak && this;
|
return this.soak && this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processedCondition() {
|
||||||
|
return this.processedConditionCache != null ? this.processedConditionCache : this.processedConditionCache = this.type === 'unless' ? this.condition.invert() : this.condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
isStatementAst(o) {
|
||||||
|
return o.level === LEVEL_TOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
astType(o) {
|
||||||
|
if (this.isStatementAst(o)) {
|
||||||
|
return 'IfStatement';
|
||||||
|
} else {
|
||||||
|
return 'ConditionalExpression';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
astProperties(o) {
|
||||||
|
var isStatement, ref1, ref2;
|
||||||
|
isStatement = this.isStatementAst(o);
|
||||||
|
return {
|
||||||
|
test: this.condition.ast(o, isStatement ? LEVEL_PAREN : LEVEL_COND),
|
||||||
|
consequent: isStatement ? this.body.ast(o, LEVEL_TOP) : this.bodyNode().ast(o, LEVEL_TOP),
|
||||||
|
alternate: this.isChain ? this.elseBody.unwrap().ast(o, isStatement ? LEVEL_TOP : LEVEL_COND) : (ref1 = (ref2 = this.elseBody) != null ? ref2.ast(o, LEVEL_TOP) : void 0) != null ? ref1 : null,
|
||||||
|
postfix: !!this.postfix,
|
||||||
|
inverted: this.type === 'unless'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
If.prototype.children = ['condition', 'body', 'elseBody'];
|
If.prototype.children = ['condition', 'body', 'elseBody'];
|
||||||
|
|
|
@ -984,7 +984,7 @@ this.$ = yy.addDataToNode(yy, _$[$0-2], $$[$0-2], _$[$0], $$[$0], true)(new yy.I
|
||||||
yy.addDataToNode(yy, _$[$0-2], $$[$0-2], null, null, true)(yy.Block.wrap([$$[$0-2]])),
|
yy.addDataToNode(yy, _$[$0-2], $$[$0-2], null, null, true)(yy.Block.wrap([$$[$0-2]])),
|
||||||
{
|
{
|
||||||
type: $$[$0-1],
|
type: $$[$0-1],
|
||||||
statement: true
|
postfix: true
|
||||||
}));
|
}));
|
||||||
break;
|
break;
|
||||||
case 360:
|
case 360:
|
||||||
|
|
|
@ -817,8 +817,8 @@ grammar =
|
||||||
If: [
|
If: [
|
||||||
o 'IfBlock'
|
o 'IfBlock'
|
||||||
o 'IfBlock ELSE Block', -> $1.addElse $3
|
o 'IfBlock ELSE Block', -> $1.addElse $3
|
||||||
o 'Statement POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
|
o 'Statement POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, postfix: true
|
||||||
o 'Expression POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
|
o 'Expression POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, postfix: true
|
||||||
]
|
]
|
||||||
|
|
||||||
IfBlockLine: [
|
IfBlockLine: [
|
||||||
|
@ -829,8 +829,8 @@ grammar =
|
||||||
IfLine: [
|
IfLine: [
|
||||||
o 'IfBlockLine'
|
o 'IfBlockLine'
|
||||||
o 'IfBlockLine ELSE Block', -> $1.addElse $3
|
o 'IfBlockLine ELSE Block', -> $1.addElse $3
|
||||||
o 'Statement POST_IF ExpressionLine', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
|
o 'Statement POST_IF ExpressionLine', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, postfix: true
|
||||||
o 'Expression POST_IF ExpressionLine', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
|
o 'Expression POST_IF ExpressionLine', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, postfix: true
|
||||||
]
|
]
|
||||||
|
|
||||||
# Arithmetic and logical operators, working on one or more operands.
|
# Arithmetic and logical operators, working on one or more operands.
|
||||||
|
|
130
src/nodes.coffee
130
src/nodes.coffee
|
@ -270,7 +270,9 @@ exports.Base = class Base
|
||||||
# as JSON. This is what the `ast` option in the Node API returns.
|
# as JSON. This is what the `ast` option in the Node API returns.
|
||||||
# We try to follow the [Babel AST spec](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md)
|
# We try to follow the [Babel AST spec](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md)
|
||||||
# as closely as possible, for improved interoperability with other tools.
|
# as closely as possible, for improved interoperability with other tools.
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
|
o = Object.assign {}, o
|
||||||
|
o.level = level if level?
|
||||||
# Every abstract syntax tree node object has four categories of properties:
|
# Every abstract syntax tree node object has four categories of properties:
|
||||||
# - type, stored in the `type` field and a string like `NumberLiteral`.
|
# - type, stored in the `type` field and a string like `NumberLiteral`.
|
||||||
# - location data, stored in the `loc`, `start`, `end` and `range` fields.
|
# - location data, stored in the `loc`, `start`, `end` and `range` fields.
|
||||||
|
@ -279,7 +281,7 @@ exports.Base = class Base
|
||||||
# These fields are all intermixed in the Babel spec; `type` and `start` and
|
# These fields are all intermixed in the Babel spec; `type` and `start` and
|
||||||
# `parsedValue` are all top level fields in the AST node object. We have
|
# `parsedValue` are all top level fields in the AST node object. We have
|
||||||
# separate methods for returning each category, that we merge together here.
|
# separate methods for returning each category, that we merge together here.
|
||||||
Object.assign {}, {type: @astType()}, @astProperties(o), @astLocationData()
|
Object.assign {}, {type: @astType(o)}, @astProperties(o), @astLocationData()
|
||||||
|
|
||||||
# By default, a node class has no specific properties.
|
# By default, a node class has no specific properties.
|
||||||
astProperties: -> {}
|
astProperties: -> {}
|
||||||
|
@ -498,6 +500,7 @@ exports.Root = class Root extends Base
|
||||||
o.scope.parameter name for name in o.locals or []
|
o.scope.parameter name for name in o.locals or []
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o) ->
|
||||||
|
o.level = LEVEL_TOP
|
||||||
@initializeScope o
|
@initializeScope o
|
||||||
super o
|
super o
|
||||||
|
|
||||||
|
@ -1011,8 +1014,8 @@ exports.ComputedPropertyName = class ComputedPropertyName extends PropertyName
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
[@makeCode('['), @value.compileToFragments(o, LEVEL_LIST)..., @makeCode(']')]
|
[@makeCode('['), @value.compileToFragments(o, LEVEL_LIST)..., @makeCode(']')]
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
@value.ast o
|
@value.ast o, level
|
||||||
|
|
||||||
exports.StatementLiteral = class StatementLiteral extends Literal
|
exports.StatementLiteral = class StatementLiteral extends Literal
|
||||||
isStatement: YES
|
isStatement: YES
|
||||||
|
@ -1121,7 +1124,7 @@ exports.Return = class Return extends Base
|
||||||
astType: -> 'ReturnStatement'
|
astType: -> 'ReturnStatement'
|
||||||
|
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
argument: @expression?.ast(o) ? null
|
argument: @expression?.ast(o, LEVEL_PAREN) ? null
|
||||||
|
|
||||||
# Parent class for `YieldReturn`/`AwaitReturn`.
|
# Parent class for `YieldReturn`/`AwaitReturn`.
|
||||||
exports.FuncDirectiveReturn = class FuncDirectiveReturn extends Return
|
exports.FuncDirectiveReturn = class FuncDirectiveReturn extends Return
|
||||||
|
@ -1138,7 +1141,7 @@ exports.FuncDirectiveReturn = class FuncDirectiveReturn extends Return
|
||||||
|
|
||||||
isStatementAst: NO
|
isStatementAst: NO
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
@checkScope o
|
@checkScope o
|
||||||
|
|
||||||
new Op @keyword,
|
new Op @keyword,
|
||||||
|
@ -1150,7 +1153,7 @@ exports.FuncDirectiveReturn = class FuncDirectiveReturn extends Return
|
||||||
@returnKeyword
|
@returnKeyword
|
||||||
)
|
)
|
||||||
.withLocationDataFrom @
|
.withLocationDataFrom @
|
||||||
.ast o
|
.ast o, level
|
||||||
|
|
||||||
# `yield return` works exactly like `return`, except that it turns the function
|
# `yield return` works exactly like `return`, except that it turns the function
|
||||||
# into a generator.
|
# into a generator.
|
||||||
|
@ -1339,13 +1342,13 @@ exports.Value = class Value extends Base
|
||||||
mergeLocationData @base.locationData, initialProperties[initialProperties.length - 1].locationData
|
mergeLocationData @base.locationData, initialProperties[initialProperties.length - 1].locationData
|
||||||
object
|
object
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
# If the `Value` has no properties, the AST node is just whatever this
|
# If the `Value` has no properties, the AST node is just whatever this
|
||||||
# node’s `base` is.
|
# node’s `base` is.
|
||||||
return @base.ast o unless @hasProperties()
|
return @base.ast o, level unless @hasProperties()
|
||||||
# Otherwise, call `Base::ast` which in turn calls the `astType` and
|
# Otherwise, call `Base::ast` which in turn calls the `astType` and
|
||||||
# `astProperties` methods below.
|
# `astProperties` methods below.
|
||||||
super o
|
super o, level
|
||||||
|
|
||||||
astType: ->
|
astType: ->
|
||||||
if @isCSXTag()
|
if @isCSXTag()
|
||||||
|
@ -1360,7 +1363,7 @@ exports.Value = class Value extends Base
|
||||||
[..., property] = @properties
|
[..., property] = @properties
|
||||||
property.name.csx = yes if @isCSXTag()
|
property.name.csx = yes if @isCSXTag()
|
||||||
return
|
return
|
||||||
object: @object().ast o
|
object: @object().ast o, LEVEL_ACCESS
|
||||||
property: property.ast o
|
property: property.ast o
|
||||||
computed: property instanceof Index or property.name?.unwrap() not instanceof PropertyName
|
computed: property instanceof Index or property.name?.unwrap() not instanceof PropertyName
|
||||||
optional: !!property.soak
|
optional: !!property.soak
|
||||||
|
@ -1519,8 +1522,8 @@ exports.CSXAttributes = class CSXAttributes extends Base
|
||||||
fragments.push attribute.compileToFragments(o, LEVEL_TOP)...
|
fragments.push attribute.compileToFragments(o, LEVEL_TOP)...
|
||||||
fragments
|
fragments
|
||||||
|
|
||||||
ast: ->
|
ast: (o) ->
|
||||||
attribute.ast() for attribute in @attributes
|
attribute.ast(o) for attribute in @attributes
|
||||||
|
|
||||||
# Node for a CSX element
|
# Node for a CSX element
|
||||||
exports.CSXElement = class CSXElement extends Base
|
exports.CSXElement = class CSXElement extends Base
|
||||||
|
@ -1545,7 +1548,7 @@ exports.CSXElement = class CSXElement extends Base
|
||||||
isFragment: ->
|
isFragment: ->
|
||||||
!@tagName.base.value.length
|
!@tagName.base.value.length
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
# The location data spanning the opening element < ... > is captured by
|
# The location data spanning the opening element < ... > is captured by
|
||||||
# the generated Arr which contains the element's attributes
|
# the generated Arr which contains the element's attributes
|
||||||
@openingElementLocationData = jisonLocationDataToAstLocationData @attributes.locationData
|
@openingElementLocationData = jisonLocationDataToAstLocationData @attributes.locationData
|
||||||
|
@ -1558,7 +1561,7 @@ exports.CSXElement = class CSXElement extends Base
|
||||||
jisonLocationDataToAstLocationData tagName.closingTagClosingBracketLocationData
|
jisonLocationDataToAstLocationData tagName.closingTagClosingBracketLocationData
|
||||||
)
|
)
|
||||||
|
|
||||||
super o
|
super o, level
|
||||||
|
|
||||||
astType: ->
|
astType: ->
|
||||||
if @isFragment()
|
if @isFragment()
|
||||||
|
@ -1769,8 +1772,8 @@ exports.Call = class Call extends Base
|
||||||
|
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
return
|
return
|
||||||
callee: @variable.ast o
|
callee: @variable.ast o, LEVEL_ACCESS
|
||||||
arguments: arg.ast(o) for arg in @args
|
arguments: arg.ast(o, LEVEL_LIST) for arg in @args
|
||||||
optional: !!@soak
|
optional: !!@soak
|
||||||
implicit: !!@implicit
|
implicit: !!@implicit
|
||||||
|
|
||||||
|
@ -1890,11 +1893,11 @@ exports.Access = class Access extends Base
|
||||||
|
|
||||||
shouldCache: NO
|
shouldCache: NO
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
# Babel doesn’t have an AST node for `Access`, but rather just includes
|
# Babel doesn’t have an AST node for `Access`, but rather just includes
|
||||||
# this Access node’s child `name` Identifier node as the `property` of
|
# this Access node’s child `name` Identifier node as the `property` of
|
||||||
# the `MemberExpression` node.
|
# the `MemberExpression` node.
|
||||||
@name.ast o
|
@name.ast o, level
|
||||||
|
|
||||||
#### Index
|
#### Index
|
||||||
|
|
||||||
|
@ -1911,13 +1914,13 @@ exports.Index = class Index extends Base
|
||||||
shouldCache: ->
|
shouldCache: ->
|
||||||
@index.shouldCache()
|
@index.shouldCache()
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
# Babel doesn’t have an AST node for `Index`, but rather just includes
|
# Babel doesn’t have an AST node for `Index`, but rather just includes
|
||||||
# this Index node’s child `index` Identifier node as the `property` of
|
# this Index node’s child `index` Identifier node as the `property` of
|
||||||
# the `MemberExpression` node. The fact that the `MemberExpression`’s
|
# the `MemberExpression` node. The fact that the `MemberExpression`’s
|
||||||
# `property` is an Index means that `computed` is `true` for the
|
# `property` is an Index means that `computed` is `true` for the
|
||||||
# `MemberExpression`.
|
# `MemberExpression`.
|
||||||
@index.ast o
|
@index.ast o, level
|
||||||
|
|
||||||
#### Range
|
#### Range
|
||||||
|
|
||||||
|
@ -2074,8 +2077,8 @@ exports.Slice = class Slice extends Base
|
||||||
"+#{fragmentsToText compiled} + 1 || 9e9"
|
"+#{fragmentsToText compiled} + 1 || 9e9"
|
||||||
[@makeCode ".slice(#{ fragmentsToText fromCompiled }#{ toStr or '' })"]
|
[@makeCode ".slice(#{ fragmentsToText fromCompiled }#{ toStr or '' })"]
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
@range.ast(o)
|
@range.ast(o, level)
|
||||||
|
|
||||||
#### Obj
|
#### Obj
|
||||||
|
|
||||||
|
@ -2388,7 +2391,7 @@ exports.Arr = class Arr extends Base
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
return
|
return
|
||||||
elements:
|
elements:
|
||||||
object.ast(o) for object in @objects
|
object.ast(o, LEVEL_LIST) for object in @objects
|
||||||
|
|
||||||
#### Class
|
#### Class
|
||||||
|
|
||||||
|
@ -3263,8 +3266,8 @@ exports.Assign = class Assign extends Base
|
||||||
|
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
ret =
|
ret =
|
||||||
right: @value.ast o
|
right: @value.ast o, LEVEL_LIST
|
||||||
left: @variable.ast o
|
left: @variable.ast o, LEVEL_LIST
|
||||||
|
|
||||||
unless @isDefaultAssignment()
|
unless @isDefaultAssignment()
|
||||||
ret.operator = @originalContext ? '='
|
ret.operator = @originalContext ? '='
|
||||||
|
@ -3599,9 +3602,9 @@ exports.Code = class Code extends Base
|
||||||
for {name} in @params when name instanceof Arr or name instanceof Obj
|
for {name} in @params when name instanceof Arr or name instanceof Obj
|
||||||
name.propagateLhs yes
|
name.propagateLhs yes
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
@updateOptions o
|
@updateOptions o
|
||||||
super o
|
super o, level
|
||||||
|
|
||||||
astType: ->
|
astType: ->
|
||||||
if @bound
|
if @bound
|
||||||
|
@ -3624,7 +3627,7 @@ exports.Code = class Code extends Base
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
return
|
return
|
||||||
params: @paramForAst(param).ast(o) for param in @params
|
params: @paramForAst(param).ast(o) for param in @params
|
||||||
body: @body.ast o
|
body: @body.ast o, LEVEL_TOP
|
||||||
generator: !!@isGenerator
|
generator: !!@isGenerator
|
||||||
async: !!@isAsync
|
async: !!@isAsync
|
||||||
# We never generate named functions, so specify `id` as `null`, which
|
# We never generate named functions, so specify `id` as `null`, which
|
||||||
|
@ -3772,7 +3775,7 @@ exports.Splat = class Splat extends Base
|
||||||
'SpreadElement'
|
'SpreadElement'
|
||||||
|
|
||||||
astProperties: (o) -> {
|
astProperties: (o) -> {
|
||||||
argument: @name.ast o
|
argument: @name.ast o, LEVEL_OP
|
||||||
@postfix
|
@postfix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4097,9 +4100,9 @@ exports.Op = class Op extends Base
|
||||||
toString: (idt) ->
|
toString: (idt) ->
|
||||||
super idt, @constructor.name + ' ' + @operator
|
super idt, @constructor.name + ' ' + @operator
|
||||||
|
|
||||||
ast: (o) ->
|
ast: (o, level) ->
|
||||||
@checkContinuation o if @isYield() or @isAwait()
|
@checkContinuation o if @isYield() or @isAwait()
|
||||||
super o
|
super o, level
|
||||||
|
|
||||||
astType: ->
|
astType: ->
|
||||||
return 'AwaitExpression' if @isAwait()
|
return 'AwaitExpression' if @isAwait()
|
||||||
|
@ -4112,8 +4115,8 @@ exports.Op = class Op extends Base
|
||||||
else 'BinaryExpression'
|
else 'BinaryExpression'
|
||||||
|
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
firstAst = @first.ast o
|
firstAst = @first.ast o, LEVEL_OP
|
||||||
secondAst = @second?.ast o
|
secondAst = @second?.ast o, LEVEL_OP
|
||||||
switch
|
switch
|
||||||
when @isUnary()
|
when @isUnary()
|
||||||
argument =
|
argument =
|
||||||
|
@ -4219,11 +4222,11 @@ exports.Try = class Try extends Base
|
||||||
|
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
return
|
return
|
||||||
block: @attempt.ast o
|
block: @attempt.ast o, LEVEL_TOP
|
||||||
handler: @catch?.ast(o) ? null
|
handler: @catch?.ast(o) ? null
|
||||||
finalizer:
|
finalizer:
|
||||||
if @ensure?
|
if @ensure?
|
||||||
Object.assign @ensure.ast(o),
|
Object.assign @ensure.ast(o, LEVEL_TOP),
|
||||||
# Include `finally` keyword in location data.
|
# Include `finally` keyword in location data.
|
||||||
mergeAstLocationData(
|
mergeAstLocationData(
|
||||||
jisonLocationDataToAstLocationData(@finallyTag.locationData),
|
jisonLocationDataToAstLocationData(@finallyTag.locationData),
|
||||||
|
@ -4263,7 +4266,7 @@ exports.Catch = class Catch extends Base
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
return
|
return
|
||||||
param: @errorVariable?.ast(o) ? null
|
param: @errorVariable?.ast(o) ? null
|
||||||
body: @recovery.ast o
|
body: @recovery.ast o, LEVEL_TOP
|
||||||
|
|
||||||
#### Throw
|
#### Throw
|
||||||
|
|
||||||
|
@ -4291,7 +4294,7 @@ exports.Throw = class Throw extends Base
|
||||||
|
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
return
|
return
|
||||||
argument: @expression.ast o
|
argument: @expression.ast o, LEVEL_LIST
|
||||||
|
|
||||||
#### Existence
|
#### Existence
|
||||||
|
|
||||||
|
@ -4380,7 +4383,7 @@ exports.Parens = class Parens extends Base
|
||||||
return @wrapInBraces fragments if @csxAttribute
|
return @wrapInBraces fragments if @csxAttribute
|
||||||
if bare then fragments else @wrapInParentheses fragments
|
if bare then fragments else @wrapInParentheses fragments
|
||||||
|
|
||||||
ast: (o) -> @body.unwrap().ast o
|
ast: (o) -> @body.unwrap().ast o, LEVEL_PAREN
|
||||||
|
|
||||||
#### StringWithInterpolations
|
#### StringWithInterpolations
|
||||||
|
|
||||||
|
@ -4703,7 +4706,7 @@ exports.Switch = class Switch extends Base
|
||||||
|
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
return
|
return
|
||||||
discriminant: @subject?.ast(o) ? null
|
discriminant: @subject?.ast(o, LEVEL_PAREN) ? null
|
||||||
cases: @casesAst o
|
cases: @casesAst o
|
||||||
|
|
||||||
class SwitchCase extends Base
|
class SwitchCase extends Base
|
||||||
|
@ -4714,8 +4717,8 @@ class SwitchCase extends Base
|
||||||
|
|
||||||
astProperties: (o) ->
|
astProperties: (o) ->
|
||||||
return
|
return
|
||||||
test: @test?.ast(o) ? null
|
test: @test?.ast(o, LEVEL_PAREN) ? null
|
||||||
consequent: @block?.ast(o).body ? []
|
consequent: @block?.ast(o, LEVEL_TOP).body ? []
|
||||||
trailing: !!@trailing
|
trailing: !!@trailing
|
||||||
|
|
||||||
exports.SwitchWhen = class SwitchWhen extends Base
|
exports.SwitchWhen = class SwitchWhen extends Base
|
||||||
|
@ -4732,12 +4735,11 @@ exports.SwitchWhen = class SwitchWhen extends Base
|
||||||
# Single-expression **Ifs** are compiled into conditional operators if possible,
|
# Single-expression **Ifs** are compiled into conditional operators if possible,
|
||||||
# because ternaries are already proper expressions, and don’t need conversion.
|
# because ternaries are already proper expressions, and don’t need conversion.
|
||||||
exports.If = class If extends Base
|
exports.If = class If extends Base
|
||||||
constructor: (condition, @body, options = {}) ->
|
constructor: (@condition, @body, options = {}) ->
|
||||||
super()
|
super()
|
||||||
@condition = if options.type is 'unless' then condition.invert() else condition
|
|
||||||
@elseBody = null
|
@elseBody = null
|
||||||
@isChain = false
|
@isChain = false
|
||||||
{@soak} = options
|
{@soak, @postfix, @type} = options
|
||||||
moveComments @condition, @ if @condition.comments
|
moveComments @condition, @ if @condition.comments
|
||||||
|
|
||||||
children: ['condition', 'body', 'elseBody']
|
children: ['condition', 'body', 'elseBody']
|
||||||
|
@ -4749,10 +4751,12 @@ exports.If = class If extends Base
|
||||||
addElse: (elseBody) ->
|
addElse: (elseBody) ->
|
||||||
if @isChain
|
if @isChain
|
||||||
@elseBodyNode().addElse elseBody
|
@elseBodyNode().addElse elseBody
|
||||||
|
@locationData = mergeLocationData @locationData, @elseBodyNode().locationData
|
||||||
else
|
else
|
||||||
@isChain = elseBody instanceof If
|
@isChain = elseBody instanceof If
|
||||||
@elseBody = @ensureBlock elseBody
|
@elseBody = @ensureBlock elseBody
|
||||||
@elseBody.updateLocationDataIfMissing elseBody.locationData
|
@elseBody.updateLocationDataIfMissing elseBody.locationData
|
||||||
|
@locationData = mergeLocationData @locationData, @elseBody.locationData if @locationData? and @elseBody.locationData?
|
||||||
this
|
this
|
||||||
|
|
||||||
# The **If** only compiles into a statement if either of its bodies needs
|
# The **If** only compiles into a statement if either of its bodies needs
|
||||||
|
@ -4782,10 +4786,10 @@ exports.If = class If extends Base
|
||||||
exeq = del o, 'isExistentialEquals'
|
exeq = del o, 'isExistentialEquals'
|
||||||
|
|
||||||
if exeq
|
if exeq
|
||||||
return new If(@condition.invert(), @elseBodyNode(), type: 'if').compileToFragments o
|
return new If(@processedCondition().invert(), @elseBodyNode(), type: 'if').compileToFragments o
|
||||||
|
|
||||||
indent = o.indent + TAB
|
indent = o.indent + TAB
|
||||||
cond = @condition.compileToFragments o, LEVEL_PAREN
|
cond = @processedCondition().compileToFragments o, LEVEL_PAREN
|
||||||
body = @ensureBlock(@body).compileToFragments merge o, {indent}
|
body = @ensureBlock(@body).compileToFragments merge o, {indent}
|
||||||
ifPart = [].concat @makeCode("if ("), cond, @makeCode(") {\n"), body, @makeCode("\n#{@tab}}")
|
ifPart = [].concat @makeCode("if ("), cond, @makeCode(") {\n"), body, @makeCode("\n#{@tab}}")
|
||||||
ifPart.unshift @makeCode @tab unless child
|
ifPart.unshift @makeCode @tab unless child
|
||||||
|
@ -4800,7 +4804,7 @@ exports.If = class If extends Base
|
||||||
|
|
||||||
# Compile the `If` as a conditional operator.
|
# Compile the `If` as a conditional operator.
|
||||||
compileExpression: (o) ->
|
compileExpression: (o) ->
|
||||||
cond = @condition.compileToFragments o, LEVEL_COND
|
cond = @processedCondition().compileToFragments o, LEVEL_COND
|
||||||
body = @bodyNode().compileToFragments o, LEVEL_LIST
|
body = @bodyNode().compileToFragments o, LEVEL_LIST
|
||||||
alt = if @elseBodyNode() then @elseBodyNode().compileToFragments(o, LEVEL_LIST) else [@makeCode('void 0')]
|
alt = if @elseBodyNode() then @elseBodyNode().compileToFragments(o, LEVEL_LIST) else [@makeCode('void 0')]
|
||||||
fragments = cond.concat @makeCode(" ? "), body, @makeCode(" : "), alt
|
fragments = cond.concat @makeCode(" ? "), body, @makeCode(" : "), alt
|
||||||
|
@ -4809,6 +4813,36 @@ exports.If = class If extends Base
|
||||||
unfoldSoak: ->
|
unfoldSoak: ->
|
||||||
@soak and this
|
@soak and this
|
||||||
|
|
||||||
|
processedCondition: ->
|
||||||
|
@processedConditionCache ?= if @type is 'unless' then @condition.invert() else @condition
|
||||||
|
|
||||||
|
isStatementAst: (o) ->
|
||||||
|
o.level is LEVEL_TOP
|
||||||
|
|
||||||
|
astType: (o) ->
|
||||||
|
if @isStatementAst o
|
||||||
|
'IfStatement'
|
||||||
|
else
|
||||||
|
'ConditionalExpression'
|
||||||
|
|
||||||
|
astProperties: (o) ->
|
||||||
|
isStatement = @isStatementAst o
|
||||||
|
|
||||||
|
return
|
||||||
|
test: @condition.ast o, if isStatement then LEVEL_PAREN else LEVEL_COND
|
||||||
|
consequent:
|
||||||
|
if isStatement
|
||||||
|
@body.ast o, LEVEL_TOP
|
||||||
|
else
|
||||||
|
@bodyNode().ast o, LEVEL_TOP
|
||||||
|
alternate:
|
||||||
|
if @isChain
|
||||||
|
@elseBody.unwrap().ast o, if isStatement then LEVEL_TOP else LEVEL_COND
|
||||||
|
else
|
||||||
|
@elseBody?.ast(o, LEVEL_TOP) ? null
|
||||||
|
postfix: !!@postfix
|
||||||
|
inverted: @type is 'unless'
|
||||||
|
|
||||||
# Constants
|
# Constants
|
||||||
# ---------
|
# ---------
|
||||||
|
|
||||||
|
|
|
@ -2321,48 +2321,151 @@ test "AST as expected for Switch node", ->
|
||||||
|
|
||||||
# # TODO: File issue for compile error when using `then` or `;` where `\n` is rn.
|
# # TODO: File issue for compile error when using `then` or `;` where `\n` is rn.
|
||||||
|
|
||||||
# test "AST as expected for If node", ->
|
test "AST as expected for If node", ->
|
||||||
# testExpression 'if maybe then yes',
|
testStatement 'if maybe then yes',
|
||||||
# type: 'If'
|
type: 'IfStatement'
|
||||||
# isChain: no
|
test: ID 'maybe'
|
||||||
# condition:
|
consequent:
|
||||||
# type: 'IdentifierLiteral'
|
type: 'BlockStatement'
|
||||||
# body:
|
body: [
|
||||||
# type: 'Value'
|
type: 'ExpressionStatement'
|
||||||
# base:
|
expression:
|
||||||
# type: 'BooleanLiteral'
|
type: 'BooleanLiteral'
|
||||||
|
]
|
||||||
|
alternate: null
|
||||||
|
postfix: no
|
||||||
|
inverted: no
|
||||||
|
|
||||||
# testExpression 'yes if maybe',
|
testStatement 'yes if maybe',
|
||||||
# type: 'If'
|
type: 'IfStatement'
|
||||||
# isChain: no
|
test: ID 'maybe'
|
||||||
# condition:
|
consequent:
|
||||||
# type: 'IdentifierLiteral'
|
type: 'BlockStatement'
|
||||||
# body:
|
body: [
|
||||||
# type: 'Value'
|
type: 'ExpressionStatement'
|
||||||
# base:
|
expression:
|
||||||
# type: 'BooleanLiteral'
|
type: 'BooleanLiteral'
|
||||||
|
]
|
||||||
|
alternate: null
|
||||||
|
postfix: yes
|
||||||
|
inverted: no
|
||||||
|
|
||||||
# # TODO: Where's the post-if flag?
|
testStatement 'unless x then x else if y then y else z',
|
||||||
|
type: 'IfStatement'
|
||||||
|
test: ID 'x'
|
||||||
|
consequent:
|
||||||
|
type: 'BlockStatement'
|
||||||
|
body: [
|
||||||
|
type: 'ExpressionStatement'
|
||||||
|
expression: ID 'x'
|
||||||
|
]
|
||||||
|
alternate:
|
||||||
|
type: 'IfStatement'
|
||||||
|
test: ID 'y'
|
||||||
|
consequent:
|
||||||
|
type: 'BlockStatement'
|
||||||
|
body: [
|
||||||
|
type: 'ExpressionStatement'
|
||||||
|
expression: ID 'y'
|
||||||
|
]
|
||||||
|
alternate:
|
||||||
|
type: 'BlockStatement'
|
||||||
|
body: [
|
||||||
|
type: 'ExpressionStatement'
|
||||||
|
expression: ID 'z'
|
||||||
|
]
|
||||||
|
postfix: no
|
||||||
|
inverted: no
|
||||||
|
postfix: no
|
||||||
|
inverted: yes
|
||||||
|
|
||||||
# testExpression 'unless x then x else if y then y else z',
|
testStatement '''
|
||||||
# type: 'If'
|
if a
|
||||||
# isChain: yes
|
b
|
||||||
# condition:
|
else
|
||||||
# type: 'Op'
|
if c
|
||||||
# operator: '!'
|
d
|
||||||
# originalOperator: '!'
|
''',
|
||||||
# flip: no
|
type: 'IfStatement'
|
||||||
# body:
|
test: ID 'a'
|
||||||
# type: 'Value'
|
consequent:
|
||||||
# elseBody:
|
type: 'BlockStatement'
|
||||||
# type: 'If'
|
body: [
|
||||||
# isChain: no
|
type: 'ExpressionStatement'
|
||||||
# condition:
|
expression: ID 'b'
|
||||||
# type: 'IdentifierLiteral'
|
]
|
||||||
# body:
|
alternate:
|
||||||
# type: 'Value'
|
type: 'BlockStatement'
|
||||||
# elseBody:
|
body: [
|
||||||
# type: 'Value'
|
type: 'IfStatement'
|
||||||
# isDefaultValue: no
|
test: ID 'c'
|
||||||
|
consequent:
|
||||||
|
type: 'BlockStatement'
|
||||||
|
body: [
|
||||||
|
type: 'ExpressionStatement'
|
||||||
|
expression: ID 'd'
|
||||||
|
]
|
||||||
|
alternate: null
|
||||||
|
postfix: no
|
||||||
|
inverted: no
|
||||||
|
]
|
||||||
|
postfix: no
|
||||||
|
inverted: no
|
||||||
|
|
||||||
# # TODO: AST generator should preserve use of `unless`.
|
testExpression '''
|
||||||
|
a =
|
||||||
|
if b then c else if d then e
|
||||||
|
''',
|
||||||
|
type: 'AssignmentExpression'
|
||||||
|
right:
|
||||||
|
type: 'ConditionalExpression'
|
||||||
|
test: ID 'b'
|
||||||
|
consequent: ID 'c'
|
||||||
|
alternate:
|
||||||
|
type: 'ConditionalExpression'
|
||||||
|
test: ID 'd'
|
||||||
|
consequent: ID 'e'
|
||||||
|
alternate: null
|
||||||
|
postfix: no
|
||||||
|
inverted: no
|
||||||
|
postfix: no
|
||||||
|
inverted: no
|
||||||
|
|
||||||
|
testExpression '''
|
||||||
|
f(
|
||||||
|
if b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
)
|
||||||
|
''',
|
||||||
|
type: 'CallExpression'
|
||||||
|
arguments: [
|
||||||
|
type: 'ConditionalExpression'
|
||||||
|
test: ID 'b'
|
||||||
|
consequent:
|
||||||
|
type: 'BlockStatement'
|
||||||
|
body: [
|
||||||
|
type: 'ExpressionStatement'
|
||||||
|
expression:
|
||||||
|
ID 'c'
|
||||||
|
,
|
||||||
|
type: 'ExpressionStatement'
|
||||||
|
expression:
|
||||||
|
ID 'd'
|
||||||
|
]
|
||||||
|
postfix: no
|
||||||
|
inverted: no
|
||||||
|
]
|
||||||
|
|
||||||
|
testStatement 'a unless b',
|
||||||
|
type: 'IfStatement'
|
||||||
|
test: ID 'b'
|
||||||
|
consequent:
|
||||||
|
type: 'BlockStatement'
|
||||||
|
body: [
|
||||||
|
type: 'ExpressionStatement'
|
||||||
|
expression: ID 'a'
|
||||||
|
]
|
||||||
|
alternate: null
|
||||||
|
postfix: yes
|
||||||
|
inverted: yes
|
||||||
|
|
|
@ -3889,3 +3889,570 @@ test "AST as expected for AwaitReturn node", ->
|
||||||
end:
|
end:
|
||||||
line: 1
|
line: 1
|
||||||
column: 15
|
column: 15
|
||||||
|
|
||||||
|
test "AST as expected for If node", ->
|
||||||
|
testAstLocationData 'if maybe then yes',
|
||||||
|
type: 'IfStatement'
|
||||||
|
test:
|
||||||
|
start: 3
|
||||||
|
end: 8
|
||||||
|
range: [3, 8]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 3
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 8
|
||||||
|
consequent:
|
||||||
|
body: [
|
||||||
|
expression:
|
||||||
|
start: 14
|
||||||
|
end: 17
|
||||||
|
range: [14, 17]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 14
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 17
|
||||||
|
start: 14
|
||||||
|
end: 17
|
||||||
|
range: [14, 17]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 14
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 17
|
||||||
|
]
|
||||||
|
start: 8
|
||||||
|
end: 17
|
||||||
|
range: [8, 17]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 8
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 17
|
||||||
|
start: 0
|
||||||
|
end: 17
|
||||||
|
range: [0, 17]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 17
|
||||||
|
|
||||||
|
testAstLocationData 'yes if maybe',
|
||||||
|
type: 'IfStatement'
|
||||||
|
test:
|
||||||
|
start: 7
|
||||||
|
end: 12
|
||||||
|
range: [7, 12]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 7
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 12
|
||||||
|
consequent:
|
||||||
|
body: [
|
||||||
|
expression:
|
||||||
|
start: 0
|
||||||
|
end: 3
|
||||||
|
range: [0, 3]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 3
|
||||||
|
start: 0
|
||||||
|
end: 3
|
||||||
|
range: [0, 3]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 3
|
||||||
|
]
|
||||||
|
start: 0
|
||||||
|
end: 3
|
||||||
|
range: [0, 3]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 3
|
||||||
|
start: 0
|
||||||
|
end: 12
|
||||||
|
range: [0, 12]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 12
|
||||||
|
|
||||||
|
testAstLocationData 'unless x then x else if y then y else z',
|
||||||
|
type: 'IfStatement'
|
||||||
|
test:
|
||||||
|
start: 7
|
||||||
|
end: 8
|
||||||
|
range: [7, 8]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 7
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 8
|
||||||
|
consequent:
|
||||||
|
body: [
|
||||||
|
expression:
|
||||||
|
start: 14
|
||||||
|
end: 15
|
||||||
|
range: [14, 15]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 14
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 15
|
||||||
|
start: 14
|
||||||
|
end: 15
|
||||||
|
range: [14, 15]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 14
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 15
|
||||||
|
]
|
||||||
|
start: 8
|
||||||
|
end: 15
|
||||||
|
range: [8, 15]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 8
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 15
|
||||||
|
alternate:
|
||||||
|
test:
|
||||||
|
start: 24
|
||||||
|
end: 25
|
||||||
|
range: [24, 25]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 24
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 25
|
||||||
|
consequent:
|
||||||
|
body: [
|
||||||
|
expression:
|
||||||
|
start: 31
|
||||||
|
end: 32
|
||||||
|
range: [31, 32]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 31
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 32
|
||||||
|
start: 31
|
||||||
|
end: 32
|
||||||
|
range: [31, 32]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 31
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 32
|
||||||
|
]
|
||||||
|
start: 25
|
||||||
|
end: 32
|
||||||
|
range: [25, 32]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 25
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 32
|
||||||
|
alternate:
|
||||||
|
body: [
|
||||||
|
expression:
|
||||||
|
start: 38
|
||||||
|
end: 39
|
||||||
|
range: [38, 39]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 38
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 39
|
||||||
|
start: 38
|
||||||
|
end: 39
|
||||||
|
range: [38, 39]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 38
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 39
|
||||||
|
]
|
||||||
|
start: 37
|
||||||
|
end: 39
|
||||||
|
range: [37, 39]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 37
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 39
|
||||||
|
start: 21
|
||||||
|
end: 39
|
||||||
|
range: [21, 39]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 21
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 39
|
||||||
|
start: 0
|
||||||
|
end: 39
|
||||||
|
range: [0, 39]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 39
|
||||||
|
|
||||||
|
testAstLocationData '''
|
||||||
|
if a
|
||||||
|
b
|
||||||
|
else
|
||||||
|
if c
|
||||||
|
d
|
||||||
|
''',
|
||||||
|
type: 'IfStatement'
|
||||||
|
test:
|
||||||
|
start: 3
|
||||||
|
end: 4
|
||||||
|
range: [3, 4]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 3
|
||||||
|
end:
|
||||||
|
line: 1
|
||||||
|
column: 4
|
||||||
|
consequent:
|
||||||
|
body: [
|
||||||
|
expression:
|
||||||
|
start: 7
|
||||||
|
end: 8
|
||||||
|
range: [7, 8]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 2
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 3
|
||||||
|
start: 7
|
||||||
|
end: 8
|
||||||
|
range: [7, 8]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 2
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 3
|
||||||
|
]
|
||||||
|
start: 5
|
||||||
|
end: 8
|
||||||
|
range: [5, 8]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 3
|
||||||
|
alternate:
|
||||||
|
body: [
|
||||||
|
test:
|
||||||
|
start: 19
|
||||||
|
end: 20
|
||||||
|
range: [19, 20]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 4
|
||||||
|
column: 5
|
||||||
|
end:
|
||||||
|
line: 4
|
||||||
|
column: 6
|
||||||
|
consequent:
|
||||||
|
body: [
|
||||||
|
expression:
|
||||||
|
start: 25
|
||||||
|
end: 26
|
||||||
|
range: [25, 26]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 5
|
||||||
|
column: 4
|
||||||
|
end:
|
||||||
|
line: 5
|
||||||
|
column: 5
|
||||||
|
start: 25
|
||||||
|
end: 26
|
||||||
|
range: [25, 26]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 5
|
||||||
|
column: 4
|
||||||
|
end:
|
||||||
|
line: 5
|
||||||
|
column: 5
|
||||||
|
]
|
||||||
|
start: 21
|
||||||
|
end: 26
|
||||||
|
range: [21, 26]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 5
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 5
|
||||||
|
column: 5
|
||||||
|
start: 16
|
||||||
|
end: 26
|
||||||
|
range: [16, 26]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 4
|
||||||
|
column: 2
|
||||||
|
end:
|
||||||
|
line: 5
|
||||||
|
column: 5
|
||||||
|
]
|
||||||
|
start: 14
|
||||||
|
end: 26
|
||||||
|
range: [14, 26]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 4
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 5
|
||||||
|
column: 5
|
||||||
|
start: 0
|
||||||
|
end: 26
|
||||||
|
range: [0, 26]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 5
|
||||||
|
column: 5
|
||||||
|
|
||||||
|
testAstLocationData '''
|
||||||
|
a =
|
||||||
|
if b then c else if d then e
|
||||||
|
''',
|
||||||
|
type: 'AssignmentExpression'
|
||||||
|
right:
|
||||||
|
test:
|
||||||
|
start: 9
|
||||||
|
end: 10
|
||||||
|
range: [9, 10]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 5
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 6
|
||||||
|
consequent:
|
||||||
|
start: 16
|
||||||
|
end: 17
|
||||||
|
range: [16, 17]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 12
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 13
|
||||||
|
alternate:
|
||||||
|
test:
|
||||||
|
start: 26
|
||||||
|
end: 27
|
||||||
|
range: [26, 27]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 22
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 23
|
||||||
|
consequent:
|
||||||
|
start: 33
|
||||||
|
end: 34
|
||||||
|
range: [33, 34]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 29
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 30
|
||||||
|
start: 23
|
||||||
|
end: 34
|
||||||
|
range: [23, 34]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 19
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 30
|
||||||
|
start: 6
|
||||||
|
end: 34
|
||||||
|
range: [6, 34]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 2
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 30
|
||||||
|
start: 0
|
||||||
|
end: 34
|
||||||
|
range: [0, 34]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 30
|
||||||
|
|
||||||
|
testAstLocationData '''
|
||||||
|
f(
|
||||||
|
if b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
)
|
||||||
|
''',
|
||||||
|
type: 'CallExpression'
|
||||||
|
arguments: [
|
||||||
|
test:
|
||||||
|
start: 8
|
||||||
|
end: 9
|
||||||
|
range: [8, 9]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 2
|
||||||
|
column: 5
|
||||||
|
end:
|
||||||
|
line: 2
|
||||||
|
column: 6
|
||||||
|
consequent:
|
||||||
|
body: [
|
||||||
|
expression:
|
||||||
|
start: 14
|
||||||
|
end: 15
|
||||||
|
range: [14, 15]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 3
|
||||||
|
column: 4
|
||||||
|
end:
|
||||||
|
line: 3
|
||||||
|
column: 5
|
||||||
|
start: 14
|
||||||
|
end: 15
|
||||||
|
range: [14, 15]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 3
|
||||||
|
column: 4
|
||||||
|
end:
|
||||||
|
line: 3
|
||||||
|
column: 5
|
||||||
|
,
|
||||||
|
expression:
|
||||||
|
start: 20
|
||||||
|
end: 21
|
||||||
|
range: [20, 21]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 4
|
||||||
|
column: 4
|
||||||
|
end:
|
||||||
|
line: 4
|
||||||
|
column: 5
|
||||||
|
start: 20
|
||||||
|
end: 21
|
||||||
|
range: [20, 21]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 4
|
||||||
|
column: 4
|
||||||
|
end:
|
||||||
|
line: 4
|
||||||
|
column: 5
|
||||||
|
]
|
||||||
|
start: 10
|
||||||
|
end: 21
|
||||||
|
range: [10, 21]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 3
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 4
|
||||||
|
column: 5
|
||||||
|
]
|
||||||
|
start: 0
|
||||||
|
end: 23
|
||||||
|
range: [0, 23]
|
||||||
|
loc:
|
||||||
|
start:
|
||||||
|
line: 1
|
||||||
|
column: 0
|
||||||
|
end:
|
||||||
|
line: 5
|
||||||
|
column: 1
|
||||||
|
|
Loading…
Reference in New Issue