@@ -22,7 +22,7 @@ import { TargetType } from "@syntest/analysis";
22
22
import { AbstractSyntaxTreeVisitor } from "@syntest/ast-visitor-javascript" ;
23
23
import { getLogger , Logger } from "@syntest/logging" ;
24
24
25
- import { unsupportedSyntax } from "../utils/diagnostics" ;
25
+ import { computedProperty , unsupportedSyntax } from "../utils/diagnostics" ;
26
26
27
27
import { Export } from "./export/Export" ;
28
28
import {
@@ -37,10 +37,18 @@ import {
37
37
SubTarget ,
38
38
} from "./Target" ;
39
39
40
- const COMPUTED_FLAG = ":computed:" ;
41
40
export class TargetVisitor extends AbstractSyntaxTreeVisitor {
42
41
protected static override LOGGER : Logger ;
43
42
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
+
44
52
private _exports : Export [ ] ;
45
53
46
54
private _subTargets : SubTarget [ ] ;
@@ -70,7 +78,9 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
70
78
// e.g. class {}
71
79
// e.g. function () {}
72
80
// Should not be possible
73
- throw new Error ( "unknown class declaration" ) ;
81
+ return this . _logOrFail (
82
+ unsupportedSyntax ( path . type , this . _getNodeId ( path ) )
83
+ ) ;
74
84
}
75
85
} else {
76
86
// e.g. class x {}
@@ -106,7 +116,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
106
116
// e.g. const {x} = function {}
107
117
// e.g. const {x} = () => {}
108
118
// Should not be possible
109
- throw new Error (
119
+ return this . _logOrFail (
110
120
unsupportedSyntax ( path . node . type , this . _getNodeId ( path ) )
111
121
) ;
112
122
}
@@ -138,13 +148,9 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
138
148
// e.g. x[y] = class {}
139
149
// e.g. x[y] = function {}
140
150
// 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 ) )
146
153
) ;
147
- return COMPUTED_FLAG ;
148
154
}
149
155
} else if ( assigned . property . type === "Identifier" ) {
150
156
// e.g. x.y = class {}
@@ -168,7 +174,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
168
174
// e.g. x.? = function {}
169
175
// e.g. x.? = () => {}
170
176
// Should not be possible
171
- throw new Error (
177
+ return this . _logOrFail (
172
178
unsupportedSyntax ( path . node . type , this . _getNodeId ( path ) )
173
179
) ;
174
180
}
@@ -177,7 +183,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
177
183
// e.g. {x} = function {}
178
184
// e.g. {x} = () => {}
179
185
// Should not be possible
180
- throw new Error (
186
+ return this . _logOrFail (
181
187
unsupportedSyntax ( path . node . type , this . _getNodeId ( path ) )
182
188
) ;
183
189
}
@@ -219,7 +225,7 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
219
225
// e.g. {?: function {}}
220
226
// e.g. {?: () => {}}
221
227
// Should not be possible
222
- throw new Error (
228
+ return this . _logOrFail (
223
229
unsupportedSyntax ( path . node . type , this . _getNodeId ( path ) )
224
230
) ;
225
231
}
@@ -256,15 +262,19 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
256
262
// e.g. c || () => {}
257
263
return this . _getTargetNameOfExpression ( path . parentPath ) ;
258
264
}
265
+ case "ExportDefaultDeclaration" : {
266
+ // e.g. export default class {}
267
+ // e.g. export default function () {}
268
+ // e.g. export default () => {}
269
+ return "default" ;
270
+ }
259
271
default : {
260
272
// e.g. class {}
261
273
// e.g. function () {}
262
274
// e.g. () => {}
263
275
// 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 ) )
268
278
) ;
269
279
}
270
280
}
@@ -309,6 +319,11 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
309
319
// only thing left where these can be found is:
310
320
// call(function () {})
311
321
const targetName = this . _getTargetNameOfExpression ( path ) ;
322
+
323
+ if ( ! targetName ) {
324
+ return ;
325
+ }
326
+
312
327
const id = this . _getNodeId ( path ) ;
313
328
const export_ = this . _getExport ( id ) ;
314
329
@@ -323,6 +338,11 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
323
338
// only thing left where these can be found is:
324
339
// call(class {})
325
340
const targetName = this . _getTargetNameOfExpression ( path ) ;
341
+
342
+ if ( ! targetName ) {
343
+ return ;
344
+ }
345
+
326
346
const id = this . _getNodeId ( path ) ;
327
347
const export_ = this . _getExport ( id ) ;
328
348
@@ -338,6 +358,10 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
338
358
// call(() => {})
339
359
const targetName = this . _getTargetNameOfExpression ( path ) ;
340
360
361
+ if ( ! targetName ) {
362
+ return ;
363
+ }
364
+
341
365
// TODO is there a difference if the parent is a variable declarator?
342
366
343
367
const id = this . _getNodeId ( path ) ;
@@ -399,6 +423,9 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
399
423
}
400
424
401
425
const targetName = this . _getTargetNameOfExpression ( right ) ;
426
+ if ( ! targetName ) {
427
+ return ;
428
+ }
402
429
let isObject = false ;
403
430
let isMethod = false ;
404
431
let objectId : string ;
@@ -408,11 +435,10 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
408
435
const object = left . get ( "object" ) ;
409
436
const property = left . get ( "property" ) ;
410
437
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 ) {
415
439
path . skip ( ) ;
440
+
441
+ this . _logOrFail ( computedProperty ( left . type , this . _getNodeId ( path ) ) ) ;
416
442
return ;
417
443
} else if ( ! left . get ( "property" ) . isIdentifier ( ) && ! left . node . computed ) {
418
444
// we also dont support a.f() = ?
@@ -637,25 +663,51 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
637
663
// loop over object properties
638
664
for ( const property of path . get ( "properties" ) ) {
639
665
if ( property . isObjectMethod ( ) ) {
640
- if ( property . node . key . type !== "Identifier" ) {
666
+ if ( property . node . computed ) {
641
667
// e.g. class A { ?() {} }
642
668
// unsupported
643
669
// 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 ;
645
674
}
646
- const targetName = property . node . key . name ;
675
+ const key = property . get ( "key" ) ;
676
+ if ( key . isIdentifier ( ) ) {
677
+ const targetName = key . node . name ;
647
678
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
+ }
659
711
} else if ( property . isObjectProperty ( ) ) {
660
712
const key = property . get ( "key" ) ;
661
713
const value = property . get ( "value" ) ;
@@ -726,7 +778,13 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
726
778
// e.g. class A { ?() {} }
727
779
// unsupported
728
780
// 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 ;
730
788
}
731
789
732
790
const targetName = classBodyAttribute . node . key . name ;
@@ -781,8 +839,8 @@ export class TargetVisitor extends AbstractSyntaxTreeVisitor {
781
839
}
782
840
}
783
841
} 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 ) )
786
844
) ;
787
845
}
788
846
}
0 commit comments