@@ -11,6 +11,9 @@ import { InlineAngularResourceLoaderPath } from '../loaders/inline-resource';
1111
1212export const NG_COMPONENT_RESOURCE_QUERY = 'ngResource' ;
1313
14+ /** Whether the current version of TypeScript is after 4.8. */
15+ const IS_TS_48 = isAfterVersion ( 4 , 8 ) ;
16+
1417export function replaceResources (
1518 shouldTransform : ( fileName : string ) => boolean ,
1619 getTypeChecker : ( ) => ts . TypeChecker ,
@@ -24,27 +27,13 @@ export function replaceResources(
2427
2528 const visitNode : ts . Visitor = ( node : ts . Node ) => {
2629 if ( ts . isClassDeclaration ( node ) ) {
27- const decorators = ts . visitNodes ( node . decorators , ( node ) =>
28- ts . isDecorator ( node )
29- ? visitDecorator (
30- nodeFactory ,
31- node ,
32- typeChecker ,
33- resourceImportDeclarations ,
34- moduleKind ,
35- inlineStyleFileExtension ,
36- )
37- : node ,
38- ) ;
39-
40- return nodeFactory . updateClassDeclaration (
30+ return visitClassDeclaration (
31+ nodeFactory ,
32+ typeChecker ,
4133 node ,
42- decorators ,
43- node . modifiers ,
44- node . name ,
45- node . typeParameters ,
46- node . heritageClauses ,
47- node . members ,
34+ resourceImportDeclarations ,
35+ moduleKind ,
36+ inlineStyleFileExtension ,
4837 ) ;
4938 }
5039
@@ -76,6 +65,75 @@ export function replaceResources(
7665 } ;
7766}
7867
68+ /**
69+ * Replaces the resources inside of a `ClassDeclaration`. This is a backwards-compatibility layer
70+ * to support TypeScript versions older than 4.8 where the decorators of a node were in a separate
71+ * array, rather than being part of its `modifiers` array.
72+ *
73+ * TODO: remove this function and use the `NodeFactory` directly once support for TypeScript
74+ * 4.6 and 4.7 has been dropped.
75+ */
76+ function visitClassDeclaration (
77+ nodeFactory : ts . NodeFactory ,
78+ typeChecker : ts . TypeChecker ,
79+ node : ts . ClassDeclaration ,
80+ resourceImportDeclarations : ts . ImportDeclaration [ ] ,
81+ moduleKind : ts . ModuleKind | undefined ,
82+ inlineStyleFileExtension : string | undefined ,
83+ ) : ts . ClassDeclaration {
84+ let decorators : ts . Decorator [ ] | undefined ;
85+ let modifiers : ts . Modifier [ ] | undefined ;
86+
87+ if ( IS_TS_48 ) {
88+ node . modifiers ?. forEach ( ( modifier ) => {
89+ if ( ts . isDecorator ( modifier ) ) {
90+ decorators ??= [ ] ;
91+ decorators . push ( modifier ) ;
92+ } else {
93+ modifiers = modifiers ??= [ ] ;
94+ modifiers . push ( modifier ) ;
95+ }
96+ } ) ;
97+ } else {
98+ decorators = node . decorators as unknown as ts . Decorator [ ] ;
99+ modifiers = node . modifiers as unknown as ts . Modifier [ ] ;
100+ }
101+
102+ if ( ! decorators || decorators . length === 0 ) {
103+ return node ;
104+ }
105+
106+ decorators = decorators . map ( ( current ) =>
107+ visitDecorator (
108+ nodeFactory ,
109+ current ,
110+ typeChecker ,
111+ resourceImportDeclarations ,
112+ moduleKind ,
113+ inlineStyleFileExtension ,
114+ ) ,
115+ ) ;
116+
117+ return IS_TS_48
118+ ? nodeFactory . updateClassDeclaration (
119+ node ,
120+ [ ...decorators , ...( modifiers ?? [ ] ) ] ,
121+ node . name ,
122+ node . typeParameters ,
123+ node . heritageClauses ,
124+ node . members ,
125+ )
126+ : nodeFactory . updateClassDeclaration (
127+ node ,
128+ decorators ,
129+ modifiers ,
130+ node . name ,
131+ node . typeParameters ,
132+ node . heritageClauses ,
133+ node . members ,
134+ ) ;
135+ }
136+
79137function visitDecorator (
80138 nodeFactory : ts . NodeFactory ,
81139 node : ts . Decorator ,
@@ -327,3 +385,16 @@ function getDecoratorOrigin(
327385
328386 return null ;
329387}
388+
389+ /** Checks if the current version of TypeScript is after the specified major/minor versions. */
390+ function isAfterVersion ( targetMajor : number , targetMinor : number ) : boolean {
391+ const [ major , minor ] = ts . versionMajorMinor . split ( '.' ) . map ( ( part ) => parseInt ( part ) ) ;
392+
393+ if ( major < targetMajor ) {
394+ return false ;
395+ } else if ( major > targetMajor ) {
396+ return true ;
397+ } else {
398+ return minor >= targetMinor ;
399+ }
400+ }
0 commit comments