Skip to content

Commit 0dc8ba9

Browse files
authored
feat: replace errors by warnings (#184)
1 parent 7099810 commit 0dc8ba9

File tree

14 files changed

+288
-167
lines changed

14 files changed

+288
-167
lines changed

.eslintignore

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ syntest/
1111
LICENSE*
1212
Dockerfile
1313
NOTICE
14-
commitlint.config.js
1514
link.sh
1615

1716
**/coverage

.husky/commit-msg

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#!/usr/bin/env sh
22
. "$(dirname -- "$0")/_/husky.sh"
33

4-
npx --no -- commitlint --edit
4+
# Do not run pre-commit hooks when running in CI.
5+
[ -n "$CI" ] && exit 0
6+
7+
npx --no -- commitlint --edit --config ./commitlint.config.json

commitlint.config.js

-20
This file was deleted.

commitlint.config.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": ["@commitlint/config-conventional"]
3+
}

libraries/analysis-javascript/lib/target/TargetVisitor.ts

+96-38
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { TargetType } from "@syntest/analysis";
2222
import { AbstractSyntaxTreeVisitor } from "@syntest/ast-visitor-javascript";
2323
import { getLogger, Logger } from "@syntest/logging";
2424

25-
import { unsupportedSyntax } from "../utils/diagnostics";
25+
import { computedProperty, unsupportedSyntax } from "../utils/diagnostics";
2626

2727
import { Export } from "./export/Export";
2828
import {
@@ -37,10 +37,18 @@ import {
3737
SubTarget,
3838
} from "./Target";
3939

40-
const COMPUTED_FLAG = ":computed:";
4140
export class TargetVisitor extends AbstractSyntaxTreeVisitor {
4241
protected static override LOGGER: Logger;
4342

43+
private _logOrFail(message: string): undefined {
44+
if (this.syntaxForgiving) {
45+
TargetVisitor.LOGGER.warn(message);
46+
return undefined;
47+
} else {
48+
throw new Error(message);
49+
}
50+
}
51+
4452
private _exports: Export[];
4553

4654
private _subTargets: SubTarget[];
@@ -70,7 +78,9 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
7078
// e.g. class {}
7179
// e.g. function () {}
7280
// Should not be possible
73-
throw new Error("unknown class declaration");
81+
return this._logOrFail(
82+
unsupportedSyntax(path.type, this._getNodeId(path))
83+
);
7484
}
7585
} else {
7686
// e.g. class x {}
@@ -106,7 +116,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
106116
// e.g. const {x} = function {}
107117
// e.g. const {x} = () => {}
108118
// Should not be possible
109-
throw new Error(
119+
return this._logOrFail(
110120
unsupportedSyntax(path.node.type, this._getNodeId(path))
111121
);
112122
}
@@ -138,13 +148,9 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
138148
// e.g. x[y] = class {}
139149
// e.g. x[y] = function {}
140150
// e.g. x[y] = () => {}
141-
// TODO unsupported cannot get the name unless executing
142-
TargetVisitor.LOGGER.warn(
143-
`This tool does not support computed property assignments. Found one at ${this._getNodeId(
144-
path
145-
)}`
151+
return this._logOrFail(
152+
computedProperty(path.node.type, this._getNodeId(path))
146153
);
147-
return COMPUTED_FLAG;
148154
}
149155
} else if (assigned.property.type === "Identifier") {
150156
// e.g. x.y = class {}
@@ -168,7 +174,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
168174
// e.g. x.? = function {}
169175
// e.g. x.? = () => {}
170176
// Should not be possible
171-
throw new Error(
177+
return this._logOrFail(
172178
unsupportedSyntax(path.node.type, this._getNodeId(path))
173179
);
174180
}
@@ -177,7 +183,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
177183
// e.g. {x} = function {}
178184
// e.g. {x} = () => {}
179185
// Should not be possible
180-
throw new Error(
186+
return this._logOrFail(
181187
unsupportedSyntax(path.node.type, this._getNodeId(path))
182188
);
183189
}
@@ -219,7 +225,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
219225
// e.g. {?: function {}}
220226
// e.g. {?: () => {}}
221227
// Should not be possible
222-
throw new Error(
228+
return this._logOrFail(
223229
unsupportedSyntax(path.node.type, this._getNodeId(path))
224230
);
225231
}
@@ -256,15 +262,19 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
256262
// e.g. c || () => {}
257263
return this._getTargetNameOfExpression(path.parentPath);
258264
}
265+
case "ExportDefaultDeclaration": {
266+
// e.g. export default class {}
267+
// e.g. export default function () {}
268+
// e.g. export default () => {}
269+
return "default";
270+
}
259271
default: {
260272
// e.g. class {}
261273
// e.g. function () {}
262274
// e.g. () => {}
263275
// Should not be possible
264-
throw new Error(
265-
`Unknown parent expression ${parentNode.type} for ${
266-
path.node.type
267-
} in ${this._getNodeId(path)}`
276+
return this._logOrFail(
277+
unsupportedSyntax(parentNode.type, this._getNodeId(path))
268278
);
269279
}
270280
}
@@ -309,6 +319,11 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
309319
// only thing left where these can be found is:
310320
// call(function () {})
311321
const targetName = this._getTargetNameOfExpression(path);
322+
323+
if (!targetName) {
324+
return;
325+
}
326+
312327
const id = this._getNodeId(path);
313328
const export_ = this._getExport(id);
314329

