@@ -3,6 +3,7 @@ import { HighlighterGeneric, createHighlighter } from 'shiki';
3
3
4
4
import { formatJs } from './prettier' ;
5
5
import { Context , Printer } from './printer' ;
6
+ import { map } from 'rxjs' ;
6
7
7
8
let highlighter : HighlighterGeneric < any , any > ;
8
9
@@ -16,67 +17,87 @@ export async function initHightlighter() {
16
17
interface CompileOutput {
17
18
output : string ;
18
19
errors : ng . ParseError [ ] | null ;
20
+ details : any ;
19
21
}
20
22
21
- export function compileTemplate ( templateStr : string ) : CompileOutput {
23
+ export async function compileFormatAndHighlight (
24
+ template : string ,
25
+ ) : Promise < CompileOutput > {
26
+ const { output : unformated , errors, details } = compileTemplate ( template ) ;
27
+
28
+ const formatted = await formatJs ( unformated ) ;
29
+ const highlighted = highlighter . codeToHtml ( formatted , {
30
+ lang : 'javascript' ,
31
+ theme : 'github-dark' ,
32
+ } ) ;
33
+
34
+ return { output : highlighted , errors, details } ;
35
+ }
36
+
37
+ function compileTemplate ( templateStr : string ) : CompileOutput {
22
38
const constantPool = new ng . ConstantPool ( ) ;
23
39
const template = ng . parseTemplate ( templateStr , 'template.html' , {
24
40
preserveWhitespaces : false ,
25
41
} ) ;
26
42
27
43
const CMP_NAME = 'TestCmp' ;
28
44
29
- const out = ng . compileComponentFromMetadata (
30
- {
31
- name : CMP_NAME ,
32
- isStandalone : true ,
33
- selector : 'test-cmp' ,
34
- host : {
35
- attributes : { } ,
36
- listeners : { } ,
37
- properties : { } ,
38
- specialAttributes : { } ,
39
- } ,
40
- inputs : { } ,
41
- outputs : { } ,
42
- lifecycle : {
43
- usesOnChanges : false ,
44
- } ,
45
- hostDirectives : null ,
46
- declarations : [ ] ,
47
- declarationListEmitMode : ng . DeclarationListEmitMode . Direct ,
48
- deps : [ ] ,
49
- animations : null ,
50
- defer : {
51
- dependenciesFn : null ,
52
- mode : ng . DeferBlockDepsEmitMode . PerComponent ,
53
- } ,
54
- i18nUseExternalIds : false ,
55
- interpolation : ng . DEFAULT_INTERPOLATION_CONFIG ,
56
- isSignal : false ,
57
- providers : null ,
58
- queries : [ ] ,
59
- styles : [ ] ,
60
- template,
61
- encapsulation : ng . ViewEncapsulation . Emulated ,
62
- exportAs : null ,
63
- fullInheritance : false ,
64
- changeDetection : null ,
65
- relativeContextFilePath : 'template.html' ,
66
- type : {
67
- value : new ng . WrappedNodeExpr ( CMP_NAME ) ,
68
- type : new ng . WrappedNodeExpr ( CMP_NAME ) ,
69
- } ,
70
- typeArgumentCount : 0 ,
71
- typeSourceSpan : null ! ,
72
- usesInheritance : false ,
73
- viewProviders : null ,
74
- viewQueries : [ ] ,
45
+ const meta : ng . R3ComponentMetadata < any > = {
46
+ name : CMP_NAME ,
47
+ isStandalone : true ,
48
+ selector : 'test-cmp' ,
49
+ host : {
50
+ attributes : { } ,
51
+ listeners : { } ,
52
+ properties : { } ,
53
+ specialAttributes : { } ,
54
+ } ,
55
+ inputs : { } ,
56
+ outputs : { } ,
57
+ lifecycle : {
58
+ usesOnChanges : false ,
75
59
} ,
60
+ hostDirectives : null ,
61
+ declarations : [ ] ,
62
+ declarationListEmitMode : ng . DeclarationListEmitMode . Direct ,
63
+ deps : [ ] ,
64
+ animations : null ,
65
+ defer : {
66
+ dependenciesFn : null ,
67
+ mode : ng . DeferBlockDepsEmitMode . PerComponent ,
68
+ } ,
69
+ i18nUseExternalIds : false ,
70
+ interpolation : ng . DEFAULT_INTERPOLATION_CONFIG ,
71
+ isSignal : false ,
72
+ providers : null ,
73
+ queries : [ ] ,
74
+ styles : [ ] ,
75
+ template,
76
+ encapsulation : ng . ViewEncapsulation . Emulated ,
77
+ exportAs : null ,
78
+ fullInheritance : false ,
79
+ changeDetection : null ,
80
+ relativeContextFilePath : 'template.html' ,
81
+ relativeTemplatePath : 'template.html' ,
82
+ type : {
83
+ value : new ng . WrappedNodeExpr ( CMP_NAME ) ,
84
+ type : new ng . WrappedNodeExpr ( CMP_NAME ) ,
85
+ } ,
86
+ typeArgumentCount : 0 ,
87
+ typeSourceSpan : null ! ,
88
+ usesInheritance : false ,
89
+ viewProviders : null ,
90
+ viewQueries : [ ] ,
91
+ } ;
92
+
93
+ const out = ng . compileComponentFromMetadata (
94
+ meta ,
76
95
constantPool ,
77
96
ng . makeBindingParser ( ng . DEFAULT_INTERPOLATION_CONFIG ) ,
78
97
) ;
79
98
99
+ const details = foo ( meta , new ng . ConstantPool ( ) ) ;
100
+
80
101
const printer = new Printer ( ) ;
81
102
let strExpression = out . expression . visitExpression (
82
103
printer ,
@@ -89,19 +110,86 @@ export function compileTemplate(templateStr: string): CompileOutput {
89
110
strExpression += `\n\n${ strStmt } ` ;
90
111
}
91
112
92
- return { output : strExpression , errors : template . errors } ;
113
+ return { output : strExpression , errors : template . errors , details } ;
93
114
}
94
115
95
- export async function compileFormatAndHighlight (
96
- template : string ,
97
- ) : Promise < CompileOutput > {
98
- const { output : unformated , errors } = compileTemplate ( template ) ;
116
+ function foo ( meta : ng . R3ComponentMetadata < any > , constantPool : ng . ConstantPool ) {
117
+ let allDeferrableDepsFn : ng . ReadVarExpr | null = null ;
99
118
100
- const formatted = await formatJs ( unformated ) ;
101
- const highlighted = highlighter . codeToHtml ( formatted , {
102
- lang : 'javascript' ,
103
- theme : 'github-dark' ,
119
+ const tpl = ng . ingestComponent (
120
+ meta . name ,
121
+ meta . template . nodes ,
122
+ constantPool ,
123
+ meta . relativeContextFilePath ,
124
+ meta . i18nUseExternalIds ,
125
+ meta . defer ,
126
+ allDeferrableDepsFn ,
127
+ meta . relativeTemplatePath ,
128
+ /* enableDebugLocations */ false ,
129
+ ) ;
130
+
131
+ const res : Map < string , any > = new Map ( ) ;
132
+
133
+ res . set ( 'initial state' , {
134
+ phase : 'Initial state' ,
135
+ units : [ ...tpl . units ] . map ( ( unit ) => mapUnit ( unit , tpl , constantPool ) ) ,
136
+ } ) ;
137
+
138
+ for ( const phase of ng . phases ) {
139
+ if (
140
+ phase . kind === ng . CompilationJobKind . Tmpl ||
141
+ phase . kind === ng . CompilationJobKind . Both
142
+ ) {
143
+ // The type of `Phase` above ensures it is impossible to call a phase that doesn't support the
144
+ // job kind.
145
+ phase . fn ( tpl as ng . CompilationJob & ng . ComponentCompilationJob ) ;
146
+ res . set ( phase . fn . name , {
147
+ phase : phase . fn . name ,
148
+ units : [ ...tpl . units ] . map ( ( unit ) => mapUnit ( unit , tpl , constantPool ) ) ,
149
+ } ) ;
150
+ }
151
+ }
152
+
153
+ res . set ( 'Final state' , {
154
+ phase : 'Final state' ,
155
+ units : [ ...tpl . units ] . map ( ( unit ) => mapUnit ( unit , tpl , constantPool ) ) ,
104
156
} ) ;
105
157
106
- return { output : highlighted , errors } ;
158
+ return res ;
159
+ }
160
+
161
+ function mapUnit (
162
+ unit : ng . ViewCompilationUnit ,
163
+ tpl : ng . ComponentCompilationJob ,
164
+ constantPool : ng . ConstantPool ,
165
+ ) {
166
+ return {
167
+ create : [ ...unit . create ] . map ( ( create ) => mapOp ( create , tpl , constantPool ) ) ,
168
+ update : [ ...unit . update ] . map ( ( update ) => mapOp ( update , tpl , constantPool ) ) ,
169
+
170
+ // create: [...unit.create],
171
+ // update: [...unit.update],
172
+ ops : [ ...unit . ops ( ) ] . map ( ( op ) => mapOp ( op , tpl , constantPool ) ) ,
173
+ } ;
174
+ }
175
+
176
+ function mapOp (
177
+ op : ng . CreateOp | ng . UpdateOp ,
178
+ tpl : ng . ComponentCompilationJob ,
179
+ constantPool : ng . ConstantPool ,
180
+ ) {
181
+ const obj = {
182
+ kind : ng . OpKind [ op . kind ] ,
183
+ //fn: null, // ng.emitTemplateFn(tpl, constantPool),
184
+ } ;
185
+
186
+ if ( 'tag' in op ) {
187
+ Object . assign ( obj , { tag : op . tag } ) ;
188
+ }
189
+
190
+ if ( 'sourceSpan' in op ) {
191
+ Object . assign ( obj , { sourceSpan : op . sourceSpan ?. toString ( ) } ) ;
192
+ }
193
+
194
+ return obj ;
107
195
}
0 commit comments