@next-core/cook 1.4.0 → 1.6.1

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,36 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.6.1](https://github.com/easyops-cn/next-core/compare/@next-core/cook@1.6.0...@next-core/cook@1.6.1) (2021-12-03)
7
+
8
+ **Note:** Version bump only for package @next-core/cook
9
+
10
+
11
+
12
+
13
+
14
+ # [1.6.0](https://github.com/easyops-cn/next-core/compare/@next-core/cook@1.5.0...@next-core/cook@1.6.0) (2021-11-29)
15
+
16
+
17
+ ### Features
18
+
19
+ * support visit node with parent ([80f1ada](https://github.com/easyops-cn/next-core/commit/80f1ada97e1b720f787753fab4eedf618c08f36b))
20
+
21
+
22
+
23
+
24
+
25
+ # [1.5.0](https://github.com/easyops-cn/next-core/compare/@next-core/cook@1.4.0...@next-core/cook@1.5.0) (2021-11-26)
26
+
27
+
28
+ ### Features
29
+
30
+ * support hooks for before visit global or unknown nodes ([50d770c](https://github.com/easyops-cn/next-core/commit/50d770c45a8194c12c3764f53d75a1a9519b790e))
31
+
32
+
33
+
34
+
35
+
6
36
  # [1.4.0](https://github.com/easyops-cn/next-core/compare/@next-core/cook@1.3.9...@next-core/cook@1.4.0) (2021-11-25)
7
37
 
8
38
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/AnalysisContext.ts"],"names":["AnalysisContext","AnalysisEnvironment","constructor","outer","Set","OuterEnv","HasBinding","name","bindingSet","has","CreateBinding","add"],"mappings":";;;;;;;;;;;AAEA;AACO,MAAMA,eAAN,CAAsB;AAAA;AAAA;AAAA;AAAA;;AAAA,C,CAK7B;;;;;AACO,MAAMC,mBAAN,CAA0B;AAI/BC,EAAAA,WAAW,CAACC,KAAD,EAA6B;AAAA;AAAA,sDAFV,IAAIC,GAAJ,EAEU;AACtC,SAAKC,QAAL,GAAgBF,KAAhB;AACD;;AAEDG,EAAAA,UAAU,CAACC,IAAD,EAAwB;AAChC,WAAO,KAAKC,UAAL,CAAgBC,GAAhB,CAAoBF,IAApB,CAAP;AACD;;AAEDG,EAAAA,aAAa,CAACH,IAAD,EAAqB;AAChC,SAAKC,UAAL,CAAgBG,GAAhB,CAAoBJ,IAApB;AACD;;AAd8B","sourcesContent":["import { Expression, FunctionDeclaration, Statement } from \"@babel/types\";\n\n// https://tc39.es/ecma262/#sec-execution-contexts\nexport class AnalysisContext {\n VariableEnvironment: AnalysisEnvironment;\n LexicalEnvironment: AnalysisEnvironment;\n}\n\n// https://tc39.es/ecma262/#sec-environment-records\nexport class AnalysisEnvironment {\n readonly OuterEnv: AnalysisEnvironment;\n private readonly bindingSet = new Set<string>();\n\n constructor(outer: AnalysisEnvironment) {\n this.OuterEnv = outer;\n }\n\n HasBinding(name: string): boolean {\n return this.bindingSet.has(name);\n }\n\n CreateBinding(name: string): void {\n this.bindingSet.add(name);\n }\n}\n\nexport interface AnalysisFunctionObject {\n FormalParameters: FunctionDeclaration[\"params\"];\n ECMAScriptCode: Statement[] | Expression;\n Environment: AnalysisEnvironment;\n}\n"],"file":"AnalysisContext.js"}
1
+ {"version":3,"sources":["../../src/AnalysisContext.ts"],"names":["AnalysisContext","AnalysisEnvironment","constructor","outer","Set","OuterEnv","HasBinding","name","bindingSet","has","CreateBinding","add"],"mappings":";;;;;;;;;;;AAQA;AACO,MAAMA,eAAN,CAAsB;AAAA;AAAA;AAAA;AAAA;;AAAA,C,CAK7B;;;;;AACO,MAAMC,mBAAN,CAA0B;AAI/BC,EAAAA,WAAW,CAACC,KAAD,EAA6B;AAAA;AAAA,sDAFV,IAAIC,GAAJ,EAEU;AACtC,SAAKC,QAAL,GAAgBF,KAAhB;AACD;;AAEDG,EAAAA,UAAU,CAACC,IAAD,EAAwB;AAChC,WAAO,KAAKC,UAAL,CAAgBC,GAAhB,CAAoBF,IAApB,CAAP;AACD;;AAEDG,EAAAA,aAAa,CAACH,IAAD,EAAqB;AAChC,SAAKC,UAAL,CAAgBG,GAAhB,CAAoBJ,IAApB;AACD;;AAd8B","sourcesContent":["import {\n ArrowFunctionExpression,\n Expression,\n FunctionDeclaration,\n FunctionExpression,\n Statement,\n} from \"@babel/types\";\n\n// https://tc39.es/ecma262/#sec-execution-contexts\nexport class AnalysisContext {\n VariableEnvironment: AnalysisEnvironment;\n LexicalEnvironment: AnalysisEnvironment;\n}\n\n// https://tc39.es/ecma262/#sec-environment-records\nexport class AnalysisEnvironment {\n readonly OuterEnv: AnalysisEnvironment;\n private readonly bindingSet = new Set<string>();\n\n constructor(outer: AnalysisEnvironment) {\n this.OuterEnv = outer;\n }\n\n HasBinding(name: string): boolean {\n return this.bindingSet.has(name);\n }\n\n CreateBinding(name: string): void {\n this.bindingSet.add(name);\n }\n}\n\nexport interface AnalysisFunctionObject {\n Function: FunctionDeclaration | FunctionExpression | ArrowFunctionExpression;\n FormalParameters: FunctionDeclaration[\"params\"];\n ECMAScriptCode: Statement[] | Expression;\n Environment: AnalysisEnvironment;\n}\n"],"file":"AnalysisContext.js"}
package/dist/cjs/lint.js CHANGED
@@ -75,93 +75,100 @@ function lint(source, {
75
75
  }
76
76
  });
77
77
  } else {
78
- const FunctionVisitor = node => {
79
- if (node.async || node.generator) {
80
- errors.push({
81
- type: "SyntaxError",
82
- message: `${node.async ? "Async" : "Generator"} function is not allowed`,
83
- loc: node.loc
84
- });
85
- }
86
- };
87
-
88
78
  (0, _precook.precook)(func, {
89
- visitors: {
90
- ArrowFunctionExpression: FunctionVisitor,
91
- FunctionDeclaration: FunctionVisitor,
92
- FunctionExpression: FunctionVisitor,
93
-
94
- Literal(node) {
95
- if (node.regex) {
96
- if (node.value === null) {
97
- errors.push({
98
- type: "SyntaxError",
99
- message: "Invalid regular expression",
100
- loc: node.loc
101
- });
102
- } else if (node.regex.flags.includes("u")) {
103
- errors.push({
104
- type: "SyntaxError",
105
- message: "Unsupported unicode flag in regular expression",
106
- loc: node.loc
107
- });
108
- }
109
- }
110
- },
111
-
112
- ObjectExpression(node) {
113
- for (const prop of node.properties) {
114
- if (prop.type === "Property") {
115
- if (prop.kind !== "init") {
79
+ hooks: {
80
+ beforeVisit(node) {
81
+ switch (node.type) {
82
+ case "ArrowFunctionExpression":
83
+ case "FunctionDeclaration":
84
+ case "FunctionExpression":
85
+ if (node.async || node.generator) {
116
86
  errors.push({
117
87
  type: "SyntaxError",
118
- message: "Unsupported object getter/setter property",
119
- loc: prop.loc
88
+ message: `${node.async ? "Async" : "Generator"} function is not allowed`,
89
+ loc: node.loc
120
90
  });
121
- } else if (!prop.computed && prop.key.type === "Identifier" && prop.key.name === "__proto__") {
91
+ }
92
+
93
+ break;
94
+
95
+ case "Literal":
96
+ if (node.regex) {
97
+ if (node.value === null) {
98
+ errors.push({
99
+ type: "SyntaxError",
100
+ message: "Invalid regular expression",
101
+ loc: node.loc
102
+ });
103
+ } else if (node.regex.flags.includes("u")) {
104
+ errors.push({
105
+ type: "SyntaxError",
106
+ message: "Unsupported unicode flag in regular expression",
107
+ loc: node.loc
108
+ });
109
+ }
110
+ }
111
+
112
+ break;
113
+
114
+ case "ObjectExpression":
115
+ for (const prop of node.properties) {
116
+ if (prop.type === "Property") {
117
+ if (prop.kind !== "init") {
118
+ errors.push({
119
+ type: "SyntaxError",
120
+ message: "Unsupported object getter/setter property",
121
+ loc: prop.loc
122
+ });
123
+ } else if (!prop.computed && prop.key.type === "Identifier" && prop.key.name === "__proto__") {
124
+ errors.push({
125
+ type: "TypeError",
126
+ message: "Setting '__proto__' property is not allowed",
127
+ loc: prop.key.loc
128
+ });
129
+ }
130
+ }
131
+ }
132
+
133
+ break;
134
+
135
+ case "VariableDeclaration":
136
+ if (node.kind === "var" && rules !== null && rules !== void 0 && rules.noVar) {
122
137
  errors.push({
123
- type: "TypeError",
124
- message: "Setting '__proto__' property is not allowed",
125
- loc: prop.key.loc
138
+ type: "SyntaxError",
139
+ message: "Var declaration is not recommended, use `let` or `const` instead",
140
+ loc: {
141
+ start: node.loc.start,
142
+ end: {
143
+ line: node.loc.end.line,
144
+ // Only decorate the "var".
145
+ column: node.loc.start.column + 3
146
+ }
147
+ }
126
148
  });
127
149
  }
128
- }
150
+
151
+ break;
129
152
  }
130
153
  },
131
154
 
132
- VariableDeclaration(node) {
133
- if (node.kind === "var" && rules !== null && rules !== void 0 && rules.noVar) {
155
+ beforeVisitGlobal(node) {
156
+ if (node.name === "arguments") {
134
157
  errors.push({
135
158
  type: "SyntaxError",
136
- message: "Var declaration is not recommended, use `let` or `const` instead",
137
- loc: {
138
- start: node.loc.start,
139
- end: {
140
- line: node.loc.end.line,
141
- // Only decorate the "var".
142
- column: node.loc.start.column + 3
143
- }
144
- }
159
+ message: "Use the rest parameters instead of 'arguments'",
160
+ loc: node.loc
145
161
  });
146
162
  }
147
163
  },
148
164
 
149
- __UnknownNode(node) {
165
+ beforeVisitUnknown(node) {
150
166
  errors.push({
151
167
  type: "SyntaxError",
152
168
  message: `Unsupported syntax: \`${node.type}\``,
153
169
  loc: node.loc
154
170
  });
155
- },
156
-
157
- __GlobalVariable(node) {
158
- if (node.name === "arguments") {
159
- errors.push({
160
- type: "SyntaxError",
161
- message: "Use the rest parameters instead of 'arguments'",
162
- loc: node.loc
163
- });
164
- }
171
+ return true;
165
172
  }
166
173
 
167
174
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lint.ts"],"names":["lint","source","typescript","rules","errors","file","body","program","jsNodes","node","type","startsWith","test","push","message","loc","func","isFunctionDeclaration","unshift","start","line","column","end","FunctionVisitor","async","generator","visitors","ArrowFunctionExpression","FunctionDeclaration","FunctionExpression","Literal","regex","value","flags","includes","ObjectExpression","prop","properties","kind","computed","key","name","VariableDeclaration","noVar","__UnknownNode","__GlobalVariable"],"mappings":";;;;;;;AAkBA;;AACA;;AAaA;AACO,SAASA,IAAT,CACLC,MADK,EAEL;AAAEC,EAAAA,UAAF;AAAcC,EAAAA;AAAd,IAAqC,EAFhC,EAGQ;AACb,QAAMC,MAAmB,GAAG,EAA5B;AACA,QAAMC,IAAI,GACR,OAAOJ,MAAP,KAAkB,QAAlB,GACI,6BAAiBA,MAAjB,EAAyB;AAAEC,IAAAA;AAAF,GAAzB,CADJ,GAEID,MAHN;;AAIA,MAAI,CAACI,IAAL,EAAW;AACT;AACA,WAAOD,MAAP;AACD;;AACD,QAAME,IAAI,GAAGD,IAAI,CAACE,OAAL,CAAaD,IAA1B;AACA,QAAME,OAAoB,GAAGN,UAAU,GAAG,EAAH,GAAQI,IAA/C;;AACA,MAAIJ,UAAJ,EAAgB;AACd,SAAK,MAAMO,IAAX,IAAmBH,IAAnB,EAAyB;AACvB,UAAIG,IAAI,CAACC,IAAL,CAAUC,UAAV,CAAqB,IAArB,CAAJ,EAAgC;AAC9B,YAAI,qBAAqBC,IAArB,CAA0BH,IAAI,CAACC,IAA/B,CAAJ,EAA0C;AACxCN,UAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,YAAAA,IAAI,EAAE,aADI;AAEVI,YAAAA,OAAO,EAAG,oCAAmCL,IAAI,CAACC,IAAK,IAF7C;AAGVK,YAAAA,GAAG,EAAEN,IAAI,CAACM;AAHA,WAAZ;AAKD;AACF,OARD,MAQO;AACLP,QAAAA,OAAO,CAACK,IAAR,CAAaJ,IAAb;AACD;AACF;AACF;;AACD,MAAIO,IAAJ;;AACA,OAAK,MAAMP,IAAX,IAAmBD,OAAnB,EAA4B;AAC1B,UAAMS,qBAAqB,GAAGR,IAAI,CAACC,IAAL,KAAc,qBAA5C;;AACA,QAAIO,qBAAqB,IAAI,CAACD,IAA9B,EAAoC;AAClCA,MAAAA,IAAI,GAAGP,IAAP;AACD,KAFD,MAEO;AACLL,MAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,QAAAA,IAAI,EAAE,aADI;AAEVI,QAAAA,OAAO,EAAEG,qBAAqB,GAC1B,sCAD0B,GAEzB,KAAIR,IAAI,CAACC,IAAK,gCAJT;AAKVK,QAAAA,GAAG,EAAEN,IAAI,CAACM;AALA,OAAZ;AAOD;AACF;;AACD,MAAI,CAACC,IAAL,EAAW;AACTZ,IAAAA,MAAM,CAACc,OAAP,CAAe;AACbR,MAAAA,IAAI,EAAE,aADO;AAEbI,MAAAA,OAAO,EAAE,gCAFI;AAGbC,MAAAA,GAAG,EAAE;AACHI,QAAAA,KAAK,EAAE;AAAEC,UAAAA,IAAI,EAAE,CAAR;AAAWC,UAAAA,MAAM,EAAE;AAAnB,SADJ;AAEHC,QAAAA,GAAG,EAAE;AAAEF,UAAAA,IAAI,EAAE,CAAR;AAAWC,UAAAA,MAAM,EAAE;AAAnB;AAFF;AAHQ,KAAf;AAQD,GATD,MASO;AACL,UAAME,eAAgC,GACpCd,IADuC,IAEpC;AACH,UAAIA,IAAI,CAACe,KAAL,IAAcf,IAAI,CAACgB,SAAvB,EAAkC;AAChCrB,QAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,UAAAA,IAAI,EAAE,aADI;AAEVI,UAAAA,OAAO,EAAG,GACRL,IAAI,CAACe,KAAL,GAAa,OAAb,GAAuB,WACxB,0BAJS;AAKVT,UAAAA,GAAG,EAAEN,IAAI,CAACM;AALA,SAAZ;AAOD;AACF,KAZD;;AAaA,0BAAQC,IAAR,EAAc;AACZU,MAAAA,QAAQ,EAAE;AACRC,QAAAA,uBAAuB,EAAEJ,eADjB;AAERK,QAAAA,mBAAmB,EAAEL,eAFb;AAGRM,QAAAA,kBAAkB,EAAEN,eAHZ;;AAIRO,QAAAA,OAAO,CAACrB,IAAD,EAAsB;AAC3B,cAAIA,IAAI,CAACsB,KAAT,EAAgB;AACd,gBAAItB,IAAI,CAACuB,KAAL,KAAe,IAAnB,EAAyB;AACvB5B,cAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,gBAAAA,IAAI,EAAE,aADI;AAEVI,gBAAAA,OAAO,EAAE,4BAFC;AAGVC,gBAAAA,GAAG,EAAEN,IAAI,CAACM;AAHA,eAAZ;AAKD,aAND,MAMO,IAAIN,IAAI,CAACsB,KAAL,CAAWE,KAAX,CAAiBC,QAAjB,CAA0B,GAA1B,CAAJ,EAAoC;AACzC9B,cAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,gBAAAA,IAAI,EAAE,aADI;AAEVI,gBAAAA,OAAO,EAAE,gDAFC;AAGVC,gBAAAA,GAAG,EAAEN,IAAI,CAACM;AAHA,eAAZ;AAKD;AACF;AACF,SApBO;;AAqBRoB,QAAAA,gBAAgB,CAAC1B,IAAD,EAA+B;AAC7C,eAAK,MAAM2B,IAAX,IAAmB3B,IAAI,CAAC4B,UAAxB,EAAoC;AAClC,gBAAID,IAAI,CAAC1B,IAAL,KAAc,UAAlB,EAA8B;AAC5B,kBAAI0B,IAAI,CAACE,IAAL,KAAc,MAAlB,EAA0B;AACxBlC,gBAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,kBAAAA,IAAI,EAAE,aADI;AAEVI,kBAAAA,OAAO,EAAE,2CAFC;AAGVC,kBAAAA,GAAG,EAAEqB,IAAI,CAACrB;AAHA,iBAAZ;AAKD,eAND,MAMO,IACL,CAACqB,IAAI,CAACG,QAAN,IACAH,IAAI,CAACI,GAAL,CAAS9B,IAAT,KAAkB,YADlB,IAEA0B,IAAI,CAACI,GAAL,CAASC,IAAT,KAAkB,WAHb,EAIL;AACArC,gBAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,kBAAAA,IAAI,EAAE,WADI;AAEVI,kBAAAA,OAAO,EAAE,6CAFC;AAGVC,kBAAAA,GAAG,EAAEqB,IAAI,CAACI,GAAL,CAASzB;AAHJ,iBAAZ;AAKD;AACF;AACF;AACF,SA3CO;;AA4CR2B,QAAAA,mBAAmB,CAACjC,IAAD,EAA4B;AAC7C,cAAIA,IAAI,CAAC6B,IAAL,KAAc,KAAd,IAAuBnC,KAAvB,aAAuBA,KAAvB,eAAuBA,KAAK,CAAEwC,KAAlC,EAAyC;AACvCvC,YAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,cAAAA,IAAI,EAAE,aADI;AAEVI,cAAAA,OAAO,EACL,kEAHQ;AAIVC,cAAAA,GAAG,EAAE;AACHI,gBAAAA,KAAK,EAAEV,IAAI,CAACM,GAAL,CAASI,KADb;AAEHG,gBAAAA,GAAG,EAAE;AACHF,kBAAAA,IAAI,EAAEX,IAAI,CAACM,GAAL,CAASO,GAAT,CAAaF,IADhB;AAEH;AACAC,kBAAAA,MAAM,EAAEZ,IAAI,CAACM,GAAL,CAASI,KAAT,CAAeE,MAAf,GAAwB;AAH7B;AAFF;AAJK,aAAZ;AAaD;AACF,SA5DO;;AA6DRuB,QAAAA,aAAa,CAACnC,IAAD,EAAmB;AAC9BL,UAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,YAAAA,IAAI,EAAE,aADI;AAEVI,YAAAA,OAAO,EAAG,yBAAwBL,IAAI,CAACC,IAAK,IAFlC;AAGVK,YAAAA,GAAG,EAAEN,IAAI,CAACM;AAHA,WAAZ;AAKD,SAnEO;;AAoER8B,QAAAA,gBAAgB,CAACpC,IAAD,EAAmB;AACjC,cAAIA,IAAI,CAACgC,IAAL,KAAc,WAAlB,EAA+B;AAC7BrC,YAAAA,MAAM,CAACS,IAAP,CAAY;AACVH,cAAAA,IAAI,EAAE,aADI;AAEVI,cAAAA,OAAO,EAAE,gDAFC;AAGVC,cAAAA,GAAG,EAAEN,IAAI,CAACM;AAHA,aAAZ;AAKD;AACF;;AA5EO;AADE,KAAd;AAgFD;;AACD,SAAOX,MAAP;AACD","sourcesContent":["import { ParseResult } from \"@babel/parser\";\nimport {\n ArrowFunctionExpression,\n File,\n FunctionDeclaration,\n FunctionExpression,\n Identifier,\n SourceLocation,\n Statement,\n VariableDeclaration,\n} from \"@babel/types\";\nimport {\n EstreeLiteral,\n CookRules,\n EstreeObjectExpression,\n EstreeVisitorFn,\n EstreeNode,\n} from \"./interfaces\";\nimport { parseForAnalysis } from \"./parse\";\nimport { precook } from \"./precook\";\n\nexport interface LintOptions {\n typescript?: boolean;\n rules?: CookRules;\n}\n\nexport interface LintError {\n type: \"SyntaxError\" | \"TypeError\";\n message: string;\n loc: SourceLocation;\n}\n\n/** For next-core internal or devtools usage only. */\nexport function lint(\n source: string | ParseResult<File>,\n { typescript, rules }: LintOptions = {}\n): LintError[] {\n const errors: LintError[] = [];\n const file =\n typeof source === \"string\"\n ? parseForAnalysis(source, { typescript })\n : source;\n if (!file) {\n // Return no errors if parse failed.\n return errors;\n }\n const body = file.program.body;\n const jsNodes: Statement[] = typescript ? [] : body;\n if (typescript) {\n for (const node of body) {\n if (node.type.startsWith(\"TS\")) {\n if (/Enum|Import|Export/.test(node.type)) {\n errors.push({\n type: \"SyntaxError\",\n message: `Unsupported TypeScript syntax: \\`${node.type}\\``,\n loc: node.loc,\n });\n }\n } else {\n jsNodes.push(node);\n }\n }\n }\n let func: FunctionDeclaration;\n for (const node of jsNodes) {\n const isFunctionDeclaration = node.type === \"FunctionDeclaration\";\n if (isFunctionDeclaration && !func) {\n func = node;\n } else {\n errors.push({\n type: \"SyntaxError\",\n message: isFunctionDeclaration\n ? \"Expect a single function declaration\"\n : `\\`${node.type}\\` is not allowed in top level`,\n loc: node.loc,\n });\n }\n }\n if (!func) {\n errors.unshift({\n type: \"SyntaxError\",\n message: \"Function declaration not found\",\n loc: {\n start: { line: 1, column: 0 },\n end: { line: 1, column: 0 },\n },\n });\n } else {\n const FunctionVisitor: EstreeVisitorFn = (\n node: FunctionDeclaration | FunctionExpression | ArrowFunctionExpression\n ) => {\n if (node.async || node.generator) {\n errors.push({\n type: \"SyntaxError\",\n message: `${\n node.async ? \"Async\" : \"Generator\"\n } function is not allowed`,\n loc: node.loc,\n });\n }\n };\n precook(func, {\n visitors: {\n ArrowFunctionExpression: FunctionVisitor,\n FunctionDeclaration: FunctionVisitor,\n FunctionExpression: FunctionVisitor,\n Literal(node: EstreeLiteral) {\n if (node.regex) {\n if (node.value === null) {\n errors.push({\n type: \"SyntaxError\",\n message: \"Invalid regular expression\",\n loc: node.loc,\n });\n } else if (node.regex.flags.includes(\"u\")) {\n errors.push({\n type: \"SyntaxError\",\n message: \"Unsupported unicode flag in regular expression\",\n loc: node.loc,\n });\n }\n }\n },\n ObjectExpression(node: EstreeObjectExpression) {\n for (const prop of node.properties) {\n if (prop.type === \"Property\") {\n if (prop.kind !== \"init\") {\n errors.push({\n type: \"SyntaxError\",\n message: \"Unsupported object getter/setter property\",\n loc: prop.loc,\n });\n } else if (\n !prop.computed &&\n prop.key.type === \"Identifier\" &&\n prop.key.name === \"__proto__\"\n ) {\n errors.push({\n type: \"TypeError\",\n message: \"Setting '__proto__' property is not allowed\",\n loc: prop.key.loc,\n });\n }\n }\n }\n },\n VariableDeclaration(node: VariableDeclaration) {\n if (node.kind === \"var\" && rules?.noVar) {\n errors.push({\n type: \"SyntaxError\",\n message:\n \"Var declaration is not recommended, use `let` or `const` instead\",\n loc: {\n start: node.loc.start,\n end: {\n line: node.loc.end.line,\n // Only decorate the \"var\".\n column: node.loc.start.column + 3,\n },\n },\n });\n }\n },\n __UnknownNode(node: EstreeNode) {\n errors.push({\n type: \"SyntaxError\",\n message: `Unsupported syntax: \\`${node.type}\\``,\n loc: node.loc,\n });\n },\n __GlobalVariable(node: Identifier) {\n if (node.name === \"arguments\") {\n errors.push({\n type: \"SyntaxError\",\n message: \"Use the rest parameters instead of 'arguments'\",\n loc: node.loc,\n });\n }\n },\n },\n });\n }\n return errors;\n}\n"],"file":"lint.js"}
1
+ {"version":3,"sources":["../../src/lint.ts"],"names":["lint","source","typescript","rules","errors","file","body","program","jsNodes","node","type","startsWith","test","push","message","loc","func","isFunctionDeclaration","unshift","start","line","column","end","hooks","beforeVisit","async","generator","regex","value","flags","includes","prop","properties","kind","computed","key","name","noVar","beforeVisitGlobal","beforeVisitUnknown"],"mappings":"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","sourcesContent":["import { ParseResult } from \"@babel/parser\";\nimport {\n File,\n FunctionDeclaration,\n SourceLocation,\n Statement,\n} from \"@babel/types\";\nimport { CookRules } from \"./interfaces\";\nimport { parseForAnalysis } from \"./parse\";\nimport { precook } from \"./precook\";\n\nexport interface LintOptions {\n typescript?: boolean;\n rules?: CookRules;\n}\n\nexport interface LintError {\n type: \"SyntaxError\" | \"TypeError\";\n message: string;\n loc: SourceLocation;\n}\n\n/** For next-core internal or devtools usage only. */\nexport function lint(\n source: string | ParseResult<File>,\n { typescript, rules }: LintOptions = {}\n): LintError[] {\n const errors: LintError[] = [];\n const file =\n typeof source === \"string\"\n ? parseForAnalysis(source, { typescript })\n : source;\n if (!file) {\n // Return no errors if parse failed.\n return errors;\n }\n const body = file.program.body;\n const jsNodes: Statement[] = typescript ? [] : body;\n if (typescript) {\n for (const node of body) {\n if (node.type.startsWith(\"TS\")) {\n if (/Enum|Import|Export/.test(node.type)) {\n errors.push({\n type: \"SyntaxError\",\n message: `Unsupported TypeScript syntax: \\`${node.type}\\``,\n loc: node.loc,\n });\n }\n } else {\n jsNodes.push(node);\n }\n }\n }\n let func: FunctionDeclaration;\n for (const node of jsNodes) {\n const isFunctionDeclaration = node.type === \"FunctionDeclaration\";\n if (isFunctionDeclaration && !func) {\n func = node;\n } else {\n errors.push({\n type: \"SyntaxError\",\n message: isFunctionDeclaration\n ? \"Expect a single function declaration\"\n : `\\`${node.type}\\` is not allowed in top level`,\n loc: node.loc,\n });\n }\n }\n if (!func) {\n errors.unshift({\n type: \"SyntaxError\",\n message: \"Function declaration not found\",\n loc: {\n start: { line: 1, column: 0 },\n end: { line: 1, column: 0 },\n },\n });\n } else {\n precook(func, {\n hooks: {\n beforeVisit(node) {\n switch (node.type) {\n case \"ArrowFunctionExpression\":\n case \"FunctionDeclaration\":\n case \"FunctionExpression\":\n if (node.async || node.generator) {\n errors.push({\n type: \"SyntaxError\",\n message: `${\n node.async ? \"Async\" : \"Generator\"\n } function is not allowed`,\n loc: node.loc,\n });\n }\n break;\n case \"Literal\":\n if (node.regex) {\n if (node.value === null) {\n errors.push({\n type: \"SyntaxError\",\n message: \"Invalid regular expression\",\n loc: node.loc,\n });\n } else if (node.regex.flags.includes(\"u\")) {\n errors.push({\n type: \"SyntaxError\",\n message: \"Unsupported unicode flag in regular expression\",\n loc: node.loc,\n });\n }\n }\n break;\n case \"ObjectExpression\":\n for (const prop of node.properties) {\n if (prop.type === \"Property\") {\n if (prop.kind !== \"init\") {\n errors.push({\n type: \"SyntaxError\",\n message: \"Unsupported object getter/setter property\",\n loc: prop.loc,\n });\n } else if (\n !prop.computed &&\n prop.key.type === \"Identifier\" &&\n prop.key.name === \"__proto__\"\n ) {\n errors.push({\n type: \"TypeError\",\n message: \"Setting '__proto__' property is not allowed\",\n loc: prop.key.loc,\n });\n }\n }\n }\n break;\n case \"VariableDeclaration\":\n if (node.kind === \"var\" && rules?.noVar) {\n errors.push({\n type: \"SyntaxError\",\n message:\n \"Var declaration is not recommended, use `let` or `const` instead\",\n loc: {\n start: node.loc.start,\n end: {\n line: node.loc.end.line,\n // Only decorate the \"var\".\n column: node.loc.start.column + 3,\n },\n },\n });\n }\n break;\n }\n },\n beforeVisitGlobal(node) {\n if (node.name === \"arguments\") {\n errors.push({\n type: \"SyntaxError\",\n message: \"Use the rest parameters instead of 'arguments'\",\n loc: node.loc,\n });\n }\n },\n beforeVisitUnknown(node) {\n errors.push({\n type: \"SyntaxError\",\n message: `Unsupported syntax: \\`${node.type}\\``,\n loc: node.loc,\n });\n return true;\n },\n },\n });\n }\n return errors;\n}\n"],"file":"lint.js"}
@@ -21,6 +21,7 @@ var _traverse = require("./traverse");
21
21
  function precook(rootAst, {
22
22
  expressionOnly,
23
23
  visitors,
24
+ withParent,
24
25
  hooks = {}
25
26
  } = {}) {
26
27
  const attemptToVisitGlobals = new Set();
@@ -41,102 +42,107 @@ function precook(rootAst, {
41
42
  }
42
43
  }
43
44
 
44
- function Evaluate(node) {
45
+ function EvaluateChildren(node, keys, parent) {
46
+ for (const key of keys) {
47
+ Evaluate(node[key], parent === null || parent === void 0 ? void 0 : parent.concat({
48
+ node,
49
+ key
50
+ }));
51
+ }
52
+ }
53
+
54
+ function Evaluate(node, parent) {
45
55
  if (Array.isArray(node)) {
46
- for (const n of node) {
47
- Evaluate(n);
48
- }
56
+ node.forEach((n, index) => {
57
+ Evaluate(n, parent ? parent.slice(0, -1).concat({ ...parent[parent.length - 1],
58
+ index
59
+ }) : parent);
60
+ });
49
61
  } else if (node) {
50
- var _hooks$beforeVisit;
62
+ var _hooks$beforeVisit, _hooks$beforeVisitUnk;
51
63
 
52
64
  // `node` maybe `null` in some cases.
53
- (_hooks$beforeVisit = hooks.beforeVisit) === null || _hooks$beforeVisit === void 0 ? void 0 : _hooks$beforeVisit.call(hooks, node);
65
+ (_hooks$beforeVisit = hooks.beforeVisit) === null || _hooks$beforeVisit === void 0 ? void 0 : _hooks$beforeVisit.call(hooks, node, parent);
54
66
  visitors && visit(node); // Expressions:
55
67
 
56
68
  switch (node.type) {
57
69
  case "Identifier":
58
70
  if (!ResolveBinding(node.name)) {
59
- attemptToVisitGlobals.add(node.name);
71
+ var _hooks$beforeVisitGlo;
60
72
 
61
- if (visitors && (0, _hasOwnProperty.hasOwnProperty)(visitors, "__GlobalVariable")) {
62
- visitors.__GlobalVariable(node);
63
- }
73
+ (_hooks$beforeVisitGlo = hooks.beforeVisitGlobal) === null || _hooks$beforeVisitGlo === void 0 ? void 0 : _hooks$beforeVisitGlo.call(hooks, node, parent);
74
+ attemptToVisitGlobals.add(node.name);
64
75
  }
65
76
 
66
77
  return;
67
78
 
68
79
  case "ArrayExpression":
69
80
  case "ArrayPattern":
70
- Evaluate(node.elements);
81
+ EvaluateChildren(node, ["elements"], parent);
71
82
  return;
72
83
 
73
84
  case "ArrowFunctionExpression":
74
85
  {
75
86
  const env = getRunningContext().LexicalEnvironment;
76
87
  const closure = OrdinaryFunctionCreate(node, env);
77
- CallFunction(closure);
88
+ CallFunction(closure, parent);
78
89
  return;
79
90
  }
80
91
 
81
92
  case "AssignmentPattern":
82
93
  case "BinaryExpression":
83
94
  case "LogicalExpression":
84
- Evaluate(node.left);
85
- Evaluate(node.right);
95
+ EvaluateChildren(node, ["left", "right"], parent);
86
96
  return;
87
97
 
88
98
  case "CallExpression":
89
99
  case "NewExpression":
90
- Evaluate(node.callee);
91
- Evaluate(node.arguments);
100
+ EvaluateChildren(node, ["callee", "arguments"], parent);
92
101
  return;
93
102
 
94
103
  case "ChainExpression":
95
- Evaluate(node.expression);
104
+ EvaluateChildren(node, ["expression"], parent);
96
105
  return;
97
106
 
98
107
  case "ConditionalExpression":
99
- Evaluate(node.test);
100
- Evaluate(node.consequent);
101
- Evaluate(node.alternate);
108
+ EvaluateChildren(node, ["test", "consequent", "alternate"], parent);
102
109
  return;
103
110
 
104
111
  case "MemberExpression":
105
- Evaluate(node.object);
112
+ EvaluateChildren(node, ["object"], parent);
106
113
 
107
114
  if (node.computed) {
108
- Evaluate(node.property);
115
+ EvaluateChildren(node, ["property"], parent);
109
116
  }
110
117
 
111
118
  return;
112
119
 
113
120
  case "ObjectExpression":
114
121
  case "ObjectPattern":
115
- Evaluate(node.properties);
122
+ EvaluateChildren(node, ["properties"], parent);
116
123
  return;
117
124
 
118
125
  case "Property":
119
126
  if (node.computed) {
120
- Evaluate(node.key);
127
+ EvaluateChildren(node, ["key"], parent);
121
128
  }
122
129
 
123
- Evaluate(node.value);
130
+ EvaluateChildren(node, ["value"], parent);
124
131
  return;
125
132
 
126
133
  case "RestElement":
127
134
  case "SpreadElement":
128
135
  case "UnaryExpression":
129
- Evaluate(node.argument);
136
+ EvaluateChildren(node, ["argument"], parent);
130
137
  return;
131
138
 
132
139
  case "SequenceExpression":
133
140
  case "TemplateLiteral":
134
- Evaluate(node.expressions);
141
+ EvaluateChildren(node, ["expressions"], parent);
135
142
  return;
136
143
 
137
144
  case "TaggedTemplateExpression":
138
- Evaluate(node.tag);
139
- Evaluate(node.quasi);
145
+ EvaluateChildren(node, ["tag", "quasi"], parent);
140
146
  return;
141
147
 
142
148
  case "Literal":
@@ -147,8 +153,7 @@ function precook(rootAst, {
147
153
  // Statements and assignments:
148
154
  switch (node.type) {
149
155
  case "AssignmentExpression":
150
- Evaluate(node.right);
151
- Evaluate(node.left);
156
+ EvaluateChildren(node, ["right", "left"], parent);
152
157
  return;
153
158
 
154
159
  case "BlockStatement":
@@ -162,7 +167,7 @@ function precook(rootAst, {
162
167
  const blockEnv = new _AnalysisContext.AnalysisEnvironment(oldEnv);
163
168
  BlockDeclarationInstantiation(node.body, blockEnv);
164
169
  runningContext.LexicalEnvironment = blockEnv;
165
- Evaluate(node.body);
170
+ EvaluateChildren(node, ["body"], parent);
166
171
  runningContext.LexicalEnvironment = oldEnv;
167
172
  return;
168
173
  }
@@ -179,20 +184,18 @@ function precook(rootAst, {
179
184
  const catchEnv = new _AnalysisContext.AnalysisEnvironment(oldEnv);
180
185
  BoundNamesInstantiation(node.param, catchEnv);
181
186
  runningContext.LexicalEnvironment = catchEnv;
182
- Evaluate(node.param);
183
- Evaluate(node.body);
187
+ EvaluateChildren(node, ["param", "body"], parent);
184
188
  runningContext.LexicalEnvironment = oldEnv;
185
189
  return;
186
190
  }
187
191
 
188
192
  case "DoWhileStatement":
189
- Evaluate(node.body);
190
- Evaluate(node.test);
193
+ EvaluateChildren(node, ["body", "test"], parent);
191
194
  return;
192
195
 
193
196
  case "ExpressionStatement":
194
197
  case "TSAsExpression":
195
- Evaluate(node.expression);
198
+ EvaluateChildren(node, ["expression"], parent);
196
199
  return;
197
200
 
198
201
  case "ForInStatement":
@@ -209,7 +212,7 @@ function precook(rootAst, {
209
212
  runningContext.LexicalEnvironment = newEnv;
210
213
  }
211
214
 
212
- Evaluate(node.right);
215
+ EvaluateChildren(node, ["right"], parent);
213
216
  runningContext.LexicalEnvironment = oldEnv; // ForIn/OfBodyEvaluation
214
217
 
215
218
  if (lexicalBinding) {
@@ -218,8 +221,7 @@ function precook(rootAst, {
218
221
  runningContext.LexicalEnvironment = iterationEnv;
219
222
  }
220
223
 
221
- Evaluate(node.left);
222
- Evaluate(node.body);
224
+ EvaluateChildren(node, ["left", "body"], parent);
223
225
  runningContext.LexicalEnvironment = oldEnv;
224
226
  return;
225
227
  }
@@ -238,10 +240,7 @@ function precook(rootAst, {
238
240
  runningContext.LexicalEnvironment = loopEnv;
239
241
  }
240
242
 
241
- Evaluate(node.init);
242
- Evaluate(node.test);
243
- Evaluate(node.body);
244
- Evaluate(node.update);
243
+ EvaluateChildren(node, ["init", "test", "body", "update"], parent);
245
244
  runningContext.LexicalEnvironment = oldEnv;
246
245
  return;
247
246
  }
@@ -252,72 +251,65 @@ function precook(rootAst, {
252
251
  const env = getRunningContext().LexicalEnvironment;
253
252
  const fo = OrdinaryFunctionCreate(node, env);
254
253
  env.CreateBinding(fn);
255
- CallFunction(fo);
254
+ CallFunction(fo, parent);
256
255
  return;
257
256
  }
258
257
 
259
258
  case "FunctionExpression":
260
259
  {
261
260
  const closure = InstantiateOrdinaryFunctionExpression(node);
262
- CallFunction(closure);
261
+ CallFunction(closure, parent);
263
262
  return;
264
263
  }
265
264
 
266
265
  case "IfStatement":
267
- Evaluate(node.test);
268
- Evaluate(node.consequent);
269
- Evaluate(node.alternate);
266
+ EvaluateChildren(node, ["test", "consequent", "alternate"], parent);
270
267
  return;
271
268
 
272
269
  case "ReturnStatement":
273
270
  case "ThrowStatement":
274
271
  case "UpdateExpression":
275
- Evaluate(node.argument);
272
+ EvaluateChildren(node, ["argument"], parent);
276
273
  return;
277
274
 
278
275
  case "SwitchCase":
279
- Evaluate(node.test);
280
- Evaluate(node.consequent);
276
+ EvaluateChildren(node, ["test", "consequent"], parent);
281
277
  return;
282
278
 
283
279
  case "SwitchStatement":
284
280
  {
285
- Evaluate(node.discriminant);
281
+ EvaluateChildren(node, ["discriminant"], parent);
286
282
  const runningContext = getRunningContext();
287
283
  const oldEnv = runningContext.LexicalEnvironment;
288
284
  const blockEnv = new _AnalysisContext.AnalysisEnvironment(oldEnv);
289
285
  BlockDeclarationInstantiation(node.cases, blockEnv);
290
286
  runningContext.LexicalEnvironment = blockEnv;
291
- Evaluate(node.cases);
287
+ EvaluateChildren(node, ["cases"], parent);
292
288
  runningContext.LexicalEnvironment = oldEnv;
293
289
  return;
294
290
  }
295
291
 
296
292
  case "TryStatement":
297
- Evaluate(node.block);
298
- Evaluate(node.handler);
299
- Evaluate(node.finalizer);
293
+ EvaluateChildren(node, ["block", "handler", "finalizer"], parent);
300
294
  return;
301
295
 
302
296
  case "VariableDeclaration":
303
- Evaluate(node.declarations);
297
+ EvaluateChildren(node, ["declarations"], parent);
304
298
  return;
305
299
 
306
300
  case "VariableDeclarator":
307
- Evaluate(node.id);
308
- Evaluate(node.init);
301
+ EvaluateChildren(node, ["id", "init"], parent);
309
302
  return;
310
303
 
311
304
  case "WhileStatement":
312
- Evaluate(node.test);
313
- Evaluate(node.body);
305
+ EvaluateChildren(node, ["test", "body"], parent);
314
306
  return;
315
307
  }
316
308
  }
317
309
 
318
- if (visitors && (0, _hasOwnProperty.hasOwnProperty)(visitors, "__UnknownNode")) {
319
- visitors.__UnknownNode(node);
320
- } else {
310
+ const silent = (_hooks$beforeVisitUnk = hooks.beforeVisitUnknown) === null || _hooks$beforeVisitUnk === void 0 ? void 0 : _hooks$beforeVisitUnk.call(hooks, node, parent);
311
+
312
+ if (!silent) {
321
313
  // eslint-disable-next-line no-console
322
314
  console.warn(`Unsupported node type \`${node.type}\``);
323
315
  }
@@ -347,10 +339,16 @@ function precook(rootAst, {
347
339
  BoundNamesInstantiation(declarations, env);
348
340
  }
349
341
 
350
- function CallFunction(closure) {
342
+ function CallFunction(closure, parent) {
351
343
  PrepareOrdinaryCall(closure);
352
- FunctionDeclarationInstantiation(closure);
353
- Evaluate(closure.ECMAScriptCode);
344
+ FunctionDeclarationInstantiation(closure, parent);
345
+ Evaluate(closure.ECMAScriptCode, parent === null || parent === void 0 ? void 0 : parent.concat({
346
+ node: closure.Function,
347
+ key: "body"
348
+ }).concat(closure.Function.body.type === "BlockStatement" ? {
349
+ node: closure.Function.body,
350
+ key: "body"
351
+ } : []));
354
352
  analysisContextStack.pop();
355
353
  }
356
354
 
@@ -362,7 +360,7 @@ function precook(rootAst, {
362
360
  analysisContextStack.push(calleeContext);
363
361
  }
364
362
 
365
- function FunctionDeclarationInstantiation(func) {
363
+ function FunctionDeclarationInstantiation(func, parent) {
366
364
  const calleeContext = getRunningContext();
367
365
  const code = func.ECMAScriptCode;
368
366
  const formals = func.FormalParameters;
@@ -374,7 +372,10 @@ function precook(rootAst, {
374
372
  const varNames = (0, _traverse.collectBoundNames)(varDeclarations);
375
373
  const env = calleeContext.LexicalEnvironment;
376
374
  BoundNamesInstantiation(formals, env);
377
- Evaluate(formals);
375
+ Evaluate(formals, parent === null || parent === void 0 ? void 0 : parent.concat({
376
+ node: func.Function,
377
+ key: "params"
378
+ }));
378
379
  let varEnv;
379
380
 
380
381
  if (!hasParameterExpressions) {
@@ -419,18 +420,16 @@ function precook(rootAst, {
419
420
  return OrdinaryFunctionCreate(functionExpression, funcEnv);
420
421
  }
421
422
 
422
- function OrdinaryFunctionCreate({
423
- params,
424
- body
425
- }, scope) {
423
+ function OrdinaryFunctionCreate(func, scope) {
426
424
  return {
427
- FormalParameters: params,
428
- ECMAScriptCode: body.type === "BlockStatement" ? body.body : body,
425
+ Function: func,
426
+ FormalParameters: func.params,
427
+ ECMAScriptCode: func.body.type === "BlockStatement" ? func.body.body : func.body,
429
428
  Environment: scope
430
429
  };
431
430
  }
432
431
 
433
- Evaluate(rootAst);
432
+ Evaluate(rootAst, withParent ? [] : undefined);
434
433
  return attemptToVisitGlobals;
435
434
  }
436
435
  //# sourceMappingURL=precook.js.map