mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
Create helper to get the object for a Value AST node, including proper non-AST location data
This commit is contained in:
@@ -1666,9 +1666,9 @@
|
||||
}
|
||||
|
||||
isSplice() {
|
||||
var lastProp, ref1;
|
||||
ref1 = this.properties, [lastProp] = slice1.call(ref1, -1);
|
||||
return lastProp instanceof Slice;
|
||||
var lastProperty, ref1;
|
||||
ref1 = this.properties, [lastProperty] = slice1.call(ref1, -1);
|
||||
return lastProperty instanceof Slice;
|
||||
}
|
||||
|
||||
looksStatic(className) {
|
||||
@@ -1795,14 +1795,38 @@
|
||||
}
|
||||
}
|
||||
|
||||
// For AST generation, we need an `object` that’s this `Value` minus its last
|
||||
// property, if it has properties.
|
||||
object() {
|
||||
var initialProperties, object;
|
||||
if (!this.hasProperties()) {
|
||||
return this;
|
||||
}
|
||||
// Get all properties except the last one; for a `Value` with only one
|
||||
// property, `initialProperties` is an empty array.
|
||||
initialProperties = this.properties.slice(0, this.properties.length - 1);
|
||||
// Create the `object` that becomes the new “base” for the split-off final
|
||||
// property.
|
||||
object = new Value(this.base, initialProperties, this.tag, this.isDefaultValue);
|
||||
// Add location data to our new node, so that it has correct location data
|
||||
// for source maps or later conversion into AST location data.
|
||||
// This new `Value` has only one property, so the location data is just
|
||||
// that of the parent `Value`’s base.
|
||||
// This new `Value` has multiple properties, so the location data spans
|
||||
// from the parent `Value`’s base to the last property that’s included
|
||||
// in this new node (a.k.a. the second-to-last property of the parent).
|
||||
object.locationData = initialProperties.length === 0 ? this.base.locationData : mergeLocationData(this.base.locationData, initialProperties[initialProperties.length - 1].locationData);
|
||||
return object;
|
||||
}
|
||||
|
||||
ast() {
|
||||
if (!this.hasProperties()) {
|
||||
// If the `Value` has no properties, the AST node is just whatever this
|
||||
// node’s `base` is.
|
||||
return this.base.ast();
|
||||
}
|
||||
// Otherwise, call `Base::ast` which in turn calls the `astType`,
|
||||
// `astProperties` and `astLocationData` methods below.
|
||||
// Otherwise, call `Base::ast` which in turn calls the `astType` and
|
||||
// `astProperties` methods below.
|
||||
return super.ast();
|
||||
}
|
||||
|
||||
@@ -1814,10 +1838,10 @@
|
||||
// becomes the `property`, and the preceding properties (e.g. `a.b`) become
|
||||
// a child `Value` node assigned to the `object` property.
|
||||
astProperties() {
|
||||
var initialProperties, property, ref1, ref2;
|
||||
ref1 = this.properties, [...initialProperties] = ref1, [property] = splice.call(initialProperties, -1);
|
||||
var property, ref1, ref2;
|
||||
ref1 = this.properties, [property] = slice1.call(ref1, -1);
|
||||
return {
|
||||
object: new Value(this.base, initialProperties, this.tag, this.isDefaultValue).ast(),
|
||||
object: this.object().ast(),
|
||||
property: property.ast(),
|
||||
computed: property instanceof Index || !(((ref2 = property.name) != null ? ref2.unwrap() : void 0) instanceof PropertyName),
|
||||
optional: !!property.soak,
|
||||
@@ -1825,17 +1849,6 @@
|
||||
};
|
||||
}
|
||||
|
||||
// When the `Value` has properties, the location data of a
|
||||
// `MemberExpression` AST node corresponding to a given property should
|
||||
// span the location of the `Value`’s `base` (including parentheses if
|
||||
// present) through the property’s location.
|
||||
astLocationData() {
|
||||
if (this.locationData != null) {
|
||||
return super.astLocationData();
|
||||
}
|
||||
return mergeAstLocationData(this.base.astLocationData(), this.properties[this.properties.length - 1].astLocationData());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Value.prototype.children = ['base', 'properties'];
|
||||
@@ -5199,9 +5212,9 @@
|
||||
//### In
|
||||
exports.In = In = (function() {
|
||||
class In extends Base {
|
||||
constructor(object, array) {
|
||||
constructor(object1, array) {
|
||||
super();
|
||||
this.object = object;
|
||||
this.object = object1;
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
|
||||
@@ -1097,8 +1097,8 @@ exports.Value = class Value extends Base
|
||||
@base.hasElision()
|
||||
|
||||
isSplice: ->
|
||||
[..., lastProp] = @properties
|
||||
lastProp instanceof Slice
|
||||
[..., lastProperty] = @properties
|
||||
lastProperty instanceof Slice
|
||||
|
||||
looksStatic: (className) ->
|
||||
(@this or @base instanceof ThisLiteral or @base.value is className) and
|
||||
@@ -1186,12 +1186,36 @@ exports.Value = class Value extends Base
|
||||
else
|
||||
@error 'tried to assign to unassignable value'
|
||||
|
||||
# For AST generation, we need an `object` that’s this `Value` minus its last
|
||||
# property, if it has properties.
|
||||
object: ->
|
||||
return @ unless @hasProperties()
|
||||
# Get all properties except the last one; for a `Value` with only one
|
||||
# property, `initialProperties` is an empty array.
|
||||
initialProperties = @properties[0...@properties.length - 1]
|
||||
# Create the `object` that becomes the new “base” for the split-off final
|
||||
# property.
|
||||
object = new Value @base, initialProperties, @tag, @isDefaultValue
|
||||
# Add location data to our new node, so that it has correct location data
|
||||
# for source maps or later conversion into AST location data.
|
||||
object.locationData =
|
||||
if initialProperties.length is 0
|
||||
# This new `Value` has only one property, so the location data is just
|
||||
# that of the parent `Value`’s base.
|
||||
@base.locationData
|
||||
else
|
||||
# This new `Value` has multiple properties, so the location data spans
|
||||
# from the parent `Value`’s base to the last property that’s included
|
||||
# in this new node (a.k.a. the second-to-last property of the parent).
|
||||
mergeLocationData @base.locationData, initialProperties[initialProperties.length - 1].locationData
|
||||
object
|
||||
|
||||
ast: ->
|
||||
# If the `Value` has no properties, the AST node is just whatever this
|
||||
# node’s `base` is.
|
||||
return @base.ast() unless @hasProperties()
|
||||
# Otherwise, call `Base::ast` which in turn calls the `astType`,
|
||||
# `astProperties` and `astLocationData` methods below.
|
||||
# Otherwise, call `Base::ast` which in turn calls the `astType` and
|
||||
# `astProperties` methods below.
|
||||
super()
|
||||
|
||||
astType: -> 'MemberExpression'
|
||||
@@ -1200,22 +1224,13 @@ exports.Value = class Value extends Base
|
||||
# becomes the `property`, and the preceding properties (e.g. `a.b`) become
|
||||
# a child `Value` node assigned to the `object` property.
|
||||
astProperties: ->
|
||||
[initialProperties..., property] = @properties
|
||||
|
||||
object: new Value(@base, initialProperties, @tag, @isDefaultValue).ast()
|
||||
property: property.ast()
|
||||
computed: property instanceof Index or property.name?.unwrap() not instanceof PropertyName
|
||||
optional: !!property.soak
|
||||
shorthand: !!property.shorthand
|
||||
|
||||
# When the `Value` has properties, the location data of a
|
||||
# `MemberExpression` AST node corresponding to a given property should
|
||||
# span the location of the `Value`’s `base` (including parentheses if
|
||||
# present) through the property’s location.
|
||||
astLocationData: ->
|
||||
return super() if @locationData?
|
||||
mergeAstLocationData @base.astLocationData(),
|
||||
@properties[@properties.length - 1].astLocationData()
|
||||
[..., property] = @properties
|
||||
return
|
||||
object: @object().ast()
|
||||
property: property.ast()
|
||||
computed: property instanceof Index or property.name?.unwrap() not instanceof PropertyName
|
||||
optional: !!property.soak
|
||||
shorthand: !!property.shorthand
|
||||
|
||||
#### HereComment
|
||||
|
||||
|
||||
Reference in New Issue
Block a user