Try AST (#5140)
* root ast * updated grammar * preserve CoffeeScript.nodes() API * root ast methods * try ast * updated grammar * updated grammar * updated grammar * updated grammar * finally location data * remove unused * updates from code review
This commit is contained in:
parent
38c8b2f35f
commit
a7b1fa51e7
|
@ -1292,40 +1292,38 @@
|
|||
o('TRY Block Catch',
|
||||
function() {
|
||||
return new Try($2,
|
||||
$3[0],
|
||||
$3[1]);
|
||||
$3);
|
||||
}),
|
||||
o('TRY Block FINALLY Block',
|
||||
function() {
|
||||
return new Try($2,
|
||||
null,
|
||||
null,
|
||||
$4);
|
||||
$4,
|
||||
LOC(3)(new Literal($3)));
|
||||
}),
|
||||
o('TRY Block Catch FINALLY Block',
|
||||
function() {
|
||||
return new Try($2,
|
||||
$3[0],
|
||||
$3[1],
|
||||
$5);
|
||||
$3,
|
||||
$5,
|
||||
LOC(4)(new Literal($4)));
|
||||
})
|
||||
],
|
||||
// A catch clause names its error and runs a block of code.
|
||||
Catch: [
|
||||
o('CATCH Identifier Block',
|
||||
function() {
|
||||
return [$2,
|
||||
$3];
|
||||
return new Catch($3,
|
||||
$2);
|
||||
}),
|
||||
o('CATCH Object Block',
|
||||
function() {
|
||||
return [LOC(2)(new Value($2)),
|
||||
$3];
|
||||
return new Catch($3,
|
||||
LOC(2)(new Value($2)));
|
||||
}),
|
||||
o('CATCH Block',
|
||||
function() {
|
||||
return [null,
|
||||
$2];
|
||||
return new Catch($2);
|
||||
})
|
||||
],
|
||||
// Throw an exception object.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// nodes are created as the result of actions in the [grammar](grammar.html),
|
||||
// but some are created by other nodes as a method of code generation. To convert
|
||||
// the syntax tree into a string of JavaScript code, call `compile()` on the root.
|
||||
var Access, Arr, Assign, AwaitReturn, Base, Block, BooleanLiteral, CSXAttribute, CSXAttributes, CSXElement, CSXExpressionContainer, CSXIdentifier, CSXTag, Call, Class, Code, CodeFragment, ComputedPropertyName, DefaultLiteral, Elision, ExecutableClassBody, Existence, Expansion, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExportSpecifier, ExportSpecifierList, Extends, For, FuncGlyph, HEREGEX_OMIT, HereComment, HoistTarget, IdentifierLiteral, If, ImportClause, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ImportSpecifierList, In, Index, InfinityLiteral, Interpolation, JS_FORBIDDEN, LEADING_BLANK_LINE, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, LineComment, Literal, ModuleDeclaration, ModuleSpecifier, ModuleSpecifierList, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, ObjectProperty, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, Root, SIMPLENUM, SIMPLE_STRING_OMIT, STRING_OMIT, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, Super, SuperCall, Switch, TAB, THIS, TRAILING_BLANK_LINE, TaggedTemplateCall, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addDataToNode, attachCommentsToNode, compact, del, ends, extend, flatten, fragmentsToText, greater, hasLineComments, indentInitial, isFunction, isLiteralArguments, isLiteralThis, isNumber, isPlainObject, isUnassignable, jisonLocationDataToAstLocationData, lesser, locationDataToString, makeDelimitedLiteral, merge, mergeAstLocationData, mergeLocationData, moveComments, multident, replaceUnicodeCodePointEscapes, shouldCacheOrIsAssignable, some, starts, throwSyntaxError, unfoldSoak, unshiftAfterComments, utility,
|
||||
var Access, Arr, Assign, AwaitReturn, Base, Block, BooleanLiteral, CSXAttribute, CSXAttributes, CSXElement, CSXExpressionContainer, CSXIdentifier, CSXTag, Call, Catch, Class, Code, CodeFragment, ComputedPropertyName, DefaultLiteral, Elision, ExecutableClassBody, Existence, Expansion, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExportSpecifier, ExportSpecifierList, Extends, For, FuncGlyph, HEREGEX_OMIT, HereComment, HoistTarget, IdentifierLiteral, If, ImportClause, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ImportSpecifierList, In, Index, InfinityLiteral, Interpolation, JS_FORBIDDEN, LEADING_BLANK_LINE, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, LineComment, Literal, ModuleDeclaration, ModuleSpecifier, ModuleSpecifierList, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, ObjectProperty, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, Root, SIMPLENUM, SIMPLE_STRING_OMIT, STRING_OMIT, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, Super, SuperCall, Switch, TAB, THIS, TRAILING_BLANK_LINE, TaggedTemplateCall, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addDataToNode, attachCommentsToNode, compact, del, ends, extend, flatten, fragmentsToText, greater, hasLineComments, indentInitial, isFunction, isLiteralArguments, isLiteralThis, isNumber, isPlainObject, isUnassignable, jisonLocationDataToAstLocationData, lesser, locationDataToString, makeDelimitedLiteral, merge, mergeAstLocationData, mergeLocationData, moveComments, multident, replaceUnicodeCodePointEscapes, shouldCacheOrIsAssignable, some, starts, throwSyntaxError, unfoldSoak, unshiftAfterComments, utility,
|
||||
indexOf = [].indexOf,
|
||||
splice = [].splice,
|
||||
slice1 = [].slice;
|
||||
|
@ -363,7 +363,7 @@
|
|||
// 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)
|
||||
// as closely as possible, for improved interoperability with other tools.
|
||||
ast() {
|
||||
ast(o) {
|
||||
// Every abstract syntax tree node object has four categories of properties:
|
||||
// - type, stored in the `type` field and a string like `NumberLiteral`.
|
||||
// - location data, stored in the `loc`, `start`, `end` and `range` fields.
|
||||
|
@ -372,9 +372,9 @@
|
|||
// 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
|
||||
// separate methods for returning each category, that we merge together here.
|
||||
return Object.assign({}, this.astProperties(), {
|
||||
return Object.assign({}, {
|
||||
type: this.astType()
|
||||
}, this.astLocationData());
|
||||
}, this.astProperties(o), this.astLocationData());
|
||||
}
|
||||
|
||||
// By default, a node class has no specific properties.
|
||||
|
@ -689,9 +689,10 @@
|
|||
return 'File';
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
this.body.isRootBlock = true;
|
||||
return {
|
||||
program: Object.assign(this.body.ast(), this.astLocationData()),
|
||||
program: Object.assign(this.body.ast(o), this.astLocationData()),
|
||||
comments: []
|
||||
};
|
||||
}
|
||||
|
@ -1085,7 +1086,11 @@
|
|||
}
|
||||
|
||||
astType() {
|
||||
return 'Program';
|
||||
if (this.isRootBlock) {
|
||||
return 'Program';
|
||||
} else {
|
||||
return 'BlockStatement';
|
||||
}
|
||||
}
|
||||
|
||||
astProperties(o) {
|
||||
|
@ -1096,12 +1101,12 @@
|
|||
expression = ref1[j];
|
||||
// If an expression is a statement, it can be added to the body as is.
|
||||
if (expression.isStatement(o)) {
|
||||
body.push(expression.ast());
|
||||
body.push(expression.ast(o));
|
||||
} else {
|
||||
// Otherwise, we need to wrap it in an `ExpressionStatement` AST node.
|
||||
body.push(Object.assign({
|
||||
type: 'ExpressionStatement',
|
||||
expression: expression.ast()
|
||||
expression: expression.ast(o)
|
||||
}, expression.astLocationData()));
|
||||
}
|
||||
}
|
||||
|
@ -1434,8 +1439,8 @@
|
|||
return [this.makeCode('['), ...this.value.compileToFragments(o, LEVEL_LIST), this.makeCode(']')];
|
||||
}
|
||||
|
||||
ast() {
|
||||
return this.value.ast();
|
||||
ast(o) {
|
||||
return this.value.ast(o);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -1924,15 +1929,15 @@
|
|||
return object;
|
||||
}
|
||||
|
||||
ast() {
|
||||
ast(o) {
|
||||
if (!this.hasProperties()) {
|
||||
// If the `Value` has no properties, the AST node is just whatever this
|
||||
// node’s `base` is.
|
||||
return this.base.ast();
|
||||
return this.base.ast(o);
|
||||
}
|
||||
// Otherwise, call `Base::ast` which in turn calls the `astType` and
|
||||
// `astProperties` methods below.
|
||||
return super.ast();
|
||||
return super.ast(o);
|
||||
}
|
||||
|
||||
astType() {
|
||||
|
@ -1946,15 +1951,15 @@
|
|||
// If this `Value` has properties, the *last* property (e.g. `c` in `a.b.c`)
|
||||
// becomes the `property`, and the preceding properties (e.g. `a.b`) become
|
||||
// a child `Value` node assigned to the `object` property.
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var property, ref1, ref2;
|
||||
ref1 = this.properties, [property] = slice1.call(ref1, -1);
|
||||
if (this.isCSXTag()) {
|
||||
property.name.csx = true;
|
||||
}
|
||||
return {
|
||||
object: this.object().ast(),
|
||||
property: property.ast(),
|
||||
object: this.object().ast(o),
|
||||
property: property.ast(o),
|
||||
computed: property instanceof Index || !(((ref2 = property.name) != null ? ref2.unwrap() : void 0) instanceof PropertyName),
|
||||
optional: !!property.soak,
|
||||
shorthand: !!property.shorthand
|
||||
|
@ -2249,7 +2254,7 @@
|
|||
return !this.tagName.base.value.length;
|
||||
}
|
||||
|
||||
ast() {
|
||||
ast(o) {
|
||||
var tagName;
|
||||
// The location data spanning the opening element < ... > is captured by
|
||||
// the generated Arr which contains the element's attributes
|
||||
|
@ -2259,7 +2264,7 @@
|
|||
if (this.content != null) {
|
||||
this.closingElementLocationData = mergeAstLocationData(jisonLocationDataToAstLocationData(tagName.closingTagOpeningBracketLocationData), jisonLocationDataToAstLocationData(tagName.closingTagClosingBracketLocationData));
|
||||
}
|
||||
return super.ast();
|
||||
return super.ast(o);
|
||||
}
|
||||
|
||||
astType() {
|
||||
|
@ -2270,19 +2275,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
elementAstProperties() {
|
||||
elementAstProperties(o) {
|
||||
var closingElement, currentExpr, openingElement, rangeDiff, shiftAstLocationData;
|
||||
openingElement = Object.assign({
|
||||
type: 'JSXOpeningElement',
|
||||
name: this.tagName.unwrap().ast(),
|
||||
name: this.tagName.unwrap().ast(o),
|
||||
selfClosing: this.closingElementLocationData == null,
|
||||
attributes: this.attributes.ast()
|
||||
attributes: this.attributes.ast(o)
|
||||
}, this.openingElementLocationData);
|
||||
closingElement = null;
|
||||
if (this.closingElementLocationData != null) {
|
||||
closingElement = Object.assign({
|
||||
type: 'JSXClosingElement',
|
||||
name: Object.assign(this.tagName.unwrap().ast(), jisonLocationDataToAstLocationData(this.tagName.base.closingTagNameLocationData))
|
||||
name: Object.assign(this.tagName.unwrap().ast(o), jisonLocationDataToAstLocationData(this.tagName.base.closingTagNameLocationData))
|
||||
}, this.closingElementLocationData);
|
||||
if (closingElement.name.type === 'JSXMemberExpression') {
|
||||
rangeDiff = closingElement.range[0] - openingElement.range[0] + '/'.length;
|
||||
|
@ -2313,7 +2318,7 @@
|
|||
return {openingElement, closingElement};
|
||||
}
|
||||
|
||||
fragmentAstProperties() {
|
||||
fragmentAstProperties(o) {
|
||||
var closingFragment, openingFragment;
|
||||
openingFragment = Object.assign({
|
||||
type: 'JSXOpeningFragment'
|
||||
|
@ -2324,8 +2329,8 @@
|
|||
return {openingFragment, closingFragment};
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
return Object.assign(this.isFragment() ? this.fragmentAstProperties() : this.elementAstProperties(), {
|
||||
astProperties(o) {
|
||||
return Object.assign(this.isFragment() ? this.fragmentAstProperties(o) : this.elementAstProperties(o), {
|
||||
children: []
|
||||
});
|
||||
}
|
||||
|
@ -2532,17 +2537,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var arg;
|
||||
return {
|
||||
callee: this.variable.ast(),
|
||||
callee: this.variable.ast(o),
|
||||
arguments: (function() {
|
||||
var j, len1, ref1, results;
|
||||
ref1 = this.args;
|
||||
results = [];
|
||||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||
arg = ref1[j];
|
||||
results.push(arg.ast());
|
||||
results.push(arg.ast(o));
|
||||
}
|
||||
return results;
|
||||
}).call(this),
|
||||
|
@ -2729,11 +2734,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
ast() {
|
||||
ast(o) {
|
||||
// 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
|
||||
// the `MemberExpression` node.
|
||||
return this.name.ast();
|
||||
return this.name.ast(o);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -2764,13 +2769,13 @@
|
|||
return this.index.shouldCache();
|
||||
}
|
||||
|
||||
ast() {
|
||||
ast(o) {
|
||||
// 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
|
||||
// the `MemberExpression` node. The fact that the `MemberExpression`’s
|
||||
// `property` is an Index means that `computed` is `true` for the
|
||||
// `MemberExpression`.
|
||||
return this.index.ast();
|
||||
return this.index.ast(o);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -2900,11 +2905,11 @@
|
|||
return [this.makeCode(`(function() {${pre}\n${idt}for (${body})${post}}).apply(this${args != null ? args : ''})`)];
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var ref1, ref2, ref3, ref4;
|
||||
return {
|
||||
from: (ref1 = (ref2 = this.from) != null ? ref2.ast() : void 0) != null ? ref1 : null,
|
||||
to: (ref3 = (ref4 = this.to) != null ? ref4.ast() : void 0) != null ? ref3 : null,
|
||||
from: (ref1 = (ref2 = this.from) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
||||
to: (ref3 = (ref4 = this.to) != null ? ref4.ast(o) : void 0) != null ? ref3 : null,
|
||||
exclusive: this.exclusive
|
||||
};
|
||||
}
|
||||
|
@ -2953,8 +2958,8 @@
|
|||
return [this.makeCode(`.slice(${fragmentsToText(fromCompiled)}${toStr || ''})`)];
|
||||
}
|
||||
|
||||
ast() {
|
||||
return this.range.ast();
|
||||
ast(o) {
|
||||
return this.range.ast(o);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -3234,7 +3239,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var property;
|
||||
return {
|
||||
implicit: !!this.generated,
|
||||
|
@ -3244,7 +3249,7 @@
|
|||
results = [];
|
||||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||
property = ref1[j];
|
||||
results.push(property.ast());
|
||||
results.push(property.ast(o));
|
||||
}
|
||||
return results;
|
||||
}).call(this)
|
||||
|
@ -3286,13 +3291,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var isComputedPropertyName, keyAst, ref1, ref2;
|
||||
isComputedPropertyName = this.key instanceof Value && this.key.base instanceof ComputedPropertyName;
|
||||
keyAst = this.key.ast();
|
||||
keyAst = this.key.ast(o);
|
||||
return {
|
||||
key: keyAst,
|
||||
value: (ref1 = (ref2 = this.value) != null ? ref2.ast() : void 0) != null ? ref1 : keyAst,
|
||||
value: (ref1 = (ref2 = this.value) != null ? ref2.ast(o) : void 0) != null ? ref1 : keyAst,
|
||||
shorthand: !!this.shorthand,
|
||||
computed: !!isComputedPropertyName,
|
||||
method: false
|
||||
|
@ -3493,7 +3498,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var object;
|
||||
return {
|
||||
elements: (function() {
|
||||
|
@ -3502,7 +3507,7 @@
|
|||
results = [];
|
||||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||
object = ref1[j];
|
||||
results.push(object.ast());
|
||||
results.push(object.ast(o));
|
||||
}
|
||||
return results;
|
||||
}).call(this)
|
||||
|
@ -4003,11 +4008,11 @@
|
|||
return code;
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var ref1, ref2, ret;
|
||||
ret = {
|
||||
specifiers: (ref1 = (ref2 = this.clause) != null ? ref2.ast() : void 0) != null ? ref1 : [],
|
||||
source: this.source.ast()
|
||||
specifiers: (ref1 = (ref2 = this.clause) != null ? ref2.ast(o) : void 0) != null ? ref1 : [],
|
||||
source: this.source.ast(o)
|
||||
};
|
||||
if (this.clause) {
|
||||
ret.importKind = 'value';
|
||||
|
@ -4040,11 +4045,11 @@
|
|||
return code;
|
||||
}
|
||||
|
||||
ast() {
|
||||
ast(o) {
|
||||
var ref1, ref2;
|
||||
// The AST for `ImportClause` is the non-nested list of import specifiers
|
||||
// that will be the `specifiers` property of an `ImportDeclaration` AST
|
||||
return compact(flatten([(ref1 = this.defaultBinding) != null ? ref1.ast() : void 0, (ref2 = this.namedImports) != null ? ref2.ast() : void 0]));
|
||||
return compact(flatten([(ref1 = this.defaultBinding) != null ? ref1.ast(o) : void 0, (ref2 = this.namedImports) != null ? ref2.ast(o) : void 0]));
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -4087,13 +4092,13 @@
|
|||
};
|
||||
|
||||
exports.ExportNamedDeclaration = ExportNamedDeclaration = class ExportNamedDeclaration extends ExportDeclaration {
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var clauseAst, ref1, ref2, ret;
|
||||
ret = {
|
||||
source: (ref1 = (ref2 = this.source) != null ? ref2.ast() : void 0) != null ? ref1 : null,
|
||||
source: (ref1 = (ref2 = this.source) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
||||
exportKind: 'value'
|
||||
};
|
||||
clauseAst = this.clause.ast();
|
||||
clauseAst = this.clause.ast(o);
|
||||
if (this.clause instanceof ExportSpecifierList) {
|
||||
ret.specifiers = clauseAst;
|
||||
ret.declaration = null;
|
||||
|
@ -4107,18 +4112,18 @@
|
|||
};
|
||||
|
||||
exports.ExportDefaultDeclaration = ExportDefaultDeclaration = class ExportDefaultDeclaration extends ExportDeclaration {
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
return {
|
||||
declaration: this.clause.ast()
|
||||
declaration: this.clause.ast(o)
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.ExportAllDeclaration = ExportAllDeclaration = class ExportAllDeclaration extends ExportDeclaration {
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
return {
|
||||
source: this.source.ast(),
|
||||
source: this.source.ast(o),
|
||||
exportKind: 'value'
|
||||
};
|
||||
}
|
||||
|
@ -4162,13 +4167,13 @@
|
|||
return code;
|
||||
}
|
||||
|
||||
ast() {
|
||||
ast(o) {
|
||||
var j, len1, ref1, results, specifier;
|
||||
ref1 = this.specifiers;
|
||||
results = [];
|
||||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||
specifier = ref1[j];
|
||||
results.push(specifier.ast());
|
||||
results.push(specifier.ast(o));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
@ -4242,12 +4247,12 @@
|
|||
return super.compileNode(o);
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var originalAst, ref1, ref2;
|
||||
originalAst = this.original.ast();
|
||||
originalAst = this.original.ast(o);
|
||||
return {
|
||||
imported: originalAst,
|
||||
local: (ref1 = (ref2 = this.alias) != null ? ref2.ast() : void 0) != null ? ref1 : originalAst,
|
||||
local: (ref1 = (ref2 = this.alias) != null ? ref2.ast(o) : void 0) != null ? ref1 : originalAst,
|
||||
importKind: null
|
||||
};
|
||||
}
|
||||
|
@ -4255,18 +4260,18 @@
|
|||
};
|
||||
|
||||
exports.ImportDefaultSpecifier = ImportDefaultSpecifier = class ImportDefaultSpecifier extends ImportSpecifier {
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
return {
|
||||
local: this.original.ast()
|
||||
local: this.original.ast(o)
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.ImportNamespaceSpecifier = ImportNamespaceSpecifier = class ImportNamespaceSpecifier extends ImportSpecifier {
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
return {
|
||||
local: this.alias.ast()
|
||||
local: this.alias.ast(o)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4277,12 +4282,12 @@
|
|||
super(local, exported, 'export');
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var originalAst, ref1, ref2;
|
||||
originalAst = this.original.ast();
|
||||
originalAst = this.original.ast(o);
|
||||
return {
|
||||
local: originalAst,
|
||||
exported: (ref1 = (ref2 = this.alias) != null ? ref2.ast() : void 0) != null ? ref1 : originalAst
|
||||
exported: (ref1 = (ref2 = this.alias) != null ? ref2.ast(o) : void 0) != null ? ref1 : originalAst
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4794,11 +4799,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var ref1, ret;
|
||||
ret = {
|
||||
right: this.value.ast(),
|
||||
left: this.variable.ast()
|
||||
right: this.value.ast(o),
|
||||
left: this.variable.ast(o)
|
||||
};
|
||||
if (!this.isDefaultAssignment()) {
|
||||
ret.operator = (ref1 = this.originalContext) != null ? ref1 : '=';
|
||||
|
@ -5470,9 +5475,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
return {
|
||||
argument: this.name.ast(),
|
||||
argument: this.name.ast(o),
|
||||
postfix: this.postfix
|
||||
};
|
||||
}
|
||||
|
@ -5946,10 +5951,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
var firstAst, ref1, secondAst;
|
||||
firstAst = this.first.ast();
|
||||
secondAst = (ref1 = this.second) != null ? ref1.ast() : void 0;
|
||||
firstAst = this.first.ast(o);
|
||||
secondAst = (ref1 = this.second) != null ? ref1.ast(o) : void 0;
|
||||
switch (false) {
|
||||
case !this.isUnary():
|
||||
return {
|
||||
|
@ -6071,25 +6076,25 @@
|
|||
// A classic *try/catch/finally* block.
|
||||
exports.Try = Try = (function() {
|
||||
class Try extends Base {
|
||||
constructor(attempt, errorVariable, recovery, ensure) {
|
||||
constructor(attempt, _catch, ensure, finallyTag) {
|
||||
super();
|
||||
this.attempt = attempt;
|
||||
this.errorVariable = errorVariable;
|
||||
this.recovery = recovery;
|
||||
this.catch = _catch;
|
||||
this.ensure = ensure;
|
||||
this.finallyTag = finallyTag;
|
||||
}
|
||||
|
||||
jumps(o) {
|
||||
var ref1;
|
||||
return this.attempt.jumps(o) || ((ref1 = this.recovery) != null ? ref1.jumps(o) : void 0);
|
||||
return this.attempt.jumps(o) || ((ref1 = this.catch) != null ? ref1.jumps(o) : void 0);
|
||||
}
|
||||
|
||||
makeReturn(res) {
|
||||
if (this.attempt) {
|
||||
this.attempt = this.attempt.makeReturn(res);
|
||||
}
|
||||
if (this.recovery) {
|
||||
this.recovery = this.recovery.makeReturn(res);
|
||||
if (this.catch) {
|
||||
this.catch = this.catch.makeReturn(res);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -6097,21 +6102,36 @@
|
|||
// Compilation is more or less as you would expect -- the *finally* clause
|
||||
// is optional, the *catch* is not.
|
||||
compileNode(o) {
|
||||
var catchPart, ensurePart, generatedErrorVariableName, message, placeholder, tryPart;
|
||||
var catchPart, ensurePart, generatedErrorVariableName, originalIndent, tryPart;
|
||||
originalIndent = o.indent;
|
||||
o.indent += TAB;
|
||||
tryPart = this.attempt.compileToFragments(o, LEVEL_TOP);
|
||||
catchPart = this.recovery ? (generatedErrorVariableName = o.scope.freeVariable('error', {
|
||||
reserve: false
|
||||
}), placeholder = new IdentifierLiteral(generatedErrorVariableName), this.errorVariable ? (message = isUnassignable(this.errorVariable.unwrapAll().value), message ? this.errorVariable.error(message) : void 0, this.recovery.unshift(new Assign(this.errorVariable, placeholder))) : void 0, [].concat(this.makeCode(" catch ("), placeholder.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode(`\n${this.tab}}`))) : !(this.ensure || this.recovery) ? (generatedErrorVariableName = o.scope.freeVariable('error', {
|
||||
catchPart = this.catch ? this.catch.compileToFragments(merge(o, {
|
||||
indent: originalIndent
|
||||
}), LEVEL_TOP) : !(this.ensure || this.catch) ? (generatedErrorVariableName = o.scope.freeVariable('error', {
|
||||
reserve: false
|
||||
}), [this.makeCode(` catch (${generatedErrorVariableName}) {}`)]) : [];
|
||||
ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode(`\n${this.tab}}`)) : [];
|
||||
return [].concat(this.makeCode(`${this.tab}try {\n`), tryPart, this.makeCode(`\n${this.tab}}`), catchPart, ensurePart);
|
||||
}
|
||||
|
||||
astType() {
|
||||
return 'TryStatement';
|
||||
}
|
||||
|
||||
astProperties(o) {
|
||||
var ref1, ref2;
|
||||
return {
|
||||
block: this.attempt.ast(o),
|
||||
handler: (ref1 = (ref2 = this.catch) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
||||
// 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
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Try.prototype.children = ['attempt', 'recovery', 'ensure'];
|
||||
Try.prototype.children = ['attempt', 'catch', 'ensure'];
|
||||
|
||||
Try.prototype.isStatement = YES;
|
||||
|
||||
|
@ -6119,6 +6139,68 @@
|
|||
|
||||
}).call(this);
|
||||
|
||||
exports.Catch = Catch = (function() {
|
||||
class Catch extends Base {
|
||||
constructor(recovery, errorVariable) {
|
||||
var base1, ref1;
|
||||
super();
|
||||
this.recovery = recovery;
|
||||
this.errorVariable = errorVariable;
|
||||
if ((ref1 = this.errorVariable) != null) {
|
||||
if (typeof (base1 = ref1.unwrap()).propagateLhs === "function") {
|
||||
base1.propagateLhs(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jumps(o) {
|
||||
return this.recovery.jumps(o);
|
||||
}
|
||||
|
||||
makeReturn(res) {
|
||||
this.recovery = this.recovery.makeReturn(res);
|
||||
return this;
|
||||
}
|
||||
|
||||
compileNode(o) {
|
||||
var generatedErrorVariableName, message, placeholder;
|
||||
o.indent += TAB;
|
||||
generatedErrorVariableName = o.scope.freeVariable('error', {
|
||||
reserve: false
|
||||
});
|
||||
placeholder = new IdentifierLiteral(generatedErrorVariableName);
|
||||
if (this.errorVariable) {
|
||||
message = isUnassignable(this.errorVariable.unwrapAll().value);
|
||||
if (message) {
|
||||
this.errorVariable.error(message);
|
||||
}
|
||||
this.recovery.unshift(new Assign(this.errorVariable, placeholder));
|
||||
}
|
||||
return [].concat(this.makeCode(" catch ("), placeholder.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode(`\n${this.tab}}`));
|
||||
}
|
||||
|
||||
astType() {
|
||||
return 'CatchClause';
|
||||
}
|
||||
|
||||
astProperties(o) {
|
||||
var ref1, ref2;
|
||||
return {
|
||||
param: (ref1 = (ref2 = this.errorVariable) != null ? ref2.ast(o) : void 0) != null ? ref1 : null,
|
||||
body: this.recovery.ast(o)
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Catch.prototype.children = ['recovery', 'errorVariable'];
|
||||
|
||||
Catch.prototype.isStatement = YES;
|
||||
|
||||
return Catch;
|
||||
|
||||
}).call(this);
|
||||
|
||||
//### Throw
|
||||
|
||||
// Simple node to throw an exception.
|
||||
|
@ -6142,9 +6224,9 @@
|
|||
return 'ThrowStatement';
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
return {
|
||||
argument: this.expression.ast()
|
||||
argument: this.expression.ast(o)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -6217,9 +6299,9 @@
|
|||
return 'UnaryExpression';
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
astProperties(o) {
|
||||
return {
|
||||
argument: this.expression.ast(),
|
||||
argument: this.expression.ast(o),
|
||||
operator: '?',
|
||||
prefix: false
|
||||
};
|
||||
|
@ -6284,8 +6366,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
ast() {
|
||||
return this.body.unwrap().ast();
|
||||
ast(o) {
|
||||
return this.body.unwrap().ast(o);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -629,16 +629,16 @@ grammar =
|
|||
# The variants of *try/catch/finally* exception handling blocks.
|
||||
Try: [
|
||||
o 'TRY Block', -> new Try $2
|
||||
o 'TRY Block Catch', -> new Try $2, $3[0], $3[1]
|
||||
o 'TRY Block FINALLY Block', -> new Try $2, null, null, $4
|
||||
o 'TRY Block Catch FINALLY Block', -> new Try $2, $3[0], $3[1], $5
|
||||
o 'TRY Block Catch', -> new Try $2, $3
|
||||
o 'TRY Block FINALLY Block', -> new Try $2, null, $4, LOC(3)(new Literal $3)
|
||||
o 'TRY Block Catch FINALLY Block', -> new Try $2, $3, $5, LOC(4)(new Literal $4)
|
||||
]
|
||||
|
||||
# A catch clause names its error and runs a block of code.
|
||||
Catch: [
|
||||
o 'CATCH Identifier Block', -> [$2, $3]
|
||||
o 'CATCH Object Block', -> [LOC(2)(new Value($2)), $3]
|
||||
o 'CATCH Block', -> [null, $2]
|
||||
o 'CATCH Identifier Block', -> new Catch $3, $2
|
||||
o 'CATCH Object Block', -> new Catch $3, LOC(2)(new Value($2))
|
||||
o 'CATCH Block', -> new Catch $2
|
||||
]
|
||||
|
||||
# Throw an exception object.
|
||||
|
|
243
src/nodes.coffee
243
src/nodes.coffee
|
@ -270,7 +270,7 @@ exports.Base = class Base
|
|||
# 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)
|
||||
# as closely as possible, for improved interoperability with other tools.
|
||||
ast: ->
|
||||
ast: (o) ->
|
||||
# Every abstract syntax tree node object has four categories of properties:
|
||||
# - type, stored in the `type` field and a string like `NumberLiteral`.
|
||||
# - location data, stored in the `loc`, `start`, `end` and `range` fields.
|
||||
|
@ -279,7 +279,7 @@ exports.Base = class Base
|
|||
# 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
|
||||
# separate methods for returning each category, that we merge together here.
|
||||
Object.assign {}, @astProperties(), {type: @astType()}, @astLocationData()
|
||||
Object.assign {}, {type: @astType()}, @astProperties(o), @astLocationData()
|
||||
|
||||
# By default, a node class has no specific properties.
|
||||
astProperties: -> {}
|
||||
|
@ -491,9 +491,10 @@ exports.Root = class Root extends Base
|
|||
|
||||
astType: -> 'File'
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
@body.isRootBlock = yes
|
||||
return
|
||||
program: Object.assign @body.ast(), @astLocationData()
|
||||
program: Object.assign @body.ast(o), @astLocationData()
|
||||
comments: []
|
||||
|
||||
#### Block
|
||||
|
@ -773,19 +774,23 @@ exports.Block = class Block extends Base
|
|||
return nodes[0] if nodes.length is 1 and nodes[0] instanceof Block
|
||||
new Block nodes
|
||||
|
||||
astType: -> 'Program'
|
||||
astType: ->
|
||||
if @isRootBlock
|
||||
'Program'
|
||||
else
|
||||
'BlockStatement'
|
||||
|
||||
astProperties: (o) ->
|
||||
body = []
|
||||
for expression in @expressions
|
||||
# If an expression is a statement, it can be added to the body as is.
|
||||
if expression.isStatement o
|
||||
body.push expression.ast()
|
||||
body.push expression.ast o
|
||||
# Otherwise, we need to wrap it in an `ExpressionStatement` AST node.
|
||||
else
|
||||
body.push Object.assign
|
||||
type: 'ExpressionStatement'
|
||||
expression: expression.ast()
|
||||
expression: expression.ast o
|
||||
,
|
||||
expression.astLocationData()
|
||||
|
||||
|
@ -994,8 +999,8 @@ exports.ComputedPropertyName = class ComputedPropertyName extends PropertyName
|
|||
compileNode: (o) ->
|
||||
[@makeCode('['), @value.compileToFragments(o, LEVEL_LIST)..., @makeCode(']')]
|
||||
|
||||
ast: ->
|
||||
@value.ast()
|
||||
ast: (o) ->
|
||||
@value.ast o
|
||||
|
||||
exports.StatementLiteral = class StatementLiteral extends Literal
|
||||
isStatement: YES
|
||||
|
@ -1295,13 +1300,13 @@ exports.Value = class Value extends Base
|
|||
mergeLocationData @base.locationData, initialProperties[initialProperties.length - 1].locationData
|
||||
object
|
||||
|
||||
ast: ->
|
||||
ast: (o) ->
|
||||
# If the `Value` has no properties, the AST node is just whatever this
|
||||
# node’s `base` is.
|
||||
return @base.ast() unless @hasProperties()
|
||||
return @base.ast o unless @hasProperties()
|
||||
# Otherwise, call `Base::ast` which in turn calls the `astType` and
|
||||
# `astProperties` methods below.
|
||||
super()
|
||||
super o
|
||||
|
||||
astType: ->
|
||||
if @isCSXTag()
|
||||
|
@ -1312,12 +1317,12 @@ exports.Value = class Value extends Base
|
|||
# If this `Value` has properties, the *last* property (e.g. `c` in `a.b.c`)
|
||||
# becomes the `property`, and the preceding properties (e.g. `a.b`) become
|
||||
# a child `Value` node assigned to the `object` property.
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
[..., property] = @properties
|
||||
property.name.csx = yes if @isCSXTag()
|
||||
return
|
||||
object: @object().ast()
|
||||
property: property.ast()
|
||||
object: @object().ast o
|
||||
property: property.ast o
|
||||
computed: property instanceof Index or property.name?.unwrap() not instanceof PropertyName
|
||||
optional: !!property.soak
|
||||
shorthand: !!property.shorthand
|
||||
|
@ -1501,7 +1506,7 @@ exports.CSXElement = class CSXElement extends Base
|
|||
isFragment: ->
|
||||
!@tagName.base.value.length
|
||||
|
||||
ast: ->
|
||||
ast: (o) ->
|
||||
# The location data spanning the opening element < ... > is captured by
|
||||
# the generated Arr which contains the element's attributes
|
||||
@openingElementLocationData = jisonLocationDataToAstLocationData @attributes.locationData
|
||||
|
@ -1514,7 +1519,7 @@ exports.CSXElement = class CSXElement extends Base
|
|||
jisonLocationDataToAstLocationData tagName.closingTagClosingBracketLocationData
|
||||
)
|
||||
|
||||
super()
|
||||
super o
|
||||
|
||||
astType: ->
|
||||
if @isFragment()
|
||||
|
@ -1522,12 +1527,12 @@ exports.CSXElement = class CSXElement extends Base
|
|||
else
|
||||
'JSXElement'
|
||||
|
||||
elementAstProperties: ->
|
||||
elementAstProperties: (o) ->
|
||||
openingElement = Object.assign {
|
||||
type: 'JSXOpeningElement'
|
||||
name: @tagName.unwrap().ast()
|
||||
name: @tagName.unwrap().ast o
|
||||
selfClosing: not @closingElementLocationData?
|
||||
attributes: @attributes.ast()
|
||||
attributes: @attributes.ast o
|
||||
}, @openingElementLocationData
|
||||
|
||||
closingElement = null
|
||||
|
@ -1535,7 +1540,7 @@ exports.CSXElement = class CSXElement extends Base
|
|||
closingElement = Object.assign {
|
||||
type: 'JSXClosingElement'
|
||||
name: Object.assign(
|
||||
@tagName.unwrap().ast(),
|
||||
@tagName.unwrap().ast(o),
|
||||
jisonLocationDataToAstLocationData @tagName.base.closingTagNameLocationData
|
||||
)
|
||||
}, @closingElementLocationData
|
||||
|
@ -1563,7 +1568,7 @@ exports.CSXElement = class CSXElement extends Base
|
|||
|
||||
{openingElement, closingElement}
|
||||
|
||||
fragmentAstProperties: ->
|
||||
fragmentAstProperties: (o) ->
|
||||
openingFragment = Object.assign {
|
||||
type: 'JSXOpeningFragment'
|
||||
}, @openingElementLocationData
|
||||
|
@ -1574,12 +1579,12 @@ exports.CSXElement = class CSXElement extends Base
|
|||
|
||||
{openingFragment, closingFragment}
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
Object.assign(
|
||||
if @isFragment()
|
||||
@fragmentAstProperties()
|
||||
@fragmentAstProperties o
|
||||
else
|
||||
@elementAstProperties()
|
||||
@elementAstProperties o
|
||||
,
|
||||
children: []
|
||||
)
|
||||
|
@ -1723,10 +1728,10 @@ exports.Call = class Call extends Base
|
|||
else
|
||||
'CallExpression'
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return
|
||||
callee: @variable.ast()
|
||||
arguments: arg.ast() for arg in @args
|
||||
callee: @variable.ast o
|
||||
arguments: arg.ast(o) for arg in @args
|
||||
optional: !!@soak
|
||||
implicit: !!@implicit
|
||||
|
||||
|
@ -1846,11 +1851,11 @@ exports.Access = class Access extends Base
|
|||
|
||||
shouldCache: NO
|
||||
|
||||
ast: ->
|
||||
ast: (o) ->
|
||||
# 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
|
||||
# the `MemberExpression` node.
|
||||
@name.ast()
|
||||
@name.ast o
|
||||
|
||||
#### Index
|
||||
|
||||
|
@ -1867,13 +1872,13 @@ exports.Index = class Index extends Base
|
|||
shouldCache: ->
|
||||
@index.shouldCache()
|
||||
|
||||
ast: ->
|
||||
ast: (o) ->
|
||||
# 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
|
||||
# the `MemberExpression` node. The fact that the `MemberExpression`’s
|
||||
# `property` is an Index means that `computed` is `true` for the
|
||||
# `MemberExpression`.
|
||||
@index.ast()
|
||||
@index.ast o
|
||||
|
||||
#### Range
|
||||
|
||||
|
@ -1987,10 +1992,10 @@ exports.Range = class Range extends Base
|
|||
args = ', arguments' if hasArgs(@from) or hasArgs(@to)
|
||||
[@makeCode "(function() {#{pre}\n#{idt}for (#{body})#{post}}).apply(this#{args ? ''})"]
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return {
|
||||
from: @from?.ast() ? null
|
||||
to: @to?.ast() ? null
|
||||
from: @from?.ast(o) ? null
|
||||
to: @to?.ast(o) ? null
|
||||
@exclusive
|
||||
}
|
||||
|
||||
|
@ -2030,8 +2035,8 @@ exports.Slice = class Slice extends Base
|
|||
"+#{fragmentsToText compiled} + 1 || 9e9"
|
||||
[@makeCode ".slice(#{ fragmentsToText fromCompiled }#{ toStr or '' })"]
|
||||
|
||||
ast: ->
|
||||
@range.ast()
|
||||
ast: (o) ->
|
||||
@range.ast(o)
|
||||
|
||||
#### Obj
|
||||
|
||||
|
@ -2198,11 +2203,11 @@ exports.Obj = class Obj extends Base
|
|||
else
|
||||
'ObjectExpression'
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return
|
||||
implicit: !!@generated
|
||||
properties:
|
||||
property.ast() for property in @expandProperties()
|
||||
property.ast(o) for property in @expandProperties()
|
||||
|
||||
exports.ObjectProperty = class ObjectProperty extends Base
|
||||
constructor: ({key, fromAssign}) ->
|
||||
|
@ -2223,13 +2228,13 @@ exports.ObjectProperty = class ObjectProperty extends Base
|
|||
@shorthand = yes
|
||||
@locationData = key.locationData
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
isComputedPropertyName = @key instanceof Value and @key.base instanceof ComputedPropertyName
|
||||
keyAst = @key.ast()
|
||||
keyAst = @key.ast o
|
||||
|
||||
return
|
||||
key: keyAst
|
||||
value: @value?.ast() ? keyAst
|
||||
value: @value?.ast(o) ? keyAst
|
||||
shorthand: !!@shorthand
|
||||
computed: !!isComputedPropertyName
|
||||
method: no
|
||||
|
@ -2341,10 +2346,10 @@ exports.Arr = class Arr extends Base
|
|||
else
|
||||
'ArrayExpression'
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return
|
||||
elements:
|
||||
object.ast() for object in @objects
|
||||
object.ast(o) for object in @objects
|
||||
|
||||
#### Class
|
||||
|
||||
|
@ -2693,10 +2698,10 @@ exports.ImportDeclaration = class ImportDeclaration extends ModuleDeclaration
|
|||
code.push @makeCode ';'
|
||||
code
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
ret =
|
||||
specifiers: @clause?.ast() ? []
|
||||
source: @source.ast()
|
||||
specifiers: @clause?.ast(o) ? []
|
||||
source: @source.ast o
|
||||
ret.importKind = 'value' if @clause
|
||||
ret
|
||||
|
||||
|
@ -2718,12 +2723,12 @@ exports.ImportClause = class ImportClause extends Base
|
|||
|
||||
code
|
||||
|
||||
ast: ->
|
||||
ast: (o) ->
|
||||
# The AST for `ImportClause` is the non-nested list of import specifiers
|
||||
# that will be the `specifiers` property of an `ImportDeclaration` AST
|
||||
compact flatten [
|
||||
@defaultBinding?.ast()
|
||||
@namedImports?.ast()
|
||||
@defaultBinding?.ast o
|
||||
@namedImports?.ast o
|
||||
]
|
||||
|
||||
exports.ExportDeclaration = class ExportDeclaration extends ModuleDeclaration
|
||||
|
@ -2753,11 +2758,11 @@ exports.ExportDeclaration = class ExportDeclaration extends ModuleDeclaration
|
|||
code
|
||||
|
||||
exports.ExportNamedDeclaration = class ExportNamedDeclaration extends ExportDeclaration
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
ret =
|
||||
source: @source?.ast() ? null
|
||||
source: @source?.ast(o) ? null
|
||||
exportKind: 'value'
|
||||
clauseAst = @clause.ast()
|
||||
clauseAst = @clause.ast o
|
||||
if @clause instanceof ExportSpecifierList
|
||||
ret.specifiers = clauseAst
|
||||
ret.declaration = null
|
||||
|
@ -2767,14 +2772,14 @@ exports.ExportNamedDeclaration = class ExportNamedDeclaration extends ExportDecl
|
|||
ret
|
||||
|
||||
exports.ExportDefaultDeclaration = class ExportDefaultDeclaration extends ExportDeclaration
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return
|
||||
declaration: @clause.ast()
|
||||
declaration: @clause.ast o
|
||||
|
||||
exports.ExportAllDeclaration = class ExportAllDeclaration extends ExportDeclaration
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return
|
||||
source: @source.ast()
|
||||
source: @source.ast o
|
||||
exportKind: 'value'
|
||||
|
||||
exports.ModuleSpecifierList = class ModuleSpecifierList extends Base
|
||||
|
@ -2798,8 +2803,8 @@ exports.ModuleSpecifierList = class ModuleSpecifierList extends Base
|
|||
code.push @makeCode '{}'
|
||||
code
|
||||
|
||||
ast: ->
|
||||
specifier.ast() for specifier in @specifiers
|
||||
ast: (o) ->
|
||||
specifier.ast(o) for specifier in @specifiers
|
||||
|
||||
exports.ImportSpecifierList = class ImportSpecifierList extends ModuleSpecifierList
|
||||
|
||||
|
@ -2839,32 +2844,32 @@ exports.ImportSpecifier = class ImportSpecifier extends ModuleSpecifier
|
|||
o.importedSymbols.push @identifier
|
||||
super o
|
||||
|
||||
astProperties: ->
|
||||
originalAst = @original.ast()
|
||||
astProperties: (o) ->
|
||||
originalAst = @original.ast o
|
||||
return
|
||||
imported: originalAst
|
||||
local: @alias?.ast() ? originalAst
|
||||
local: @alias?.ast(o) ? originalAst
|
||||
importKind: null
|
||||
|
||||
exports.ImportDefaultSpecifier = class ImportDefaultSpecifier extends ImportSpecifier
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return
|
||||
local: @original.ast()
|
||||
local: @original.ast o
|
||||
|
||||
exports.ImportNamespaceSpecifier = class ImportNamespaceSpecifier extends ImportSpecifier
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return
|
||||
local: @alias.ast()
|
||||
local: @alias.ast o
|
||||
|
||||
exports.ExportSpecifier = class ExportSpecifier extends ModuleSpecifier
|
||||
constructor: (local, exported) ->
|
||||
super local, exported, 'export'
|
||||
|
||||
astProperties: ->
|
||||
originalAst = @original.ast()
|
||||
astProperties: (o) ->
|
||||
originalAst = @original.ast o
|
||||
return
|
||||
local: originalAst
|
||||
exported: @alias?.ast() ? originalAst
|
||||
exported: @alias?.ast(o) ? originalAst
|
||||
|
||||
#### Assign
|
||||
|
||||
|
@ -3217,10 +3222,10 @@ exports.Assign = class Assign extends Base
|
|||
else
|
||||
'AssignmentExpression'
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
ret =
|
||||
right: @value.ast()
|
||||
left: @variable.ast()
|
||||
right: @value.ast o
|
||||
left: @variable.ast o
|
||||
|
||||
unless @isDefaultAssignment()
|
||||
ret.operator = @originalContext ? '='
|
||||
|
@ -3686,8 +3691,8 @@ exports.Splat = class Splat extends Base
|
|||
else
|
||||
'SpreadElement'
|
||||
|
||||
astProperties: -> {
|
||||
argument: @name.ast()
|
||||
astProperties: (o) -> {
|
||||
argument: @name.ast o
|
||||
@postfix
|
||||
}
|
||||
|
||||
|
@ -4017,9 +4022,9 @@ exports.Op = class Op extends Base
|
|||
if @isUnary() then 'UnaryExpression'
|
||||
else 'BinaryExpression'
|
||||
|
||||
astProperties: ->
|
||||
firstAst = @first.ast()
|
||||
secondAst = @second?.ast()
|
||||
astProperties: (o) ->
|
||||
firstAst = @first.ast o
|
||||
secondAst = @second?.ast o
|
||||
switch
|
||||
when @isUnary()
|
||||
return
|
||||
|
@ -4074,36 +4079,30 @@ exports.In = class In extends Base
|
|||
|
||||
# A classic *try/catch/finally* block.
|
||||
exports.Try = class Try extends Base
|
||||
constructor: (@attempt, @errorVariable, @recovery, @ensure) ->
|
||||
constructor: (@attempt, @catch, @ensure, @finallyTag) ->
|
||||
super()
|
||||
|
||||
children: ['attempt', 'recovery', 'ensure']
|
||||
children: ['attempt', 'catch', 'ensure']
|
||||
|
||||
isStatement: YES
|
||||
|
||||
jumps: (o) -> @attempt.jumps(o) or @recovery?.jumps(o)
|
||||
jumps: (o) -> @attempt.jumps(o) or @catch?.jumps(o)
|
||||
|
||||
makeReturn: (res) ->
|
||||
@attempt = @attempt .makeReturn res if @attempt
|
||||
@recovery = @recovery.makeReturn res if @recovery
|
||||
@attempt = @attempt.makeReturn res if @attempt
|
||||
@catch = @catch .makeReturn res if @catch
|
||||
this
|
||||
|
||||
# Compilation is more or less as you would expect -- the *finally* clause
|
||||
# is optional, the *catch* is not.
|
||||
compileNode: (o) ->
|
||||
originalIndent = o.indent
|
||||
o.indent += TAB
|
||||
tryPart = @attempt.compileToFragments o, LEVEL_TOP
|
||||
|
||||
catchPart = if @recovery
|
||||
generatedErrorVariableName = o.scope.freeVariable 'error', reserve: no
|
||||
placeholder = new IdentifierLiteral generatedErrorVariableName
|
||||
if @errorVariable
|
||||
message = isUnassignable @errorVariable.unwrapAll().value
|
||||
@errorVariable.error message if message
|
||||
@recovery.unshift new Assign @errorVariable, placeholder
|
||||
[].concat @makeCode(" catch ("), placeholder.compileToFragments(o), @makeCode(") {\n"),
|
||||
@recovery.compileToFragments(o, LEVEL_TOP), @makeCode("\n#{@tab}}")
|
||||
else unless @ensure or @recovery
|
||||
catchPart = if @catch
|
||||
@catch.compileToFragments merge(o, indent: originalIndent), LEVEL_TOP
|
||||
else unless @ensure or @catch
|
||||
generatedErrorVariableName = o.scope.freeVariable 'error', reserve: no
|
||||
[@makeCode(" catch (#{generatedErrorVariableName}) {}")]
|
||||
else
|
||||
|
@ -4116,6 +4115,56 @@ exports.Try = class Try extends Base
|
|||
tryPart,
|
||||
@makeCode("\n#{@tab}}"), catchPart, ensurePart
|
||||
|
||||
astType: -> 'TryStatement'
|
||||
|
||||
astProperties: (o) ->
|
||||
return
|
||||
block: @attempt.ast o
|
||||
handler: @catch?.ast(o) ? null
|
||||
finalizer:
|
||||
if @ensure?
|
||||
Object.assign @ensure.ast(o),
|
||||
# Include `finally` keyword in location data.
|
||||
mergeAstLocationData(
|
||||
jisonLocationDataToAstLocationData(@finallyTag.locationData),
|
||||
@ensure.astLocationData()
|
||||
)
|
||||
else
|
||||
null
|
||||
|
||||
exports.Catch = class Catch extends Base
|
||||
constructor: (@recovery, @errorVariable) ->
|
||||
super()
|
||||
@errorVariable?.unwrap().propagateLhs? yes
|
||||
|
||||
children: ['recovery', 'errorVariable']
|
||||
|
||||
isStatement: YES
|
||||
|
||||
jumps: (o) -> @recovery.jumps(o)
|
||||
|
||||
makeReturn: (res) ->
|
||||
@recovery = @recovery.makeReturn res
|
||||
this
|
||||
|
||||
compileNode: (o) ->
|
||||
o.indent += TAB
|
||||
generatedErrorVariableName = o.scope.freeVariable 'error', reserve: no
|
||||
placeholder = new IdentifierLiteral generatedErrorVariableName
|
||||
if @errorVariable
|
||||
message = isUnassignable @errorVariable.unwrapAll().value
|
||||
@errorVariable.error message if message
|
||||
@recovery.unshift new Assign @errorVariable, placeholder
|
||||
[].concat @makeCode(" catch ("), placeholder.compileToFragments(o), @makeCode(") {\n"),
|
||||
@recovery.compileToFragments(o, LEVEL_TOP), @makeCode("\n#{@tab}}")
|
||||
|
||||
astType: -> 'CatchClause'
|
||||
|
||||
astProperties: (o) ->
|
||||
return
|
||||
param: @errorVariable?.ast(o) ? null
|
||||
body: @recovery.ast o
|
||||
|
||||
#### Throw
|
||||
|
||||
# Simple node to throw an exception.
|
||||
|
@ -4140,9 +4189,9 @@ exports.Throw = class Throw extends Base
|
|||
|
||||
astType: -> 'ThrowStatement'
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return
|
||||
argument: @expression.ast()
|
||||
argument: @expression.ast o
|
||||
|
||||
#### Existence
|
||||
|
||||
|
@ -4188,9 +4237,9 @@ exports.Existence = class Existence extends Base
|
|||
|
||||
astType: -> 'UnaryExpression'
|
||||
|
||||
astProperties: ->
|
||||
astProperties: (o) ->
|
||||
return
|
||||
argument: @expression.ast()
|
||||
argument: @expression.ast o
|
||||
operator: '?'
|
||||
prefix: no
|
||||
|
||||
|
@ -4231,7 +4280,7 @@ exports.Parens = class Parens extends Base
|
|||
return @wrapInBraces fragments if @csxAttribute
|
||||
if bare then fragments else @wrapInParentheses fragments
|
||||
|
||||
ast: -> @body.unwrap().ast()
|
||||
ast: (o) -> @body.unwrap().ast o
|
||||
|
||||
#### StringWithInterpolations
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@ looseArray = (arr) ->
|
|||
enumerable: no
|
||||
arr
|
||||
|
||||
testExpression = (code, expected) ->
|
||||
ast = getAstExpression code
|
||||
testAgainstExpected = (ast, expected) ->
|
||||
if expected?
|
||||
deepStrictIncludeExpectedProperties ast, expected
|
||||
else
|
||||
|
@ -37,6 +36,13 @@ testExpression = (code, expected) ->
|
|||
# parameter to see what the current AST generation is for your input code.
|
||||
console.log inspect ast
|
||||
|
||||
testExpression = (code, expected) ->
|
||||
ast = getAstExpression code
|
||||
testAgainstExpected ast, expected
|
||||
|
||||
testStatement = (code, expected) ->
|
||||
ast = getAstStatement code
|
||||
testAgainstExpected ast, expected
|
||||
|
||||
test 'Confirm functionality of `deepStrictIncludeExpectedProperties`', ->
|
||||
actual =
|
||||
|
@ -346,13 +352,13 @@ test "AST as expected for ComputedPropertyName node", ->
|
|||
implicit: yes
|
||||
|
||||
test "AST as expected for StatementLiteral node", ->
|
||||
testExpression 'break',
|
||||
testStatement 'break',
|
||||
type: 'BreakStatement'
|
||||
|
||||
testExpression 'continue',
|
||||
testStatement 'continue',
|
||||
type: 'ContinueStatement'
|
||||
|
||||
testExpression 'debugger',
|
||||
testStatement 'debugger',
|
||||
type: 'DebuggerStatement'
|
||||
|
||||
test "AST as expected for ThisLiteral node", ->
|
||||
|
@ -1030,7 +1036,7 @@ test "AST as expected for Arr node", ->
|
|||
# ]
|
||||
|
||||
test "AST as expected for ModuleDeclaration node", ->
|
||||
testExpression 'export {X}',
|
||||
testStatement 'export {X}',
|
||||
type: 'ExportNamedDeclaration'
|
||||
declaration: null
|
||||
specifiers: [
|
||||
|
@ -1045,7 +1051,7 @@ test "AST as expected for ModuleDeclaration node", ->
|
|||
source: null
|
||||
exportKind: 'value'
|
||||
|
||||
testExpression 'import X from "."',
|
||||
testStatement 'import X from "."',
|
||||
type: 'ImportDeclaration'
|
||||
specifiers: [
|
||||
type: 'ImportDefaultSpecifier'
|
||||
|
@ -1059,7 +1065,7 @@ test "AST as expected for ModuleDeclaration node", ->
|
|||
value: '.'
|
||||
|
||||
test "AST as expected for ImportDeclaration node", ->
|
||||
testExpression 'import React, {Component} from "react"',
|
||||
testStatement 'import React, {Component} from "react"',
|
||||
type: 'ImportDeclaration'
|
||||
specifiers: [
|
||||
type: 'ImportDefaultSpecifier'
|
||||
|
@ -1084,14 +1090,14 @@ test "AST as expected for ImportDeclaration node", ->
|
|||
raw: '"react"'
|
||||
|
||||
test "AST as expected for ExportNamedDeclaration node", ->
|
||||
testExpression 'export {}',
|
||||
testStatement 'export {}',
|
||||
type: 'ExportNamedDeclaration'
|
||||
declaration: null
|
||||
specifiers: []
|
||||
source: null
|
||||
exportKind: 'value'
|
||||
|
||||
# testExpression 'export fn = ->',
|
||||
# testStatement 'export fn = ->',
|
||||
# type: 'ExportNamedDeclaration'
|
||||
# clause:
|
||||
# type: 'Assign'
|
||||
|
@ -1100,9 +1106,9 @@ test "AST as expected for ExportNamedDeclaration node", ->
|
|||
# value:
|
||||
# type: 'Code'
|
||||
|
||||
# testExpression 'export class A',
|
||||
# testStatement 'export class A',
|
||||
|
||||
testExpression 'export {x as y, z as default}',
|
||||
testStatement 'export {x as y, z as default}',
|
||||
type: 'ExportNamedDeclaration'
|
||||
declaration: null
|
||||
specifiers: [
|
||||
|
@ -1125,7 +1131,7 @@ test "AST as expected for ExportNamedDeclaration node", ->
|
|||
source: null
|
||||
exportKind: 'value'
|
||||
|
||||
testExpression 'export {default, default as b} from "./abc"',
|
||||
testStatement 'export {default, default as b} from "./abc"',
|
||||
type: 'ExportNamedDeclaration'
|
||||
declaration: null
|
||||
specifiers: [
|
||||
|
@ -1153,12 +1159,12 @@ test "AST as expected for ExportNamedDeclaration node", ->
|
|||
exportKind: 'value'
|
||||
|
||||
test "AST as expected for ExportDefaultDeclaration node", ->
|
||||
# testExpression 'export default class',
|
||||
# testStatement 'export default class',
|
||||
# type: 'ExportDefaultDeclaration'
|
||||
# clause:
|
||||
# type: 'Class'
|
||||
|
||||
testExpression 'export default "abc"',
|
||||
testStatement 'export default "abc"',
|
||||
type: 'ExportDefaultDeclaration'
|
||||
declaration:
|
||||
type: 'StringLiteral'
|
||||
|
@ -1167,7 +1173,7 @@ test "AST as expected for ExportDefaultDeclaration node", ->
|
|||
raw: '"abc"'
|
||||
|
||||
test "AST as expected for ExportAllDeclaration node", ->
|
||||
testExpression 'export * from "module-name"',
|
||||
testStatement 'export * from "module-name"',
|
||||
type: 'ExportAllDeclaration'
|
||||
source:
|
||||
type: 'StringLiteral'
|
||||
|
@ -1177,7 +1183,7 @@ test "AST as expected for ExportAllDeclaration node", ->
|
|||
exportKind: 'value'
|
||||
|
||||
test "AST as expected for ExportSpecifierList node", ->
|
||||
testExpression 'export {a, b, c}',
|
||||
testStatement 'export {a, b, c}',
|
||||
type: 'ExportNamedDeclaration'
|
||||
declaration: null
|
||||
specifiers: [
|
||||
|
@ -1207,7 +1213,7 @@ test "AST as expected for ExportSpecifierList node", ->
|
|||
]
|
||||
|
||||
test "AST as expected for ImportDefaultSpecifier node", ->
|
||||
testExpression 'import React from "react"',
|
||||
testStatement 'import React from "react"',
|
||||
type: 'ImportDeclaration'
|
||||
specifiers: [
|
||||
type: 'ImportDefaultSpecifier'
|
||||
|
@ -1221,7 +1227,7 @@ test "AST as expected for ImportDefaultSpecifier node", ->
|
|||
value: 'react'
|
||||
|
||||
test "AST as expected for ImportNamespaceSpecifier node", ->
|
||||
testExpression 'import * as React from "react"',
|
||||
testStatement 'import * as React from "react"',
|
||||
type: 'ImportDeclaration'
|
||||
specifiers: [
|
||||
type: 'ImportNamespaceSpecifier'
|
||||
|
@ -1234,7 +1240,7 @@ test "AST as expected for ImportNamespaceSpecifier node", ->
|
|||
type: 'StringLiteral'
|
||||
value: 'react'
|
||||
|
||||
testExpression 'import React, * as ReactStar from "react"',
|
||||
testStatement 'import React, * as ReactStar from "react"',
|
||||
type: 'ImportDeclaration'
|
||||
specifiers: [
|
||||
type: 'ImportDefaultSpecifier'
|
||||
|
@ -1685,24 +1691,102 @@ test "AST as expected for Op node", ->
|
|||
# type: 'NumberLiteral'
|
||||
# value: '2'
|
||||
|
||||
# test "AST as expected for Try node", ->
|
||||
# testExpression 'try cappuccino',
|
||||
# type: 'Try'
|
||||
# attempt:
|
||||
# type: 'Value'
|
||||
# recovery: undefined
|
||||
test "AST as expected for Try node", ->
|
||||
testStatement 'try cappuccino',
|
||||
type: 'TryStatement'
|
||||
block:
|
||||
type: 'BlockStatement'
|
||||
body: [
|
||||
type: 'ExpressionStatement'
|
||||
expression:
|
||||
type: 'Identifier'
|
||||
name: 'cappuccino'
|
||||
]
|
||||
handler: null
|
||||
finalizer: null
|
||||
|
||||
# testExpression 'try to catch it then log it',
|
||||
# type: 'Try'
|
||||
# attempt:
|
||||
# type: 'Value'
|
||||
# recovery:
|
||||
# type: 'Value'
|
||||
# base:
|
||||
# type: 'Call'
|
||||
testStatement '''
|
||||
try
|
||||
x = 1
|
||||
y()
|
||||
catch e
|
||||
d()
|
||||
finally
|
||||
f + g
|
||||
''',
|
||||
type: 'TryStatement'
|
||||
block:
|
||||
type: 'BlockStatement'
|
||||
body: [
|
||||
type: 'ExpressionStatement'
|
||||
expression:
|
||||
type: 'AssignmentExpression'
|
||||
,
|
||||
type: 'ExpressionStatement'
|
||||
expression:
|
||||
type: 'CallExpression'
|
||||
]
|
||||
handler:
|
||||
type: 'CatchClause'
|
||||
param:
|
||||
type: 'Identifier'
|
||||
name: 'e'
|
||||
body:
|
||||
type: 'BlockStatement'
|
||||
body: [
|
||||
type: 'ExpressionStatement'
|
||||
expression:
|
||||
type: 'CallExpression'
|
||||
]
|
||||
finalizer:
|
||||
type: 'BlockStatement'
|
||||
body: [
|
||||
type: 'ExpressionStatement'
|
||||
expression:
|
||||
type: 'BinaryExpression'
|
||||
]
|
||||
|
||||
testStatement '''
|
||||
try
|
||||
catch
|
||||
finally
|
||||
''',
|
||||
type: 'TryStatement'
|
||||
block:
|
||||
type: 'BlockStatement'
|
||||
body: []
|
||||
handler:
|
||||
type: 'CatchClause'
|
||||
param: null
|
||||
body:
|
||||
type: 'BlockStatement'
|
||||
body: []
|
||||
finalizer:
|
||||
type: 'BlockStatement'
|
||||
body: []
|
||||
|
||||
testStatement '''
|
||||
try
|
||||
catch {e}
|
||||
f
|
||||
''',
|
||||
type: 'TryStatement'
|
||||
block:
|
||||
type: 'BlockStatement'
|
||||
body: []
|
||||
handler:
|
||||
type: 'CatchClause'
|
||||
param:
|
||||
type: 'ObjectPattern'
|
||||
body:
|
||||
type: 'BlockStatement'
|
||||
body: [
|
||||
type: 'ExpressionStatement'
|
||||
]
|
||||
finalizer: null
|
||||
|
||||
test "AST as expected for Throw node", ->
|
||||
testExpression 'throw new BallError "catch"',
|
||||
testStatement 'throw new BallError "catch"',
|
||||
type: 'ThrowStatement'
|
||||
argument:
|
||||
type: 'NewExpression'
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# ---------------------------------
|
||||
|
||||
testAstLocationData = (code, expected) ->
|
||||
testAstNodeLocationData getAstExpression(code), expected
|
||||
testAstNodeLocationData getAstExpressionOrStatement(code), expected
|
||||
|
||||
testAstRootLocationData = (code, expected) ->
|
||||
testAstNodeLocationData getAstRoot(code), expected
|
||||
|
@ -2667,6 +2667,253 @@ test "AST location data as expected for CSXTag node", ->
|
|||
column: 11
|
||||
]
|
||||
|
||||
test "AST as expected for Try node", ->
|
||||
testAstLocationData 'try cappuccino',
|
||||
type: 'TryStatement'
|
||||
block:
|
||||
type: 'BlockStatement'
|
||||
body: [
|
||||
expression:
|
||||
start: 4
|
||||
end: 14
|
||||
range: [4, 14]
|
||||
loc:
|
||||
start:
|
||||
line: 1
|
||||
column: 4
|
||||
end:
|
||||
line: 1
|
||||
column: 14
|
||||
start: 4
|
||||
end: 14
|
||||
range: [4, 14]
|
||||
loc:
|
||||
start:
|
||||
line: 1
|
||||
column: 4
|
||||
end:
|
||||
line: 1
|
||||
column: 14
|
||||
]
|
||||
# TODO: the location data for the block is wrong (wrong location data on generated INDENT)
|
||||
# start: 4
|
||||
# end: 14
|
||||
# range: [4, 14]
|
||||
# loc:
|
||||
# start:
|
||||
# line: 1
|
||||
# column: 4
|
||||
# end:
|
||||
# line: 1
|
||||
# column: 14
|
||||
start: 0
|
||||
end: 14
|
||||
range: [0, 14]
|
||||
loc:
|
||||
start:
|
||||
line: 1
|
||||
column: 0
|
||||
end:
|
||||
line: 1
|
||||
column: 14
|
||||
|
||||
testAstLocationData '''
|
||||
try
|
||||
x = 1
|
||||
y()
|
||||
catch e
|
||||
d()
|
||||
finally
|
||||
f + g
|
||||
''',
|
||||
type: 'TryStatement'
|
||||
block:
|
||||
type: 'BlockStatement'
|
||||
body: [
|
||||
expression:
|
||||
start: 6
|
||||
end: 11
|
||||
range: [6, 11]
|
||||
loc:
|
||||
start:
|
||||
line: 2
|
||||
column: 2
|
||||
end:
|
||||
line: 2
|
||||
column: 7
|
||||
start: 6
|
||||
end: 11
|
||||
range: [6, 11]
|
||||
loc:
|
||||
start:
|
||||
line: 2
|
||||
column: 2
|
||||
end:
|
||||
line: 2
|
||||
column: 7
|
||||
,
|
||||
expression:
|
||||
start: 14
|
||||
end: 17
|
||||
range: [14, 17]
|
||||
loc:
|
||||
start:
|
||||
line: 3
|
||||
column: 2
|
||||
end:
|
||||
line: 3
|
||||
column: 5
|
||||
start: 14
|
||||
end: 17
|
||||
range: [14, 17]
|
||||
loc:
|
||||
start:
|
||||
line: 3
|
||||
column: 2
|
||||
end:
|
||||
line: 3
|
||||
column: 5
|
||||
]
|
||||
start: 4
|
||||
end: 17
|
||||
range: [4, 17]
|
||||
loc:
|
||||
start:
|
||||
line: 2
|
||||
column: 0
|
||||
end:
|
||||
line: 3
|
||||
column: 5
|
||||
handler:
|
||||
param:
|
||||
start: 24
|
||||
end: 25
|
||||
range: [24, 25]
|
||||
loc:
|
||||
start:
|
||||
line: 4
|
||||
column: 6
|
||||
end:
|
||||
line: 4
|
||||
column: 7
|
||||
body:
|
||||
body: [
|
||||
start: 28
|
||||
end: 31
|
||||
range: [28, 31]
|
||||
loc:
|
||||
start:
|
||||
line: 5
|
||||
column: 2
|
||||
end:
|
||||
line: 5
|
||||
column: 5
|
||||
]
|
||||
start: 26
|
||||
end: 31
|
||||
range: [26, 31]
|
||||
loc:
|
||||
start:
|
||||
line: 5
|
||||
column: 0
|
||||
end:
|
||||
line: 5
|
||||
column: 5
|
||||
start: 18
|
||||
end: 31
|
||||
range: [18, 31]
|
||||
loc:
|
||||
start:
|
||||
line: 4
|
||||
column: 0
|
||||
end:
|
||||
line: 5
|
||||
column: 5
|
||||
finalizer:
|
||||
body: [
|
||||
expression:
|
||||
start: 42
|
||||
end: 47
|
||||
range: [42, 47]
|
||||
loc:
|
||||
start:
|
||||
line: 7
|
||||
column: 2
|
||||
end:
|
||||
line: 7
|
||||
column: 7
|
||||
start: 42
|
||||
end: 47
|
||||
range: [42, 47]
|
||||
loc:
|
||||
start:
|
||||
line: 7
|
||||
column: 2
|
||||
end:
|
||||
line: 7
|
||||
column: 7
|
||||
]
|
||||
start: 32
|
||||
end: 47
|
||||
range: [32, 47]
|
||||
loc:
|
||||
start:
|
||||
line: 6
|
||||
column: 0
|
||||
end:
|
||||
line: 7
|
||||
column: 7
|
||||
start: 0
|
||||
end: 47
|
||||
range: [0, 47]
|
||||
loc:
|
||||
start:
|
||||
line: 1
|
||||
column: 0
|
||||
end:
|
||||
line: 7
|
||||
column: 7
|
||||
|
||||
testAstLocationData '''
|
||||
try
|
||||
catch {e}
|
||||
f
|
||||
''',
|
||||
type: 'TryStatement'
|
||||
handler:
|
||||
param:
|
||||
start: 10
|
||||
end: 13
|
||||
range: [10, 13]
|
||||
loc:
|
||||
start:
|
||||
line: 2
|
||||
column: 6
|
||||
end:
|
||||
line: 2
|
||||
column: 9
|
||||
body:
|
||||
start: 14
|
||||
end: 17
|
||||
range: [14, 17]
|
||||
loc:
|
||||
start:
|
||||
line: 3
|
||||
column: 0
|
||||
end:
|
||||
line: 3
|
||||
column: 3
|
||||
start: 4
|
||||
end: 17
|
||||
range: [4, 17]
|
||||
loc:
|
||||
start:
|
||||
line: 2
|
||||
column: 0
|
||||
end:
|
||||
line: 3
|
||||
column: 3
|
||||
|
||||
test "AST location data as expected for Root node", ->
|
||||
testAstRootLocationData '1\n2',
|
||||
type: 'File'
|
||||
|
|
|
@ -59,8 +59,16 @@ getAstExpressions = (code) ->
|
|||
|
||||
# Many tests want just the root node.
|
||||
exports.getAstExpression = (code) ->
|
||||
expressionStatementAst = getAstExpressions(code)[0]
|
||||
ok expressionStatementAst.type is 'ExpressionStatement', 'Expected ExpressionStatement AST wrapper'
|
||||
expressionStatementAst.expression
|
||||
|
||||
exports.getAstStatement = (code) ->
|
||||
statement = getAstExpressions(code)[0]
|
||||
ok statement.type isnt 'ExpressionStatement', "Didn't expect ExpressionStatement AST wrapper"
|
||||
statement
|
||||
|
||||
exports.getAstExpressionOrStatement = (code) ->
|
||||
expressionAst = getAstExpressions(code)[0]
|
||||
if expressionAst.type is 'ExpressionStatement'
|
||||
expressionAst.expression
|
||||
else
|
||||
expressionAst
|
||||
return expressionAst unless expressionAst.type is 'ExpressionStatement'
|
||||
expressionAst.expression
|
||||
|
|
Loading…
Reference in New Issue