From e33eb821a82d6c94219231ae18a3dd67ae14e31e Mon Sep 17 00:00:00 2001 From: dcode Date: Mon, 9 Mar 2020 20:40:21 +0100 Subject: [PATCH] Fix failing non-null checks --- src/compiler.ts | 17 ++++++------- src/flow.ts | 63 +++++++++++++++++++++++++++++-------------------- src/parser.ts | 8 ------- 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 33c51601c6..347bc6da66 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -2592,9 +2592,6 @@ export class Compiler extends DiagnosticEmitter { var flow = this.currentFlow; var returnType = flow.returnType; - // Remember that this flow returns - flow.set(FlowFlags.RETURNS | FlowFlags.TERMINATES); - var valueExpression = statement.value; if (valueExpression) { if (returnType == Type.void) { @@ -2633,6 +2630,9 @@ export class Compiler extends DiagnosticEmitter { } flow.freeScopedLocals(); + // Remember that this flow returns + flow.set(FlowFlags.RETURNS | FlowFlags.TERMINATES); + // If the last statement anyway, make it the block's return value if (isLastInBody && expr != 0 && returnType != Type.void) { if (!stmts.length) return expr; @@ -5711,7 +5711,7 @@ export class Compiler extends DiagnosticEmitter { target, expr, // TODO: delay release above if possible? this.currentType, - left, + right, resolver.currentThisExpression, resolver.currentElementExpression, contextualType != Type.void @@ -5850,12 +5850,13 @@ export class Compiler extends DiagnosticEmitter { // compile the value and do the assignment assert(targetType != Type.void); - var valueExpr = this.compileExpression(valueExpression, targetType, Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN); + var valueExpr = this.compileExpression(valueExpression, targetType, Constraints.WILL_RETAIN); + var valueType = this.currentType; return this.makeAssignment( target, - valueExpr, - this.currentType, - expression, + this.convertExpression(valueExpr, valueType, targetType, false, false, valueExpression), + valueType, + valueExpression, thisExpression, elementExpression, contextualType != Type.void diff --git a/src/flow.ts b/src/flow.ts index abd91ab53e..ef330117a1 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -764,35 +764,48 @@ export class Flow { this.flags = newFlags | (this.flags & FlowFlags.UNCHECKED_CONTEXT); - var leftLocalFlags = left.localFlags; - var numLeftLocalFlags = leftLocalFlags.length; - var rightLocalFlags = right.localFlags; - var numRightLocalFlags = rightLocalFlags.length; - var maxLocalFlags = max(numLeftLocalFlags, numRightLocalFlags); - var combinedFlags = new Array(maxLocalFlags); - for (let i = 0; i < maxLocalFlags; ++i) { - let leftFlags = i < numLeftLocalFlags ? leftLocalFlags[i] : 0; - let rightFlags = i < numRightLocalFlags ? rightLocalFlags[i] : 0; - let newFlags = leftFlags & rightFlags & ( - LocalFlags.CONSTANT | - LocalFlags.WRAPPED | - LocalFlags.NONNULL | - LocalFlags.INITIALIZED - ); - if (leftFlags & LocalFlags.RETAINED) { - if (rightFlags & LocalFlags.RETAINED) { - newFlags |= LocalFlags.RETAINED; - } else { + var thisLocalFlags = this.localFlags; + if (leftFlags & FlowFlags.TERMINATES) { + if (!(rightFlags & FlowFlags.TERMINATES)) { + let rightLocalFlags = right.localFlags; + for (let i = 0, k = rightLocalFlags.length; i < k; ++i) { + thisLocalFlags[i] = rightLocalFlags[i]; + } + } + } else if (rightFlags & FlowFlags.TERMINATES) { + let leftLocalFlags = left.localFlags; + for (let i = 0, k = leftLocalFlags.length; i < k; ++i) { + thisLocalFlags[i] = leftLocalFlags[i]; + } + } else { + let leftLocalFlags = left.localFlags; + let numLeftLocalFlags = leftLocalFlags.length; + let rightLocalFlags = right.localFlags; + let numRightLocalFlags = rightLocalFlags.length; + let maxLocalFlags = max(numLeftLocalFlags, numRightLocalFlags); + for (let i = 0; i < maxLocalFlags; ++i) { + let leftFlags = i < numLeftLocalFlags ? leftLocalFlags[i] : 0; + let rightFlags = i < numRightLocalFlags ? rightLocalFlags[i] : 0; + let newFlags = leftFlags & rightFlags & ( + LocalFlags.CONSTANT | + LocalFlags.WRAPPED | + LocalFlags.NONNULL | + LocalFlags.INITIALIZED + ); + if (leftFlags & LocalFlags.RETAINED) { + if (rightFlags & LocalFlags.RETAINED) { + newFlags |= LocalFlags.RETAINED; + } else { + newFlags |= LocalFlags.CONDITIONALLY_RETAINED; + } + } else if (rightFlags & LocalFlags.RETAINED) { newFlags |= LocalFlags.CONDITIONALLY_RETAINED; + } else { + newFlags |= (leftFlags | rightFlags) & LocalFlags.CONDITIONALLY_RETAINED; } - } else if (rightFlags & LocalFlags.RETAINED) { - newFlags |= LocalFlags.CONDITIONALLY_RETAINED; - } else { - newFlags |= (leftFlags | rightFlags) & LocalFlags.CONDITIONALLY_RETAINED; + thisLocalFlags[i] = newFlags; } - combinedFlags[i] = newFlags; } - this.localFlags = combinedFlags; } /** Tests if the specified flows have differing local states. */ diff --git a/src/parser.ts b/src/parser.ts index 3e9bf3b498..ad0f8ac617 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1296,7 +1296,6 @@ export class Parser extends DiagnosticEmitter { if (!type) return null; } else { type = Node.createOmittedType(tn.range(tn.pos)); - type = type!; // FIXME: WHY? } let initializer: Expression | null = null; if (tn.skip(Token.EQUALS)) { @@ -1423,7 +1422,6 @@ export class Parser extends DiagnosticEmitter { returnType = Node.createOmittedType( tn.range(tn.pos) ); - returnType = returnType!; // FIXME: WHY? if (!isSetter) { this.error( DiagnosticCode.Type_expected, @@ -1532,7 +1530,6 @@ export class Parser extends DiagnosticEmitter { if (!returnType) return null; } else { returnType = Node.createOmittedType(tn.range(tn.pos)); - returnType = returnType!; // FIXME: WHY? } if (arrowKind) { @@ -2082,7 +2079,6 @@ export class Parser extends DiagnosticEmitter { if (!returnType) return null; } else { returnType = Node.createOmittedType(tn.range(tn.pos)); - returnType = returnType!; // FIXME: WHY? if (!isSetter && name.kind != NodeKind.CONSTRUCTOR) { this.error( DiagnosticCode.Type_expected, @@ -3543,7 +3539,6 @@ export class Parser extends DiagnosticEmitter { return null; } inner = Node.createParenthesizedExpression(inner, tn.range(startPos, tn.pos)); - inner = inner!; // FIXME: WHY? return this.maybeParseCallExpression(tn, inner); } // ArrayLiteralExpression @@ -3833,7 +3828,6 @@ export class Parser extends DiagnosticEmitter { null, tn.range(startPos, tn.pos) ); - expr = expr!; // FIXME: WHY? expr = this.maybeParseCallExpression(tn, expr); break; } @@ -3864,7 +3858,6 @@ export class Parser extends DiagnosticEmitter { next, tn.range(startPos, tn.pos) ); - expr = expr!; // FIXME: WHY? expr = this.maybeParseCallExpression(tn, expr); break; } @@ -3932,7 +3925,6 @@ export class Parser extends DiagnosticEmitter { next, tn.range(startPos, tn.pos) ); - expr = expr!; // FIXME: WHY? } else { let next = this.parseExpression(tn, nextPrecedence + 1); if (!next) return null;