fix(compiler): generate safe access strictNullChecks compatible code (#12800)

fixes #12795
This commit is contained in:
Chuck Jazdzewski 2016-11-11 17:12:17 -08:00 committed by Victor Berchet
parent 52be848f94
commit a965d11cce
3 changed files with 8 additions and 4 deletions

View File

@ -32,7 +32,8 @@ export enum BuiltinTypeName {
String,
Int,
Number,
Function
Function,
Null
}
export class BuiltinType extends Type {
@ -73,7 +74,7 @@ export var INT_TYPE = new BuiltinType(BuiltinTypeName.Int);
export var NUMBER_TYPE = new BuiltinType(BuiltinTypeName.Number);
export var STRING_TYPE = new BuiltinType(BuiltinTypeName.String);
export var FUNCTION_TYPE = new BuiltinType(BuiltinTypeName.Function);
export var NULL_TYPE = new BuiltinType(BuiltinTypeName.Null);
export interface TypeVisitor {
visitBuiltintType(type: BuiltinType, context: any): any;
@ -175,7 +176,8 @@ export abstract class Expression {
}
isBlank(): Expression {
// Note: We use equals by purpose here to compare to null and undefined in JS.
return this.equals(NULL_EXPR);
// We use the typed null to allow strictNullChecks to narrow types.
return this.equals(TYPED_NULL_EXPR);
}
cast(type: Type): Expression { return new CastExpr(this, type); }
toStmt(): Statement { return new ExpressionStatement(this); }
@ -451,6 +453,7 @@ export var SUPER_EXPR = new ReadVarExpr(BuiltinVar.Super);
export var CATCH_ERROR_VAR = new ReadVarExpr(BuiltinVar.CatchError);
export var CATCH_STACK_VAR = new ReadVarExpr(BuiltinVar.CatchStack);
export var NULL_EXPR = new LiteralExpr(null, null);
export var TYPED_NULL_EXPR = new LiteralExpr(null, NULL_TYPE);
//// Statements
export enum StmtModifier {

View File

@ -69,7 +69,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
visitLiteralExpr(ast: o.LiteralExpr, ctx: EmitterVisitorContext): any {
const value = ast.value;
if (isBlank(value)) {
if (isBlank(value) && ast.type != o.NULL_TYPE) {
ctx.print(`(${value} as any)`);
return null;
}

View File

@ -110,6 +110,7 @@ export function main() {
it('should support blank literals', () => {
expect(emitStmt(o.literal(null).toStmt())).toEqual('(null as any);');
expect(emitStmt(o.literal(undefined).toStmt())).toEqual('(undefined as any);');
expect(emitStmt(o.variable('a', null).isBlank().toStmt())).toEqual('(a == null);');
});
it('should support external identifiers', () => {