@@ -323,6 +338,11 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
323338
// only thing left where these can be found is:
324339
// call(class {})
325340
const targetName = this._getTargetNameOfExpression(path);
341+
342+
if (!targetName) {
343+
return;
344+
}
345+
326346
const id = this._getNodeId(path);
327347
const export_ = this._getExport(id);
328348

@@ -338,6 +358,10 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
338358
// call(() => {})
339359
const targetName = this._getTargetNameOfExpression(path);
340360

361+
if (!targetName) {
362+
return;
363+
}
364+
341365
// TODO is there a difference if the parent is a variable declarator?
342366

343367
const id = this._getNodeId(path);
@@ -399,6 +423,9 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
399423
}
400424

401425
const targetName = this._getTargetNameOfExpression(right);
426+
if (!targetName) {
427+
return;
428+
}
402429
let isObject = false;
403430
let isMethod = false;
404431
let objectId: string;
@@ -408,11 +435,10 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
408435
const object = left.get("object");
409436
const property = left.get("property");
410437

411-
if (left.get("property").isIdentifier() && left.node.computed) {
412-
TargetVisitor.LOGGER.warn(
413-
"We do not support dynamic computed properties: x[a] = ?"
414-
);
438+
if (property.isIdentifier() && left.node.computed) {
415439
path.skip();
440+
441+
this._logOrFail(computedProperty(left.type, this._getNodeId(path)));
416442
return;
417443
} else if (!left.get("property").isIdentifier() && !left.node.computed) {
418444
// we also dont support a.f() = ?
@@ -637,25 +663,51 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
637663
// loop over object properties
638664
for (const property of path.get("properties")) {
639665
if (property.isObjectMethod()) {
640-
if (property.node.key.type !== "Identifier") {
666+
if (property.node.computed) {
641667
// e.g. class A { ?() {} }
642668
// unsupported
643669
// not possible i think
644-
throw new Error("unknown class method key");
670+
this._logOrFail(
671+
computedProperty(property.type, this._getNodeId(property))
672+
);
673+
continue;
645674
}
646-
const targetName = property.node.key.name;
675+
const key = property.get("key");
676+
if (key.isIdentifier()) {
677+
const targetName = key.node.name;
647678

648-
const id = this._getNodeId(property);
649-
this._extractFromFunction(
650-
property,
651-
id,
652-
id,
653-
targetName,
654-
undefined,
655-
true,
656-
false,
657-
objectId
658-
);
679+
const id = this._getNodeId(property);
680+
this._extractFromFunction(
681+
property,
682+
id,
683+
id,
684+
targetName,
685+
undefined,
686+
true,
687+
false,
688+
objectId
689+
);
690+
} else if (key.isLiteral()) {
691+
const targetName = "value" in key ? String(key.value) : "null";
692+
693+
const id = this._getNodeId(property);
694+
this._extractFromFunction(
695+
property,
696+
id,
697+
id,
698+
targetName,
699+
undefined,
700+
true,
701+
false,
702+
objectId
703+
);
704+
} else {
705+
// not possible i think
706+
this._logOrFail(
707+
unsupportedSyntax(property.node.type, this._getNodeId(property))
708+
);
709+
continue;
710+
}
659711
} else if (property.isObjectProperty()) {
660712
const key = property.get("key");
661713
const value = property.get("value");
@@ -726,7 +778,13 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
726778
// e.g. class A { ?() {} }
727779
// unsupported
728780
// not possible i think
729-
throw new Error("unknown class method key");
781+
this._logOrFail(
782+
unsupportedSyntax(
783+
classBodyAttribute.node.type,
784+
this._getNodeId(classBodyAttribute)
785+
)
786+
);
787+
continue;
730788
}
731789

732790
const targetName = classBodyAttribute.node.key.name;
@@ -781,8 +839,8 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
781839
}
782840
}
783841
} else {
784-
TargetVisitor.LOGGER.warn(
785-
`Unsupported class body attribute: ${classBodyAttribute.node.type}`
842+
return this._logOrFail(
843+
unsupportedSyntax(body.node.type, this._getNodeId(classBodyAttribute))
786844
);
787845
}
788846
}

0 commit comments

Comments
 (0)