@@ -16,6 +16,7 @@ import { nonStringFields } from './CubeValidator';
1616import { CubeDictionary } from './CubeDictionary' ;
1717import { ErrorReporter } from './ErrorReporter' ;
1818import { camelizeCube } from './utils' ;
19+ import { perfTracker } from './PerfTracker' ;
1920
2021type EscapeStateStack = {
2122 inFormattedStr ?: boolean ;
@@ -24,6 +25,8 @@ type EscapeStateStack = {
2425 depth ?: number ;
2526} ;
2627
28+ const PY_TEMPLATE_SYNTAX = / \{ .* } / ms;
29+
2730export class YamlCompiler {
2831 public dataSchemaCompiler : DataSchemaCompiler | null = null ;
2932
@@ -90,7 +93,9 @@ export class YamlCompiler {
9093 for ( const key of Object . keys ( yamlObj ) ) {
9194 if ( key === 'cubes' ) {
9295 ( yamlObj . cubes || [ ] ) . forEach ( ( { name, ...cube } ) => {
96+ const transpileAndPrepareJsFileTimer = perfTracker . start ( 'yaml-transpileAndPrepareJsFile' ) ;
9397 const transpiledFile = this . transpileAndPrepareJsFile ( file , 'cube' , { name, ...cube } , errorsReport ) ;
98+ transpileAndPrepareJsFileTimer . end ( ) ;
9499 this . dataSchemaCompiler ?. compileJsFile ( transpiledFile , errorsReport ) ;
95100 } ) ;
96101 } else if ( key === 'views' ) {
@@ -132,7 +137,10 @@ export class YamlCompiler {
132137
133138 cubeObj . hierarchies = this . yamlArrayToObj ( cubeObj . hierarchies || [ ] , 'hierarchies' , errorsReport ) ;
134139
135- return this . transpileYaml ( cubeObj , [ ] , cubeObj . name , errorsReport ) ;
140+ const transpileYamlTimer = perfTracker . start ( 'transpileYaml' ) ;
141+ const res = this . transpileYaml ( cubeObj , [ ] , cubeObj . name , errorsReport ) ;
142+ transpileYamlTimer . end ( ) ;
143+ return res ;
136144 }
137145
138146 private transpileYaml ( obj , propertyPath , cubeName , errorsReport : ErrorReporter ) {
@@ -146,11 +154,17 @@ export class YamlCompiler {
146154 return this . parsePythonIntoArrowFunction ( obj , cubeName , obj , errorsReport ) ;
147155 } else if ( Array . isArray ( obj ) ) {
148156 const resultAst = t . program ( [ t . expressionStatement ( t . arrayExpression ( obj . map ( code => {
149- let ast : t . Program | t . NullLiteral | t . BooleanLiteral | t . NumericLiteral | null = null ;
157+ let ast : t . Program | t . NullLiteral | t . BooleanLiteral | t . NumericLiteral | t . StringLiteral | null = null ;
150158 // Special case for accessPolicy.rowLevel.filter.values and other values-like fields
151159 if ( propertyPath [ propertyPath . length - 1 ] === 'values' ) {
152160 if ( typeof code === 'string' ) {
153- ast = this . parsePythonAndTranspileToJs ( `f"${ this . escapeDoubleQuotes ( code ) } "` , errorsReport ) ;
161+ if ( code . match ( PY_TEMPLATE_SYNTAX ) ) {
162+ const parsePythonAndTranspileToJsTimer184 = perfTracker . start ( 'parsePythonAndTranspileToJs call 184' ) ;
163+ ast = this . parsePythonAndTranspileToJs ( `f"${ this . escapeDoubleQuotes ( code ) } "` , errorsReport ) ;
164+ parsePythonAndTranspileToJsTimer184 . end ( ) ;
165+ } else {
166+ ast = t . stringLiteral ( code ) ;
167+ }
154168 } else if ( typeof code === 'boolean' ) {
155169 ast = t . booleanLiteral ( code ) ;
156170 } else if ( typeof code === 'number' ) {
@@ -162,7 +176,9 @@ export class YamlCompiler {
162176 }
163177 }
164178 if ( ast === null ) {
179+ const parsePythonAndTranspileToJsTimer201 = perfTracker . start ( 'parsePythonAndTranspileToJs call 201' ) ;
165180 ast = this . parsePythonAndTranspileToJs ( code , errorsReport ) ;
181+ parsePythonAndTranspileToJsTimer201 . end ( ) ;
166182 }
167183 return this . extractProgramBodyIfNeeded ( ast ) ;
168184 } ) . filter ( ast => ! ! ast ) ) ) ] ) ;
@@ -173,7 +189,9 @@ export class YamlCompiler {
173189 }
174190
175191 if ( propertyPath [ propertyPath . length - 1 ] === 'extends' ) {
192+ const parsePythonAndTranspileToJsTimer214 = perfTracker . start ( 'parsePythonAndTranspileToJs call 214' ) ;
176193 const ast = this . parsePythonAndTranspileToJs ( obj , errorsReport ) ;
194+ parsePythonAndTranspileToJsTimer214 . end ( ) ;
177195 return this . astIntoArrowFunction ( ast , obj , cubeName , name => this . cubeDictionary . resolveCube ( name ) ) ;
178196 } else if ( typeof obj === 'string' ) {
179197 let code = obj ;
@@ -182,7 +200,9 @@ export class YamlCompiler {
182200 code = `f"${ this . escapeDoubleQuotes ( obj ) } "` ;
183201 }
184202
203+ const parsePythonAndTranspileToJsTimer225 = perfTracker . start ( 'parsePythonAndTranspileToJs call 225' ) ;
185204 const ast = this . parsePythonAndTranspileToJs ( code , errorsReport ) ;
205+ parsePythonAndTranspileToJsTimer225 . end ( ) ;
186206 return this . extractProgramBodyIfNeeded ( ast ) ;
187207 } else if ( typeof obj === 'boolean' ) {
188208 return t . booleanLiteral ( obj ) ;
@@ -260,7 +280,9 @@ export class YamlCompiler {
260280 }
261281
262282 private parsePythonIntoArrowFunction ( codeString : string , cubeName , originalObj , errorsReport : ErrorReporter ) {
283+ const parsePythonAndTranspileToJsTimer301 = perfTracker . start ( 'parsePythonAndTranspileToJs call 301' ) ;
263284 const ast = this . parsePythonAndTranspileToJs ( codeString , errorsReport ) ;
285+ parsePythonAndTranspileToJsTimer301 . end ( ) ;
264286 return this . astIntoArrowFunction ( ast as any , codeString , cubeName ) ;
265287 }
266288
@@ -270,8 +292,12 @@ export class YamlCompiler {
270292 }
271293
272294 try {
295+ const parsePythonAndTranspileToJsTimer = perfTracker . start ( 'PythonParser->transpileToJs()' ) ;
296+
273297 const pythonParser = new PythonParser ( codeString ) ;
274- return pythonParser . transpileToJs ( ) ;
298+ const res = pythonParser . transpileToJs ( ) ;
299+ parsePythonAndTranspileToJsTimer . end ( ) ;
300+ return res ;
275301 } catch ( e : any ) {
276302 errorsReport . error ( `Can't parse python expression. Most likely this type of syntax isn't supported yet: ${ e . message || e } ` ) ;
277303 }
@@ -280,6 +306,7 @@ export class YamlCompiler {
280306 }
281307
282308 private astIntoArrowFunction ( input : t . Program | t . NullLiteral , codeString : string , cubeName , resolveSymbol ?: ( string ) => any) {
309+ const astIntoArrowFunctionTimer = perfTracker . start ( 'astIntoArrowFunction' ) ;
283310 const initialJs = babelGenerator ( input , { } , codeString ) . code ;
284311
285312 // Re-parse generated JS to set all necessary parent paths
@@ -304,6 +331,7 @@ export class YamlCompiler {
304331 babelTraverse ( ast , traverseObj ) ;
305332
306333 const body : any = ast . program . body [ 0 ] ;
334+ astIntoArrowFunctionTimer . end ( ) ;
307335 return body ?. expression ;
308336 }
309337
0 commit comments