Skip to content

Commit e2fec9e

Browse files
committed
add tests, bug fixes for FunctionExpression, CallExpression.
Also adds transform function to ensure that node types match those expected by escodegen.
1 parent d17061c commit e2fec9e

13 files changed

Lines changed: 518 additions & 167 deletions

.eslintrc.json

Lines changed: 105 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -18,112 +18,116 @@
1818
},
1919

2020
"rules": {
21-
"accessor-pairs": 2,
22-
"arrow-parens": [2, "as-needed"],
23-
"arrow-spacing": [2, { "before": true, "after": true }],
24-
"block-spacing": [2, "always"],
25-
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
26-
"comma-dangle": [2, "never"],
27-
"comma-spacing": [2, { "before": false, "after": true }],
28-
"comma-style": [2, "last"],
29-
"constructor-super": 2,
30-
"curly": [2, "multi-line"],
31-
"dot-location": [2, "property"],
32-
"eol-last": 2,
33-
"eqeqeq": [2, "allow-null"],
34-
"generator-star-spacing": [2, { "before": true, "after": true }],
35-
"handle-callback-err": [2, "^(err|error)$"],
36-
"indent": [2, 2, { "SwitchCase": 1 }],
37-
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
38-
"keyword-spacing": [2, { "before": true, "after": true }],
39-
"new-cap": [2, { "newIsCap": true, "capIsNew": false }],
40-
"new-parens": 2,
41-
"no-array-constructor": 2,
42-
"no-caller": 2,
43-
"no-class-assign": 2,
44-
"no-cond-assign": 2,
45-
"no-const-assign": 2,
46-
"no-control-regex": 2,
47-
"no-debugger": 2,
48-
"no-delete-var": 2,
49-
"no-dupe-args": 2,
50-
"no-dupe-class-members": 2,
51-
"no-dupe-keys": 2,
52-
"no-duplicate-case": 2,
53-
"no-empty-character-class": 2,
54-
"no-eval": 2,
55-
"no-ex-assign": 2,
56-
"no-extend-native": 2,
57-
"no-extra-bind": 2,
58-
"no-extra-boolean-cast": 2,
59-
"no-extra-parens": [2, "functions"],
60-
"no-fallthrough": 2,
61-
"no-floating-decimal": 2,
62-
"no-func-assign": 2,
63-
"no-implied-eval": 2,
64-
"no-implicit-coercion": 2,
65-
"no-inner-declarations": [2, "functions"],
66-
"no-invalid-regexp": 2,
67-
"no-irregular-whitespace": 2,
68-
"no-iterator": 2,
69-
"no-label-var": 2,
70-
"no-labels": 2,
71-
"no-lone-blocks": 2,
72-
"no-lonely-if": 2,
73-
"no-mixed-spaces-and-tabs": 2,
21+
"accessor-pairs": 1,
22+
"arrow-parens": [1, "as-needed"],
23+
"arrow-spacing": [1, { "before": true, "after": true }],
24+
"block-spacing": [1, "always"],
25+
"brace-style": [1, "1tbs", { "allowSingleLine": true }],
26+
"comma-dangle": [1, "never"],
27+
"comma-spacing": [1, { "before": false, "after": true }],
28+
"comma-style": [1, "last"],
29+
"constructor-super": 1,
30+
"curly": [1, "multi-line"],
31+
"dot-location": [1, "property"],
32+
"eol-last": 1,
33+
"eqeqeq": [1, "allow-null"],
34+
"generator-star-spacing": [1, { "before": true, "after": true }],
35+
"handle-callback-err": [1, "^(err|error)$"],
36+
"indent": [1, 2, { "SwitchCase": 1 }],
37+
"key-spacing": [1, { "beforeColon": false, "afterColon": true }],
38+
"keyword-spacing": [1, { "before": true, "after": true }],
39+
"new-cap": [1, { "newIsCap": true, "capIsNew": false }],
40+
"new-parens": 1,
41+
"no-array-constructor": 1,
42+
"no-caller": 1,
43+
"no-class-assign": 1,
44+
"no-cond-assign": 1,
45+
"no-const-assign": 1,
46+
"no-control-regex": 1,
47+
"no-debugger": 1,
48+
"no-delete-var": 1,
49+
"no-dupe-args": 1,
50+
"no-dupe-class-members": 1,
51+
"no-dupe-keys": 1,
52+
"no-duplicate-case": 1,
53+
"no-duplicate-imports": 1,
54+
"no-empty": 1,
55+
"no-empty-character-class": 1,
56+
"no-eval": 1,
57+
"no-ex-assign": 1,
58+
"no-extend-native": 1,
59+
"no-extra-bind": 1,
60+
"no-extra-boolean-cast": 1,
61+
"no-extra-parens": [1, "functions"],
62+
"no-extra-semi": 1,
63+
"no-fallthrough": 1,
64+
"no-floating-decimal": 1,
65+
"no-func-assign": 1,
66+
"no-implied-eval": 1,
67+
"no-invalid-this": 0,
68+
"no-implicit-coercion": 1,
69+
"no-inner-declarations": [1, "functions"],
70+
"no-invalid-regexp": 1,
71+
"no-irregular-whitespace": 1,
72+
"no-iterator": 1,
73+
"no-label-var": 1,
74+
"no-labels": 1,
75+
"no-lone-blocks": 1,
76+
"no-lonely-if": 1,
77+
"no-mixed-spaces-and-tabs": 1,
7478
"no-multi-spaces": 0,
75-
"no-multi-str": 2,
76-
"no-multiple-empty-lines": [2, { "max": 1 }],
77-
"no-native-reassign": 2,
78-
"no-negated-in-lhs": 2,
79-
"no-new": 2,
80-
"no-new-func": 2,
81-
"no-new-object": 2,
82-
"no-new-require": 2,
83-
"no-new-wrappers": 2,
84-
"no-obj-calls": 2,
85-
"no-octal": 2,
86-
"no-octal-escape": 2,
87-
"no-proto": 2,
88-
"no-redeclare": 2,
89-
"no-regex-spaces": 2,
90-
"no-return-assign": 2,
91-
"no-self-compare": 2,
92-
"no-sequences": 2,
93-
"no-shadow-restricted-names": 2,
94-
"no-spaced-func": 2,
95-
"no-sparse-arrays": 2,
96-
"no-this-before-super": 2,
97-
"no-throw-literal": 2,
98-
"no-trailing-spaces": 2,
79+
"no-multi-str": 1,
80+
"no-multiple-empty-lines": [1, { "max": 1 }],
81+
"no-native-reassign": 1,
82+
"no-negated-in-lhs": 1,
83+
"no-new": 1,
84+
"no-new-func": 1,
85+
"no-new-object": 1,
86+
"no-new-require": 1,
87+
"no-new-wrappers": 1,
88+
"no-obj-calls": 1,
89+
"no-octal": 1,
90+
"no-octal-escape": 1,
91+
"no-proto": 1,
92+
"no-redeclare": 1,
93+
"no-regex-spaces": 1,
94+
"no-return-assign": 1,
95+
"no-self-compare": 1,
96+
"no-sequences": 1,
97+
"no-shadow-restricted-names": 1,
98+
"no-spaced-func": 1,
99+
"no-sparse-arrays": 1,
100+
"no-this-before-super": 1,
101+
"no-throw-literal": 1,
102+
"no-trailing-spaces": 1,
99103
"no-undef": 2,
100-
"no-undef-init": 2,
101-
"no-unexpected-multiline": 2,
102-
"no-unneeded-ternary": [2, { "defaultAssignment": false }],
103-
"no-unreachable": 2,
104-
"no-unused-expressions": 2,
105-
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
106-
"no-useless-call": 2,
107-
"no-with": 2,
104+
"no-undef-init": 1,
105+
"no-unexpected-multiline": 1,
106+
"no-unneeded-ternary": [1, { "defaultAssignment": false }],
107+
"no-unreachable": 1,
108+
"no-unused-expressions": 1,
109+
"no-unused-vars": [1, { "vars": "all", "args": "none" }],
110+
"no-useless-call": 1,
111+
"no-with": 1,
108112
"object-curly-spacing": ["error", "always", { "objectsInObjects": true }],
109-
"one-var": [2, { "initialized": "never" }],
113+
"one-var": [1, { "initialized": "never" }],
110114
"operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }],
111115
"padded-blocks": [0, "never"],
112-
"prefer-const": [2, { "destructuring": "all", "ignoreReadBeforeAssign": false }],
113-
"quotes": [2, "single", "avoid-escape"],
114-
"radix": 2,
115-
"semi": [2, "always"],
116-
"semi-spacing": [2, { "before": false, "after": true }],
117-
"space-before-blocks": [2, "always"],
118-
"space-before-function-paren": [2, { "anonymous": "never", "named": "never", "asyncArrow": "always" }],
119-
"space-in-parens": [2, "never"],
120-
"space-infix-ops": 2,
121-
"space-unary-ops": [2, { "words": true, "nonwords": false }],
116+
"prefer-const": [1, { "destructuring": "all", "ignoreReadBeforeAssign": false }],
117+
"quotes": [1, "single", "avoid-escape"],
118+
"radix": 1,
119+
"semi": [1, "always"],
120+
"semi-spacing": [1, { "before": false, "after": true }],
121+
"space-before-blocks": [1, "always"],
122+
"space-before-function-paren": [1, { "anonymous": "never", "named": "never", "asyncArrow": "always" }],
123+
"space-in-parens": [1, "never"],
124+
"space-infix-ops": 1,
125+
"space-unary-ops": [1, { "words": true, "nonwords": false }],
122126
"spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }],
123-
"strict": 2,
124-
"use-isnan": 2,
125-
"valid-typeof": 2,
126-
"wrap-iife": [2, "any"],
127-
"yoda": [2, "never"]
127+
"strict": 1,
128+
"use-isnan": 1,
129+
"valid-typeof": 1,
130+
"wrap-iife": [1, "any"],
131+
"yoda": [1, "never"]
128132
}
129133
}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,4 @@ vendor
7171
.chat
7272
*.generated.*
7373
*.updated.*
74+
issues.md

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ You might also be interested in these projects:
370370

