fix: ensure strict mode when evaluating in JIT (#30122)
PR Close #30122
This commit is contained in:
parent
728db88280
commit
452f121486
@ -31,6 +31,13 @@ export class JitEvaluator {
|
|||||||
createSourceMaps: boolean): {[key: string]: any} {
|
createSourceMaps: boolean): {[key: string]: any} {
|
||||||
const converter = new JitEmitterVisitor(reflector);
|
const converter = new JitEmitterVisitor(reflector);
|
||||||
const ctx = EmitterVisitorContext.createRoot();
|
const ctx = EmitterVisitorContext.createRoot();
|
||||||
|
// Ensure generated code is in strict mode
|
||||||
|
if (statements.length > 0 && !isUseStrictStatement(statements[0])) {
|
||||||
|
statements = [
|
||||||
|
o.literal('use strict').toStmt(),
|
||||||
|
...statements,
|
||||||
|
];
|
||||||
|
}
|
||||||
converter.visitAllStatements(statements, ctx);
|
converter.visitAllStatements(statements, ctx);
|
||||||
converter.createReturnStmt(ctx);
|
converter.createReturnStmt(ctx);
|
||||||
return this.evaluateCode(sourceUrl, ctx, converter.getArgs(), createSourceMaps);
|
return this.evaluateCode(sourceUrl, ctx, converter.getArgs(), createSourceMaps);
|
||||||
@ -150,3 +157,8 @@ export class JitEmitterVisitor extends AbstractJsEmitterVisitor {
|
|||||||
ctx.print(ast, this._evalArgNames[id]);
|
ctx.print(ast, this._evalArgNames[id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function isUseStrictStatement(statement: o.Statement): boolean {
|
||||||
|
return statement.isEquivalent(o.literal('use strict').toStmt());
|
||||||
|
}
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
import {EmitterVisitorContext} from '@angular/compiler/src/output/abstract_emitter';
|
import {EmitterVisitorContext} from '@angular/compiler/src/output/abstract_emitter';
|
||||||
import * as o from '@angular/compiler/src/output/output_ast';
|
import * as o from '@angular/compiler/src/output/output_ast';
|
||||||
import {JitEmitterVisitor} from '@angular/compiler/src/output/output_jit';
|
import {JitEmitterVisitor, JitEvaluator} from '@angular/compiler/src/output/output_jit';
|
||||||
|
import {R3JitReflector} from '@angular/compiler/src/render3/r3_jit';
|
||||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||||
|
|
||||||
const anotherModuleUrl = 'somePackage/someOtherPath';
|
const anotherModuleUrl = 'somePackage/someOtherPath';
|
||||||
@ -32,5 +33,31 @@ const anotherModuleUrl = 'somePackage/someOtherPath';
|
|||||||
expect(Object.keys(args).length).toBe(20);
|
expect(Object.keys(args).length).toBe(20);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should use strict mode', () => {
|
||||||
|
const evaluator = new JitEvaluator();
|
||||||
|
expect(() => {
|
||||||
|
evaluator.evaluateStatements(
|
||||||
|
'http://angular.io/something.ts',
|
||||||
|
[
|
||||||
|
// Set an undeclared variable
|
||||||
|
// foo = "bar";
|
||||||
|
o.variable('foo').equals(o.literal('bar')).toStmt(),
|
||||||
|
],
|
||||||
|
new R3JitReflector({}), false);
|
||||||
|
}).toThrowError();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not add more than one strict mode statement if there is already one present', () => {
|
||||||
|
const converter = new JitEmitterVisitor(new JitReflector());
|
||||||
|
const ctx = EmitterVisitorContext.createRoot();
|
||||||
|
converter.visitAllStatements(
|
||||||
|
[
|
||||||
|
o.literal('use strict').toStmt(),
|
||||||
|
],
|
||||||
|
ctx);
|
||||||
|
const matches = ctx.toSource().match(/'use strict';/g) !;
|
||||||
|
expect(matches.length).toBe(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user