spider-src 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +74 -0
- data/README.md +37 -0
- data/Rakefile +25 -0
- data/lib/spider-src/support/spider/.eslintrc +17 -0
- data/lib/spider-src/support/spider/.npmignore +9 -0
- data/lib/spider-src/support/spider/.travis.yml +7 -0
- data/lib/spider-src/support/spider/.yo-rc.json +3 -0
- data/lib/spider-src/support/spider/CHANGELOG.md +64 -0
- data/lib/spider-src/support/spider/Gruntfile.js +97 -0
- data/lib/spider-src/support/spider/Gruntfile.spider +93 -0
- data/lib/spider-src/support/spider/LICENSE +201 -0
- data/lib/spider-src/support/spider/README.md +50 -0
- data/lib/spider-src/support/spider/cli.js +119 -0
- data/lib/spider-src/support/spider/lib/ast/CaseClause.js +179 -0
- data/lib/spider-src/support/spider/lib/ast/CatchClause.js +26 -0
- data/lib/spider-src/support/spider/lib/ast/ExportBatchSpecifier.js +19 -0
- data/lib/spider-src/support/spider/lib/ast/ExportSpecifier.js +33 -0
- data/lib/spider-src/support/spider/lib/ast/ImportDefaultSpecifier.js +23 -0
- data/lib/spider-src/support/spider/lib/ast/ImportNamespaceSpecifier.js +23 -0
- data/lib/spider-src/support/spider/lib/ast/ImportSpecifier.js +40 -0
- data/lib/spider-src/support/spider/lib/ast/Node.js +93 -0
- data/lib/spider-src/support/spider/lib/ast/Parameter.js +229 -0
- data/lib/spider-src/support/spider/lib/ast/Program.js +58 -0
- data/lib/spider-src/support/spider/lib/ast/Property.js +32 -0
- data/lib/spider-src/support/spider/lib/ast/Range.js +257 -0
- data/lib/spider-src/support/spider/lib/ast/VariableDeclarator.js +29 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/ArrayExpression.js +41 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/ArrayPattern.js +45 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/AssignmentExpression.js +29 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/BinaryExpression.js +104 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/CallExpression.js +139 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/ConditionalExpression.js +31 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/CurryCallExpression.js +102 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/ExistentialExpression.js +83 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/ForInExpression.js +116 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/FunctionExpression.js +157 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/InExpression.js +99 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/LogicalExpression.js +50 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/MemberExpression.js +43 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/NewExpression.js +46 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/NullCheckCallExpression.js +132 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/NullCoalescingExpression.js +114 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/NullPropagatingExpression.js +161 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/ObjectExpression.js +39 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/ObjectPattern.js +49 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/RangeMemberExpression.js +157 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/SplatExpression.js +48 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/SuperExpression.js +170 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/ThisExpression.js +22 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/UnaryExpression.js +147 -0
- data/lib/spider-src/support/spider/lib/ast/expressions/UpdateExpression.js +26 -0
- data/lib/spider-src/support/spider/lib/ast/literals/BooleanLiteral.js +24 -0
- data/lib/spider-src/support/spider/lib/ast/literals/Identifier.js +60 -0
- data/lib/spider-src/support/spider/lib/ast/literals/NullLiteral.js +24 -0
- data/lib/spider-src/support/spider/lib/ast/literals/NumberLiteral.js +24 -0
- data/lib/spider-src/support/spider/lib/ast/literals/RegularExpressionLiteral.js +25 -0
- data/lib/spider-src/support/spider/lib/ast/literals/StringLiteral.js +90 -0
- data/lib/spider-src/support/spider/lib/ast/literals/UndefinedLiteral.js +30 -0
- data/lib/spider-src/support/spider/lib/ast/statements/BlockStatement.js +47 -0
- data/lib/spider-src/support/spider/lib/ast/statements/BreakStatement.js +19 -0
- data/lib/spider-src/support/spider/lib/ast/statements/ContinueStatement.js +19 -0
- data/lib/spider-src/support/spider/lib/ast/statements/DebuggerStatement.js +19 -0
- data/lib/spider-src/support/spider/lib/ast/statements/DoWhileStatement.js +25 -0
- data/lib/spider-src/support/spider/lib/ast/statements/ExportDeclarationStatement.js +51 -0
- data/lib/spider-src/support/spider/lib/ast/statements/ExpressionStatement.js +22 -0
- data/lib/spider-src/support/spider/lib/ast/statements/FallthroughStatement.js +74 -0
- data/lib/spider-src/support/spider/lib/ast/statements/ForInStatement.js +79 -0
- data/lib/spider-src/support/spider/lib/ast/statements/ForOfStatement.js +98 -0
- data/lib/spider-src/support/spider/lib/ast/statements/ForStatement.js +43 -0
- data/lib/spider-src/support/spider/lib/ast/statements/FunctionDeclarationStatement.js +104 -0
- data/lib/spider-src/support/spider/lib/ast/statements/GoStatement.js +41 -0
- data/lib/spider-src/support/spider/lib/ast/statements/IfStatement.js +32 -0
- data/lib/spider-src/support/spider/lib/ast/statements/ImportDeclarationStatement.js +40 -0
- data/lib/spider-src/support/spider/lib/ast/statements/PushStatement.js +37 -0
- data/lib/spider-src/support/spider/lib/ast/statements/ReturnStatement.js +26 -0
- data/lib/spider-src/support/spider/lib/ast/statements/SwitchStatement.js +159 -0
- data/lib/spider-src/support/spider/lib/ast/statements/ThrowStatement.js +22 -0
- data/lib/spider-src/support/spider/lib/ast/statements/TryStatement.js +36 -0
- data/lib/spider-src/support/spider/lib/ast/statements/UntilStatement.js +31 -0
- data/lib/spider-src/support/spider/lib/ast/statements/UseStatement.js +49 -0
- data/lib/spider-src/support/spider/lib/ast/statements/VariableDeclarationStatement.js +36 -0
- data/lib/spider-src/support/spider/lib/ast/statements/WhileStatement.js +25 -0
- data/lib/spider-src/support/spider/lib/ast.js +16 -0
- data/lib/spider-src/support/spider/lib/parser.js +14878 -0
- data/lib/spider-src/support/spider/lib/spider.js +217 -0
- data/lib/spider-src/support/spider/package.json +61 -0
- data/lib/spider-src/support/spider/spider-script.js +6 -0
- data/lib/spider-src/support/spider/src/ast/CaseClause.spider +179 -0
- data/lib/spider-src/support/spider/src/ast/CatchClause.spider +30 -0
- data/lib/spider-src/support/spider/src/ast/ExportBatchSpecifier.spider +19 -0
- data/lib/spider-src/support/spider/src/ast/ExportSpecifier.spider +37 -0
- data/lib/spider-src/support/spider/src/ast/ImportDefaultSpecifier.spider +25 -0
- data/lib/spider-src/support/spider/src/ast/ImportNamespaceSpecifier.spider +25 -0
- data/lib/spider-src/support/spider/src/ast/ImportSpecifier.spider +44 -0
- data/lib/spider-src/support/spider/src/ast/Node.spider +104 -0
- data/lib/spider-src/support/spider/src/ast/Parameter.spider +233 -0
- data/lib/spider-src/support/spider/src/ast/Program.spider +109 -0
- data/lib/spider-src/support/spider/src/ast/Property.spider +36 -0
- data/lib/spider-src/support/spider/src/ast/Range.spider +291 -0
- data/lib/spider-src/support/spider/src/ast/VariableDeclarator.spider +33 -0
- data/lib/spider-src/support/spider/src/ast/expressions/ArrayExpression.spider +32 -0
- data/lib/spider-src/support/spider/src/ast/expressions/ArrayPattern.spider +37 -0
- data/lib/spider-src/support/spider/src/ast/expressions/AssignmentExpression.spider +34 -0
- data/lib/spider-src/support/spider/src/ast/expressions/BinaryExpression.spider +125 -0
- data/lib/spider-src/support/spider/src/ast/expressions/CallExpression.spider +149 -0
- data/lib/spider-src/support/spider/src/ast/expressions/ConditionalExpression.spider +34 -0
- data/lib/spider-src/support/spider/src/ast/expressions/CurryCallExpression.spider +109 -0
- data/lib/spider-src/support/spider/src/ast/expressions/ExistentialExpression.spider +102 -0
- data/lib/spider-src/support/spider/src/ast/expressions/ForInExpression.spider +140 -0
- data/lib/spider-src/support/spider/src/ast/expressions/FunctionExpression.spider +183 -0
- data/lib/spider-src/support/spider/src/ast/expressions/InExpression.spider +114 -0
- data/lib/spider-src/support/spider/src/ast/expressions/LogicalExpression.spider +62 -0
- data/lib/spider-src/support/spider/src/ast/expressions/MemberExpression.spider +57 -0
- data/lib/spider-src/support/spider/src/ast/expressions/NewExpression.spider +40 -0
- data/lib/spider-src/support/spider/src/ast/expressions/NullCheckCallExpression.spider +151 -0
- data/lib/spider-src/support/spider/src/ast/expressions/NullCoalescingExpression.spider +151 -0
- data/lib/spider-src/support/spider/src/ast/expressions/NullPropagatingExpression.spider +190 -0
- data/lib/spider-src/support/spider/src/ast/expressions/ObjectExpression.spider +30 -0
- data/lib/spider-src/support/spider/src/ast/expressions/ObjectPattern.spider +42 -0
- data/lib/spider-src/support/spider/src/ast/expressions/RangeMemberExpression.spider +179 -0
- data/lib/spider-src/support/spider/src/ast/expressions/SplatExpression.spider +49 -0
- data/lib/spider-src/support/spider/src/ast/expressions/SuperExpression.spider +235 -0
- data/lib/spider-src/support/spider/src/ast/expressions/ThisExpression.spider +21 -0
- data/lib/spider-src/support/spider/src/ast/expressions/UnaryExpression.spider +158 -0
- data/lib/spider-src/support/spider/src/ast/expressions/UpdateExpression.spider +28 -0
- data/lib/spider-src/support/spider/src/ast/literals/BooleanLiteral.spider +23 -0
- data/lib/spider-src/support/spider/src/ast/literals/Identifier.spider +68 -0
- data/lib/spider-src/support/spider/src/ast/literals/NullLiteral.spider +23 -0
- data/lib/spider-src/support/spider/src/ast/literals/NumberLiteral.spider +23 -0
- data/lib/spider-src/support/spider/src/ast/literals/RegularExpressionLiteral.spider +24 -0
- data/lib/spider-src/support/spider/src/ast/literals/StringLiteral.spider +91 -0
- data/lib/spider-src/support/spider/src/ast/literals/UndefinedLiteral.spider +30 -0
- data/lib/spider-src/support/spider/src/ast/statements/BlockStatement.spider +45 -0
- data/lib/spider-src/support/spider/src/ast/statements/BreakStatement.spider +19 -0
- data/lib/spider-src/support/spider/src/ast/statements/ContinueStatement.spider +19 -0
- data/lib/spider-src/support/spider/src/ast/statements/DebuggerStatement.spider +19 -0
- data/lib/spider-src/support/spider/src/ast/statements/DoWhileStatement.spider +28 -0
- data/lib/spider-src/support/spider/src/ast/statements/ExportDeclarationStatement.spider +46 -0
- data/lib/spider-src/support/spider/src/ast/statements/ExpressionStatement.spider +22 -0
- data/lib/spider-src/support/spider/src/ast/statements/FallthroughStatement.spider +85 -0
- data/lib/spider-src/support/spider/src/ast/statements/ForInStatement.spider +92 -0
- data/lib/spider-src/support/spider/src/ast/statements/ForOfStatement.spider +117 -0
- data/lib/spider-src/support/spider/src/ast/statements/ForStatement.spider +51 -0
- data/lib/spider-src/support/spider/src/ast/statements/FunctionDeclarationStatement.spider +115 -0
- data/lib/spider-src/support/spider/src/ast/statements/GoStatement.spider +44 -0
- data/lib/spider-src/support/spider/src/ast/statements/IfStatement.spider +38 -0
- data/lib/spider-src/support/spider/src/ast/statements/ImportDeclarationStatement.spider +33 -0
- data/lib/spider-src/support/spider/src/ast/statements/PushStatement.spider +40 -0
- data/lib/spider-src/support/spider/src/ast/statements/ReturnStatement.spider +28 -0
- data/lib/spider-src/support/spider/src/ast/statements/SwitchStatement.spider +161 -0
- data/lib/spider-src/support/spider/src/ast/statements/ThrowStatement.spider +23 -0
- data/lib/spider-src/support/spider/src/ast/statements/TryStatement.spider +42 -0
- data/lib/spider-src/support/spider/src/ast/statements/UntilStatement.spider +36 -0
- data/lib/spider-src/support/spider/src/ast/statements/UseStatement.spider +62 -0
- data/lib/spider-src/support/spider/src/ast/statements/VariableDeclarationStatement.spider +34 -0
- data/lib/spider-src/support/spider/src/ast/statements/WhileStatement.spider +28 -0
- data/lib/spider-src/support/spider/src/ast.spider +80 -0
- data/lib/spider-src/support/spider/src/spider.pegjs +1434 -0
- data/lib/spider-src/support/spider/src/spider.spider +276 -0
- data/lib/spider-src/support/spider/test/spider_test.js +1787 -0
- data/lib/spider-src/version.rb +5 -0
- data/lib/spider-src.rb +37 -0
- data/spider-src.gemspec +24 -0
- data/test/test_spider_src.rb +33 -0
- metadata +225 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
use :node;
|
|
2
|
+
|
|
3
|
+
var Node = module.require('../Node').Node;
|
|
4
|
+
|
|
5
|
+
fn ObjectPattern(properties)
|
|
6
|
+
extends Node {
|
|
7
|
+
|
|
8
|
+
this.type = 'ObjectPattern';
|
|
9
|
+
this.properties = properties;
|
|
10
|
+
|
|
11
|
+
for property in this.properties {
|
|
12
|
+
property.parent = this;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
ObjectPattern.prototype.codegen = () -> {
|
|
17
|
+
if !super.codegen() {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var context = this.getContext().node;
|
|
22
|
+
for property, i in this.properties {
|
|
23
|
+
this.properties[i] = property.codegen();
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
if property.value? {
|
|
27
|
+
if property.value.type == "Identifier" {
|
|
28
|
+
context.defineIdentifier(property.value);
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
if property.key.type == "Identifier" {
|
|
32
|
+
context.defineIdentifier(property.key);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return this;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
ObjectPattern.prototype.hasCallExpression = () -> true;
|
|
41
|
+
|
|
42
|
+
exports.ObjectPattern = ObjectPattern;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
use :node;
|
|
2
|
+
|
|
3
|
+
var Node = module.require('../Node').Node;
|
|
4
|
+
|
|
5
|
+
fn RangeMemberExpression(object, range)
|
|
6
|
+
extends Node {
|
|
7
|
+
|
|
8
|
+
this.type = 'RangeMemberExpression';
|
|
9
|
+
this.object = object;
|
|
10
|
+
this.object.parent = this;
|
|
11
|
+
|
|
12
|
+
this.range = range;
|
|
13
|
+
this.range.parent = this;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
RangeMemberExpression.prototype.codegen = () -> {
|
|
17
|
+
if !super.codegen() {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var isNumber = (n) -> !::isNaN(::parseFloat(n)) && ::isFinite(n);
|
|
22
|
+
|
|
23
|
+
// If this node is the left side of an assignment expression,
|
|
24
|
+
// it means we're dealing with splice. For example:
|
|
25
|
+
// items[1..2] = [1, 2];
|
|
26
|
+
if this.parent.type == 'AssignmentExpression' &&
|
|
27
|
+
this.parent.left == this {
|
|
28
|
+
this.parent.type = 'CallExpression';
|
|
29
|
+
|
|
30
|
+
this.parent.callee = {
|
|
31
|
+
"type": "MemberExpression",
|
|
32
|
+
"computed": false,
|
|
33
|
+
"object": {
|
|
34
|
+
"type": "MemberExpression",
|
|
35
|
+
"computed": false,
|
|
36
|
+
"object": {
|
|
37
|
+
"type": "ArrayExpression",
|
|
38
|
+
"elements": []
|
|
39
|
+
},
|
|
40
|
+
"property": {
|
|
41
|
+
"type": "Identifier",
|
|
42
|
+
"name": "splice"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"property": {
|
|
46
|
+
"type": "Identifier",
|
|
47
|
+
"name": "apply"
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
var to;
|
|
52
|
+
var start = this.range.start.codegen() if this.range.start else {
|
|
53
|
+
"type": "Literal",
|
|
54
|
+
"value": 0
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
if this.range.to? {
|
|
58
|
+
if isNumber(start.value) &&
|
|
59
|
+
isNumber(this.range.to.value) {
|
|
60
|
+
to = {
|
|
61
|
+
"type": "Literal",
|
|
62
|
+
"value": this.range.to.value - start.value + (1 if this.range.operator == '..' else 0)
|
|
63
|
+
};
|
|
64
|
+
} else {
|
|
65
|
+
to = this.range.to.codegen();
|
|
66
|
+
|
|
67
|
+
if start.value != 0 {
|
|
68
|
+
to = {
|
|
69
|
+
"type": "BinaryExpression",
|
|
70
|
+
"operator": "-",
|
|
71
|
+
"left": to,
|
|
72
|
+
"right": start,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if this.range.operator == '..' {
|
|
77
|
+
to = {
|
|
78
|
+
"type": "BinaryExpression",
|
|
79
|
+
"operator": "+",
|
|
80
|
+
"left": to,
|
|
81
|
+
"right": {
|
|
82
|
+
"type": "Literal",
|
|
83
|
+
"value": 1
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
to = {
|
|
90
|
+
"type": "Literal",
|
|
91
|
+
"value": 9000000000,
|
|
92
|
+
"raw": "9e9"
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
::Object.defineProperty(this.parent, 'arguments', {
|
|
97
|
+
value: [
|
|
98
|
+
this.object.codegen(),
|
|
99
|
+
{
|
|
100
|
+
"type": "CallExpression",
|
|
101
|
+
"callee": {
|
|
102
|
+
"type": "MemberExpression",
|
|
103
|
+
"computed": false,
|
|
104
|
+
"object": {
|
|
105
|
+
"type": "ArrayExpression",
|
|
106
|
+
"elements": [start, to]
|
|
107
|
+
},
|
|
108
|
+
"property": {
|
|
109
|
+
"type": "Identifier",
|
|
110
|
+
"name": "concat"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"arguments": [
|
|
114
|
+
this.parent.right
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
enumerable: true
|
|
119
|
+
});
|
|
120
|
+
} else {
|
|
121
|
+
// Otherwise, we're dealing with slice. For example:
|
|
122
|
+
// var x = items[1..2];
|
|
123
|
+
this.type = "CallExpression";
|
|
124
|
+
this.callee = {
|
|
125
|
+
"type": "MemberExpression",
|
|
126
|
+
"computed": false,
|
|
127
|
+
"object": this.object.codegen(),
|
|
128
|
+
"property": {
|
|
129
|
+
"type": "Identifier",
|
|
130
|
+
"name": "slice"
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
var args = [];
|
|
135
|
+
|
|
136
|
+
if !this.range.start? {
|
|
137
|
+
args.push({
|
|
138
|
+
"type": "Literal",
|
|
139
|
+
"value": 0
|
|
140
|
+
});
|
|
141
|
+
} else {
|
|
142
|
+
args.push(this.range.start.codegen());
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if this.range.to? {
|
|
146
|
+
if this.range.operator == '...' {
|
|
147
|
+
args.push(this.range.to.codegen());
|
|
148
|
+
} else {
|
|
149
|
+
if this.range.to.value && isNumber(this.range.to.value) {
|
|
150
|
+
args.push({
|
|
151
|
+
"type": "Literal",
|
|
152
|
+
"value": this.range.to.value + 1
|
|
153
|
+
});
|
|
154
|
+
} else {
|
|
155
|
+
args.push({
|
|
156
|
+
"type": "BinaryExpression",
|
|
157
|
+
"operator": "+",
|
|
158
|
+
"left": this.range.to.codegen(),
|
|
159
|
+
"right": {
|
|
160
|
+
"type": "Literal",
|
|
161
|
+
"value": 1
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
::Object.defineProperty(this, 'arguments', {
|
|
169
|
+
value: args,
|
|
170
|
+
enumerable: true
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return this;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
RangeMemberExpression.prototype.hasCallExpression = () -> true;
|
|
178
|
+
|
|
179
|
+
exports.RangeMemberExpression = RangeMemberExpression;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
use :node;
|
|
2
|
+
|
|
3
|
+
var Node = module.require('../Node').Node;
|
|
4
|
+
|
|
5
|
+
fn SplatExpression(expression)
|
|
6
|
+
extends Node {
|
|
7
|
+
|
|
8
|
+
this.type = 'SplatExpression';
|
|
9
|
+
|
|
10
|
+
this.expression = expression;
|
|
11
|
+
this.expression.parent = this;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
SplatExpression.prototype.codegen = () -> {
|
|
15
|
+
if !super.codegen() {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
this.expression = this.expression.codegen();
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
"type": "CallExpression",
|
|
23
|
+
"callee": {
|
|
24
|
+
"type": "MemberExpression",
|
|
25
|
+
"computed": false,
|
|
26
|
+
"object": {
|
|
27
|
+
"type": "MemberExpression",
|
|
28
|
+
"computed": false,
|
|
29
|
+
"object": {
|
|
30
|
+
"type": "ArrayExpression",
|
|
31
|
+
"elements": []
|
|
32
|
+
},
|
|
33
|
+
"property": {
|
|
34
|
+
"type": "Identifier",
|
|
35
|
+
"name": "slice"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"property": {
|
|
39
|
+
"type": "Identifier",
|
|
40
|
+
"name": "call"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"arguments": [this.expression]
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
SplatExpression.prototype.hasCallExpression = () -> true;
|
|
48
|
+
|
|
49
|
+
exports.SplatExpression = SplatExpression;
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
use :node;
|
|
2
|
+
|
|
3
|
+
var Node = module.require('../Node').Node;
|
|
4
|
+
var extend = require('util')._extend;
|
|
5
|
+
|
|
6
|
+
fn SuperExpression()
|
|
7
|
+
extends Node {
|
|
8
|
+
|
|
9
|
+
this.type = 'SuperExpression';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
SuperExpression.prototype.codegen = () -> {
|
|
13
|
+
if !super.codegen() {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Raise an error if we are getting a syntax
|
|
18
|
+
// such as: super?.test
|
|
19
|
+
if this.parent.type == 'NullPropagatingExpression' {
|
|
20
|
+
Node.getErrorManager().error({
|
|
21
|
+
type: "InvalidSuperReference",
|
|
22
|
+
message: "cannot refer to super before the ?. operator",
|
|
23
|
+
loc: this.loc
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return { type: 'ThisExpression' };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// The only supported use case for super is
|
|
30
|
+
// member expression (e.g: super.x)
|
|
31
|
+
if this.parent.type != 'MemberExpression' {
|
|
32
|
+
Node.getErrorManager().error({
|
|
33
|
+
type: "InvalidUsageForSuper",
|
|
34
|
+
message: "invalid usage of super keyword",
|
|
35
|
+
loc: this.loc
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return { type: 'ThisExpression' };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Find a parent function that extends another function
|
|
42
|
+
// (has the extends keyword) or a prototype assignment
|
|
43
|
+
var parentNode = this;
|
|
44
|
+
var node = this;
|
|
45
|
+
while (node && !node.inheritsFrom &&
|
|
46
|
+
(node.type != 'AssignmentExpression' || ((!node.left.property || node.left.property.name != 'prototype') &&
|
|
47
|
+
(!node.left.object.property || node.left.object.property.name != 'prototype')))) {
|
|
48
|
+
parentNode = node;
|
|
49
|
+
node = node.parent;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Raise an error if there's no parent function
|
|
53
|
+
if !node {
|
|
54
|
+
Node.getErrorManager().error({
|
|
55
|
+
type: "InvalidContextForSuper",
|
|
56
|
+
message: "invalid context for super keyword",
|
|
57
|
+
loc: this.loc
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return { type: 'ThisExpression' };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Add _self variable to a context.
|
|
64
|
+
var addSelf = (context) -> {
|
|
65
|
+
var selfId = {
|
|
66
|
+
"type": "Identifier",
|
|
67
|
+
"name": "_self",
|
|
68
|
+
"codeGenerated": "true"
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
if (!context.node.__isSelfDefined) {
|
|
72
|
+
context.node.body.splice(0, 0, {
|
|
73
|
+
"type": "VariableDeclaration",
|
|
74
|
+
"declarations": [{
|
|
75
|
+
"type": "VariableDeclarator",
|
|
76
|
+
"id": selfId,
|
|
77
|
+
"init": {
|
|
78
|
+
type: "ThisExpression"
|
|
79
|
+
}
|
|
80
|
+
}],
|
|
81
|
+
"kind": "let"
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
context.node.__isSelfDefined = true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return selfId;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// Modify the call expression to look like:
|
|
91
|
+
// _fn.call(_self)
|
|
92
|
+
var mutateCallExpression = (id, parent, selfNode) -> {
|
|
93
|
+
selfNode.codeGenerated = true;
|
|
94
|
+
|
|
95
|
+
parent.object = id;
|
|
96
|
+
parent.property = ::Object.create({
|
|
97
|
+
"codeGenerated": "true",
|
|
98
|
+
"type": "Identifier",
|
|
99
|
+
"name": "call"
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
parent.parent.arguments.splice(0, 0, selfNode);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// If we are inside a prototype function, change
|
|
106
|
+
// something like: super.x() to Base.prototype.x.call(_self);
|
|
107
|
+
if node.type == 'AssignmentExpression' {
|
|
108
|
+
var identifier = node.left.object;
|
|
109
|
+
var context;
|
|
110
|
+
|
|
111
|
+
if node.left.property.name != 'prototype' {
|
|
112
|
+
identifier = identifier.object;
|
|
113
|
+
context = { node: node.right.body };
|
|
114
|
+
} else {
|
|
115
|
+
// Make sure that the syntax is something like:
|
|
116
|
+
// Fn.prototype = { ... }
|
|
117
|
+
if node.right.type != 'ObjectExpression' {
|
|
118
|
+
Node.getErrorManager().error({
|
|
119
|
+
type: "InvalidUsageForSuper",
|
|
120
|
+
message: "invalid usage of super keyword",
|
|
121
|
+
loc: this.loc
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return { type: 'ThisExpression' };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
var contextNode = this;
|
|
128
|
+
while (contextNode.parent? && contextNode.parent != node.right) {
|
|
129
|
+
contextNode = contextNode.parent;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Make sure that the syntax is something like:
|
|
133
|
+
// Fn.prototype = { test: fn () { ... } }
|
|
134
|
+
if contextNode?.type != 'Property' ||
|
|
135
|
+
contextNode?.value?.type != 'FunctionExpression' {
|
|
136
|
+
Node.getErrorManager().error({
|
|
137
|
+
type: "InvalidUsageForSuper",
|
|
138
|
+
message: "invalid usage of super keyword",
|
|
139
|
+
loc: this.loc
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return { type: 'ThisExpression' };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
context = { node: contextNode.value.body };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
var selfNode;
|
|
149
|
+
if context.node == this.getContext().node {
|
|
150
|
+
selfNode = { type: 'ThisExpression' };
|
|
151
|
+
} else {
|
|
152
|
+
selfNode = addSelf(context);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// If this is a call expression, e.g: super.test(),
|
|
156
|
+
// Turn this into Base.prototype.test.call(_self)
|
|
157
|
+
if this.parent.parent.type == 'CallExpression' {
|
|
158
|
+
var memberExpression = {
|
|
159
|
+
type: 'MemberExpression',
|
|
160
|
+
computed: false,
|
|
161
|
+
object: {
|
|
162
|
+
type: 'MemberExpression',
|
|
163
|
+
computed: false,
|
|
164
|
+
object: this.parent.getDefinedIdentifier(identifier.name).parent.inheritsFrom.callee,
|
|
165
|
+
property: {
|
|
166
|
+
type: 'Identifier',
|
|
167
|
+
name: 'prototype'
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
property: this.parent.parent.callee.property
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
mutateCallExpression(memberExpression, this.parent, selfNode);
|
|
174
|
+
return memberExpression;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Otherwise, just return (this|_self).property
|
|
178
|
+
return selfNode;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
var superContext = parentNode.getContext();
|
|
182
|
+
|
|
183
|
+
// Find the most left side in the member expression
|
|
184
|
+
// For super.a.b.c.d, the most left side would be super
|
|
185
|
+
var lastObject = this.parent;
|
|
186
|
+
while (lastObject.object.type == 'MemberExpression') {
|
|
187
|
+
lastObject = lastObject.object;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Change it to a this expression
|
|
191
|
+
lastObject.object = {
|
|
192
|
+
type: 'ThisExpression'
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
var id = {
|
|
196
|
+
"type": "Identifier",
|
|
197
|
+
"name": "_" + this.parent.property.name
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// Declare a new variable in the function that extends
|
|
201
|
+
// with a reference to our property
|
|
202
|
+
if !this.parent.isIdentifierDefined(id.name) {
|
|
203
|
+
superContext.node.body.splice(superContext.position, 0, {
|
|
204
|
+
"codeGenerated": "true",
|
|
205
|
+
"type": "VariableDeclaration",
|
|
206
|
+
"declarations": [{
|
|
207
|
+
"type": "VariableDeclarator",
|
|
208
|
+
"id": id,
|
|
209
|
+
"init": extend({}, lastObject)
|
|
210
|
+
}],
|
|
211
|
+
"kind": "let"
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
superContext.node.defineIdentifier(id);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// If we are in a call expression, change it to:
|
|
218
|
+
// _fn.call(_self)
|
|
219
|
+
if this.parent.parent.type == 'CallExpression' {
|
|
220
|
+
mutateCallExpression(id, this.parent, addSelf(superContext));
|
|
221
|
+
} else {
|
|
222
|
+
// Otherwise, just refer to the variable
|
|
223
|
+
this.parent.type = 'Identifier';
|
|
224
|
+
::Object.defineProperty(this.parent, 'name', {
|
|
225
|
+
value: id.name,
|
|
226
|
+
enumerable: true
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return id;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
SuperExpression.prototype.hasCallExpression = () -> false;
|
|
234
|
+
|
|
235
|
+
exports.SuperExpression = SuperExpression;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
use :node;
|
|
2
|
+
|
|
3
|
+
var Node = module.require('../Node').Node;
|
|
4
|
+
|
|
5
|
+
fn ThisExpression()
|
|
6
|
+
extends Node {
|
|
7
|
+
|
|
8
|
+
this.type = 'ThisExpression';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
ThisExpression.prototype.codegen = () -> {
|
|
12
|
+
if !super.codegen() {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return this;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
ThisExpression.prototype.hasCallExpression = () -> false;
|
|
20
|
+
|
|
21
|
+
exports.ThisExpression = ThisExpression;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
use :node;
|
|
2
|
+
|
|
3
|
+
var Node = module.require('../Node').Node;
|
|
4
|
+
|
|
5
|
+
fn UnaryExpression(operator, argument)
|
|
6
|
+
extends Node {
|
|
7
|
+
|
|
8
|
+
this.type = 'UnaryExpression';
|
|
9
|
+
this.operator = operator;
|
|
10
|
+
this.argument = argument;
|
|
11
|
+
this.argument.parent = this;
|
|
12
|
+
this.prefix = true;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
UnaryExpression.prototype.codegen = () -> {
|
|
16
|
+
if !super.codegen() {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this.argument = this.argument.codegen();
|
|
21
|
+
|
|
22
|
+
// typeof operator should compile to:
|
|
23
|
+
// ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
|
|
24
|
+
if (this.operator == 'typeof') {
|
|
25
|
+
var typeofExpression = {
|
|
26
|
+
"type": "CallExpression",
|
|
27
|
+
"callee": {
|
|
28
|
+
"type": "MemberExpression",
|
|
29
|
+
"computed": false,
|
|
30
|
+
"object": {
|
|
31
|
+
"type": "MemberExpression",
|
|
32
|
+
"computed": true,
|
|
33
|
+
"object": {
|
|
34
|
+
"type": "CallExpression",
|
|
35
|
+
"callee": {
|
|
36
|
+
"type": "MemberExpression",
|
|
37
|
+
"computed": false,
|
|
38
|
+
"object": {
|
|
39
|
+
"type": "CallExpression",
|
|
40
|
+
"callee": {
|
|
41
|
+
"type": "MemberExpression",
|
|
42
|
+
"computed": false,
|
|
43
|
+
"object": {
|
|
44
|
+
"type": "MemberExpression",
|
|
45
|
+
"computed": false,
|
|
46
|
+
"object": {
|
|
47
|
+
"type": "ObjectExpression",
|
|
48
|
+
"properties": []
|
|
49
|
+
},
|
|
50
|
+
"property": {
|
|
51
|
+
"type": "Identifier",
|
|
52
|
+
"name": "toString"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"property": {
|
|
56
|
+
"type": "Identifier",
|
|
57
|
+
"name": "call"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"arguments": [this.argument]
|
|
61
|
+
},
|
|
62
|
+
"property": {
|
|
63
|
+
"type": "Identifier",
|
|
64
|
+
"name": "match"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"arguments": [{
|
|
68
|
+
"type": "Literal",
|
|
69
|
+
"value": new ::RegExp("\\s([a-zA-Z]+)")
|
|
70
|
+
}]
|
|
71
|
+
},
|
|
72
|
+
"property": {
|
|
73
|
+
"type": "Literal",
|
|
74
|
+
"value": 1,
|
|
75
|
+
"raw": "1"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"property": {
|
|
79
|
+
"type": "Identifier",
|
|
80
|
+
"name": "toLowerCase"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"arguments": []
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
if !this.argument.hasCallExpression() {
|
|
87
|
+
this.type = "ConditionalExpression";
|
|
88
|
+
this.test = {
|
|
89
|
+
"type": "BinaryExpression",
|
|
90
|
+
"operator": "===",
|
|
91
|
+
"left": {
|
|
92
|
+
"type": "UnaryExpression",
|
|
93
|
+
"operator": "typeof",
|
|
94
|
+
"argument": this.argument,
|
|
95
|
+
"prefix": true
|
|
96
|
+
},
|
|
97
|
+
"right": {
|
|
98
|
+
"type": "Literal",
|
|
99
|
+
"value": "undefined",
|
|
100
|
+
"raw": "'undefined'"
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
this.consequent = {
|
|
105
|
+
"type": "Literal",
|
|
106
|
+
"value": "undefined"
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
this.alternate = typeofExpression;
|
|
110
|
+
} else {
|
|
111
|
+
this.type = typeofExpression.type;
|
|
112
|
+
this.callee = typeofExpression.callee;
|
|
113
|
+
::Object.defineProperty(this, 'arguments', {
|
|
114
|
+
value: typeofExpression.arguments,
|
|
115
|
+
enumerable: true
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
} else if this.operator == "<-" {
|
|
119
|
+
var parent = this.parent;
|
|
120
|
+
while parent? and parent.type != "FunctionExpression" and parent.type != "GoStatement" {
|
|
121
|
+
parent = parent.parent;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if not parent? or
|
|
125
|
+
(parent.type != "GoStatement" and
|
|
126
|
+
(parent.parent.type != "UnaryExpression" or
|
|
127
|
+
parent.parent.operator != "async")) {
|
|
128
|
+
Node.getErrorManager().error({
|
|
129
|
+
type: "GetExpressionRequiresAsync",
|
|
130
|
+
message: "unary <- must be in a go statement or an async function",
|
|
131
|
+
loc: this.loc
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
this.operator = "await";
|
|
136
|
+
this.argument = {
|
|
137
|
+
"type": "CallExpression",
|
|
138
|
+
"callee": {
|
|
139
|
+
"type": "MemberExpression",
|
|
140
|
+
"object": this.argument,
|
|
141
|
+
"property": {
|
|
142
|
+
"type": "Identifier",
|
|
143
|
+
"name": "get"
|
|
144
|
+
},
|
|
145
|
+
"computed": false
|
|
146
|
+
},
|
|
147
|
+
"arguments": []
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return this;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
UnaryExpression.prototype.hasCallExpression = () -> {
|
|
155
|
+
return this.argument?.hasCallExpression();
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
exports.UnaryExpression = UnaryExpression;
|