371371
| **Commits** | **Contributor** |
372372
| --- | --- |
373-
| 42 | [jonschlinkert](https://github.com/jonschlinkert) |
373+
| 45 | [jonschlinkert](https://github.com/jonschlinkert) |
374374
| 1 | [6utt3rfly](https://github.com/6utt3rfly) |
375375
| 1 | [freshgum-bubbles](https://github.com/freshgum-bubbles) |
376376

@@ -389,4 +389,4 @@ Released under the [MIT License](LICENSE).
389389

390390
***
391391

392-
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on February 06, 2025._
392+
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 19, 2025._

lib/Expression.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const ExpressionSync = require('./ExpressionSync');
4+
const transform = require('./transform');
45
const variables = require('./variables');
56
const utils = require('./utils');
67

@@ -21,13 +22,18 @@ class Expression extends ExpressionSync {
2122
async comparison(left, operator, right, context, node) {
2223
const bool = this.options.booleanLogicalOperators === true;
2324

24-
if (typeof left === 'symbol' || typeof right === 'symbol') {
25+
if (typeof left === 'symbol' && left === Expression.FAIL) {
26+
this.state.fail = true;
27+
return Expression.FAIL;
28+
}
29+
30+
if (typeof right === 'symbol' && right === Expression.FAIL) {
2531
this.state.fail = true;
2632
return Expression.FAIL;
2733
}
2834

2935
const s = v => {
30-
if (typeof v === 'symbol') {
36+
if (typeof v === 'symbol' && v === Expression.FAIL) {
3137
this.state.fail = true;
3238
return;
3339
}
@@ -38,16 +44,6 @@ class Expression extends ExpressionSync {
3844
const val = () => s(typeof right === 'function' ? right() : right);
3945

4046
switch (operator) {
41-
case 'in': {
42-
const value = await val();
43-
44-
if (!this.options.strict && (typeof value === 'string' || Array.isArray(value))) {
45-
return value.includes(left);
46-
}
47-
48-
return left in value;
49-
}
50-
5147
// Arithmetic operators
5248
case '+': return left + await val();
5349
case '-': return left - await val();
@@ -57,11 +53,20 @@ class Expression extends ExpressionSync {
5753
case '**': return left ** await val();
5854

5955
// Relational operators
60-
case 'instanceof': return left instanceof await val();
6156
case '<': return left < await val();
6257
case '>': return left > await val();
6358
case '<=': return left <= await val();
6459
case '>=': return left >= await val();
60+
case 'instanceof': return left instanceof await val();
61+
case 'in': {
62+
const value = await val();
63+
64+
if (!this.options.strict && (typeof value === 'string' || Array.isArray(value))) {
65+
return value.includes(left);
66+
}
67+
68+
return left in value;
69+
}
6570

6671
// Equality operators
6772
case '!==': return left !== await val();
@@ -128,6 +133,13 @@ class Expression extends ExpressionSync {
128133
}
129134
}
130135

136+
async BinaryExpression(node, context) {
137+
const left = await this.visit(node.left, context, node);
138+
const right = () => this.visit(node.right, context, node);
139+
140+
return this.comparison(left, node.operator, right, context, node);
141+
}
142+
131143
async BlockStatement(node, context, parent) {
132144
const output = [];
133145

@@ -202,6 +214,10 @@ class Expression extends ExpressionSync {
202214
output += await this.visit(node.quasis[length], context, node);
203215
return output;
204216
}
217+
218+
async YieldExpression(node, context) {
219+
throw new SyntaxError('YieldExpression is not supported yet');
220+
}
205221
}
206222

207223
Expression.evaluate.sync = (...args) => ExpressionSync.evaluate(...args);

lib/ExpressionSync.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class ExpressionSync {
3434
seenObjects: new WeakSet(),
3535
templateLiterals: new Set()
3636
};
37+
3738
this.stack = [];
3839
this.seen = new Set();
3940

@@ -46,6 +47,7 @@ class ExpressionSync {
4647

4748
incrementDepth() {
4849
this.state.expressionDepth++;
50+
4951
if (this.state.expressionDepth > MAX_EXPRESSION_DEPTH) {
5052
throw new RangeError('Maximum expression depth exceeded');
5153
}
@@ -393,7 +395,10 @@ class ExpressionSync {
393395
if (type === 'SpreadElement') {
394396
Object.assign(object, this.visit(property, context, node));
395397
} else {
396-
const name = property.computed ? this.visit(key, context, property) : (key.value || key.name);
398+
const name = property.computed
399+
? this.visit(key, context, property)
400+
: (key.value || key.name);
401+
397402
object[name] = this.visit(value, context, property);
398403
}
399404
}
@@ -469,6 +474,7 @@ class ExpressionSync {
469474
case '!': return !v;
470475
case '+': return +v; // eslint-disable-line no-implicit-coercion
471476
case '-': return -v;
477+
default: break;
472478
}
473479
};
474480

0 commit comments

Comments
 (0)