refactor(compiler): ensure compatibility with typescript strict flag (#30993)

As part of FW-1265, the `@angular/compiler` package is made compatible
with the TypeScript `--strict` flag. This already unveiled a few bugs,
so the strictness flag seems to help with increasing the overall code health.

Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
This commit is contained in:
Paul Gschwendtner 2019-06-14 09:28:04 +02:00 committed by Miško Hevery
parent 2200884e55
commit 012b535147
11 changed files with 28 additions and 25 deletions

View File

@ -132,7 +132,7 @@ export class StaticReflector implements CompileReflector {
public tryAnnotations(type: StaticSymbol): any[] {
const originalRecorder = this.errorRecorder;
this.errorRecorder = (error: any, fileName: string) => {};
this.errorRecorder = (error: any, fileName?: string) => {};
try {
return this.annotations(type);
} finally {
@ -429,7 +429,7 @@ export class StaticReflector implements CompileReflector {
*/
private trySimplify(context: StaticSymbol, value: any): any {
const originalRecorder = this.errorRecorder;
this.errorRecorder = (error: any, fileName: string) => {};
this.errorRecorder = (error: any, fileName?: string) => {};
const result = this.simplify(context, value);
this.errorRecorder = originalRecorder;
return result;

View File

@ -273,7 +273,7 @@ class KeyVisitor implements o.ExpressionVisitor {
visitCommaExpr = invalid;
}
function invalid<T>(arg: o.Expression | o.Statement): never {
function invalid<T>(this: o.ExpressionVisitor, arg: o.Expression | o.Statement): never {
throw new Error(
`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
}

View File

@ -210,7 +210,7 @@ const USE_FACTORY = Object.keys({useFactory: null})[0];
const USE_VALUE = Object.keys({useValue: null})[0];
const USE_EXISTING = Object.keys({useExisting: null})[0];
const wrapReference = function(value: Type): R3Reference {
const wrapReference = function(value: any): R3Reference {
const wrapped = new WrappedNodeExpr(value);
return {value: wrapped, type: wrapped};
};

View File

@ -83,7 +83,7 @@ export class CompileMetadataResolver {
private _createProxyClass(baseType: any, name: string): cpl.ProxyClass {
let delegate: any = null;
const proxyClass: cpl.ProxyClass = <any>function() {
const proxyClass: cpl.ProxyClass = <any>function(this: unknown) {
if (!delegate) {
throw new Error(
`Illegal state: Class ${name} for type ${stringify(baseType)} is not compiled yet!`);

View File

@ -112,7 +112,7 @@ export class RecursiveVisitor implements Visitor {
if (children) results.push(visitAll(t, children, context));
}
cb(visit);
return [].concat.apply([], results);
return Array.prototype.concat.apply([], results);
}
}

View File

@ -38,8 +38,8 @@ class _ExecutionContext {
exports: string[] = [];
constructor(
public parent: _ExecutionContext|null, public instance: any, public className: string|null,
public vars: Map<string, any>) {}
public parent: _ExecutionContext|null, public instance: Object|null,
public className: string|null, public vars: Map<string, any>) {}
createChildWihtLocalVars(): _ExecutionContext {
return new _ExecutionContext(this, this.instance, this.className, new Map<string, any>());
@ -79,9 +79,9 @@ function createDynamicClass(
const ctorParamNames = _classStmt.constructorMethod.params.map(param => param.name);
// Note: use `function` instead of arrow function to capture `this`
const ctor = function(...args: any[]) {
const ctor = function(this: Object, ...args: any[]) {
const instanceCtx = new _ExecutionContext(_ctx, this, _classStmt.name, _ctx.vars);
_classStmt.fields.forEach((field) => { this[field.name] = undefined; });
_classStmt.fields.forEach((field) => { (this as any)[field.name] = undefined; });
_executeFunctionStatements(
ctorParamNames, args, _classStmt.constructorMethod.body, instanceCtx, _visitor);
};
@ -125,7 +125,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
if (ast.builtin != null) {
switch (ast.builtin) {
case o.BuiltinVar.Super:
return ctx.instance.__proto__;
return Object.getPrototypeOf(ctx.instance);
case o.BuiltinVar.This:
return ctx.instance;
case o.BuiltinVar.CatchError:
@ -188,7 +188,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
const args = this.visitAllExpressions(stmt.args, ctx);
const fnExpr = stmt.fn;
if (fnExpr instanceof o.ReadVarExpr && fnExpr.builtin === o.BuiltinVar.Super) {
ctx.instance.constructor.prototype.constructor.apply(ctx.instance, args);
ctx.instance !.constructor.prototype.constructor.apply(ctx.instance, args);
return null;
} else {
const fn = stmt.fn.visitExpression(this, ctx);

View File

@ -15,7 +15,7 @@ import {ParseTreeResult} from '../../../ml_parser/parser';
import {I18N_ATTR, I18N_ATTR_PREFIX, I18nMeta, hasI18nAttrs, icuFromI18nMessage, metaFromI18nMessage, parseI18nMeta} from './util';
function setI18nRefs(html: html.Node & {i18n: i18n.AST}, i18n: i18n.Node) {
function setI18nRefs(html: html.Node & {i18n?: i18n.AST}, i18n: i18n.Node) {
html.i18n = i18n;
}

View File

@ -165,7 +165,8 @@ export function assembleBoundTextPlaceholders(
meta instanceof i18n.Message ? meta.nodes.find(node => node instanceof i18n.Container) : meta;
if (node) {
(node as i18n.Container)
.children.filter((child: i18n.Node) => child instanceof i18n.Placeholder)
.children
.filter((child: i18n.Node): child is i18n.Placeholder => child instanceof i18n.Placeholder)
.forEach((child: i18n.Placeholder, idx: number) => {
const content = wrapI18nPlaceholder(startIdx + idx, contextId);
updatePlaceholderMap(placeholders, child.name, content);

View File

@ -177,7 +177,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
this._valueConverter = new ValueConverter(
constantPool, () => this.allocateDataSlot(),
(numSlots: number) => this.allocatePureFunctionSlots(numSlots),
(name, localName, slot, value: o.ReadVarExpr) => {
(name, localName, slot, value: o.Expression) => {
const pipeType = pipeTypeByName.get(name);
if (pipeType) {
this.pipes.add(pipeType);
@ -1517,7 +1517,7 @@ const SHARED_CONTEXT_KEY = '$$shared_ctx$$';
* declaration should always come before the local ref declaration.
*/
type BindingData = {
retrievalLevel: number; lhs: o.ReadVarExpr; declareLocalCallback?: DeclareLocalVarCallback;
retrievalLevel: number; lhs: o.Expression; declareLocalCallback?: DeclareLocalVarCallback;
declare: boolean;
priority: number;
localRef: boolean;
@ -1593,7 +1593,7 @@ export class BindingScope implements LocalResolver {
* @param declareLocalCallback The callback to invoke when declaring this local var
* @param localRef Whether or not this is a local ref
*/
set(retrievalLevel: number, name: string, lhs: o.ReadVarExpr,
set(retrievalLevel: number, name: string, lhs: o.Expression,
priority: number = DeclarationPriority.DEFAULT,
declareLocalCallback?: DeclareLocalVarCallback, localRef?: true): BindingScope {
if (this.map.has(name)) {
@ -1644,12 +1644,14 @@ export class BindingScope implements LocalResolver {
if (!this.map.has(bindingKey)) {
this.generateSharedContextVar(retrievalLevel);
}
return this.map.get(bindingKey) !.lhs;
// Shared context variables are always generated as "ReadVarExpr".
return this.map.get(bindingKey) !.lhs as o.ReadVarExpr;
}
getSharedContextName(retrievalLevel: number): o.ReadVarExpr|null {
const sharedCtxObj = this.map.get(SHARED_CONTEXT_KEY + retrievalLevel);
return sharedCtxObj && sharedCtxObj.declare ? sharedCtxObj.lhs : null;
// Shared context variables are always generated as "ReadVarExpr".
return sharedCtxObj && sharedCtxObj.declare ? sharedCtxObj.lhs as o.ReadVarExpr : null;
}
maybeGenerateSharedContextVar(value: BindingData) {

View File

@ -62,14 +62,14 @@ export function temporaryAllocator(statements: o.Statement[], name: string): ()
}
export function unsupported(feature: string): never {
export function unsupported(this: void|Function, feature: string): never {
if (this) {
throw new Error(`Builder ${this.constructor.name} doesn't support ${feature} yet`);
}
throw new Error(`Feature ${feature} is not supported yet`);
}
export function invalid<T>(arg: o.Expression | o.Statement | t.Node): never {
export function invalid<T>(this: t.Visitor, arg: o.Expression | o.Statement | t.Node): never {
throw new Error(
`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
}

View File

@ -359,7 +359,7 @@ export class RecursiveTemplateAstVisitor extends NullTemplateVisitor implements
if (children && children.length) results.push(templateVisitAll(t, children, context));
}
cb(visit);
return [].concat.apply([], results);
return Array.prototype.concat.apply([], results);
}
}