fix(compiler): Update types for TypeScript nullability support

This commit is contained in:
Miško Hevery
2017-03-24 09:59:58 -07:00
committed by Hans
parent d8b73e4223
commit 09d9f5fe54
118 changed files with 2086 additions and 1859 deletions

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileProviderMetadata, componentFactoryName, createHostComponentMeta, flatten, identifierName, sourceUrl, templateSourceUrl} from '../compile_metadata';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileProviderMetadata, CompileTypeSummary, componentFactoryName, createHostComponentMeta, flatten, identifierName, sourceUrl, templateSourceUrl} from '../compile_metadata';
import {CompilerConfig} from '../config';
import {Identifiers, createIdentifier, createIdentifierToken} from '../identifiers';
import {CompileMetadataResolver} from '../metadata_resolver';
@ -32,8 +32,8 @@ export class AotCompiler {
private _metadataResolver: CompileMetadataResolver, private _templateParser: TemplateParser,
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
private _ngModuleCompiler: NgModuleCompiler, private _outputEmitter: OutputEmitter,
private _summaryResolver: SummaryResolver<StaticSymbol>, private _localeId: string,
private _translationFormat: string, private _genFilePreamble: string,
private _summaryResolver: SummaryResolver<StaticSymbol>, private _localeId: string|null,
private _translationFormat: string|null, private _genFilePreamble: string|null,
private _symbolResolver: StaticSymbolResolver) {}
clearCache() { this._metadataResolver.clearCache(); }
@ -113,11 +113,11 @@ export class AotCompiler {
targetExportedVars: string[]): GeneratedFile {
const symbolSummaries = this._symbolResolver.getSymbolsOf(srcFileUrl)
.map(symbol => this._symbolResolver.resolveSymbol(symbol));
const typeSummaries = [
...ngModules.map(ref => this._metadataResolver.getNgModuleSummary(ref)),
...directives.map(ref => this._metadataResolver.getDirectiveSummary(ref)),
...pipes.map(ref => this._metadataResolver.getPipeSummary(ref)),
...injectables.map(ref => this._metadataResolver.getInjectableSummary(ref))
const typeSummaries: CompileTypeSummary[] = [
...ngModules.map(ref => this._metadataResolver.getNgModuleSummary(ref) !),
...directives.map(ref => this._metadataResolver.getDirectiveSummary(ref) !),
...pipes.map(ref => this._metadataResolver.getPipeSummary(ref) !),
...injectables.map(ref => this._metadataResolver.getInjectableSummary(ref) !)
];
const {json, exportAs} = serializeSummaries(
this._summaryResolver, this._symbolResolver, symbolSummaries, typeSummaries);
@ -130,7 +130,7 @@ export class AotCompiler {
}
private _compileModule(ngModuleType: StaticSymbol, targetStatements: o.Statement[]): string {
const ngModule = this._metadataResolver.getNgModuleMetadata(ngModuleType);
const ngModule = this._metadataResolver.getNgModuleMetadata(ngModuleType) !;
const providers: CompileProviderMetadata[] = [];
if (this._localeId) {
@ -183,11 +183,11 @@ export class AotCompiler {
o.variable(hostViewFactoryVar), new o.LiteralMapExpr(inputsExprs),
new o.LiteralMapExpr(outputsExprs),
o.literalArr(
compMeta.template.ngContentSelectors.map(selector => o.literal(selector)))
compMeta.template !.ngContentSelectors.map(selector => o.literal(selector)))
]))
.toDeclStmt(
o.importType(
createIdentifier(Identifiers.ComponentFactory), [o.importType(compMeta.type)],
createIdentifier(Identifiers.ComponentFactory), [o.importType(compMeta.type) !],
[o.TypeModifier.Const]),
[o.StmtModifier.Final]));
return compFactoryVar;
@ -195,7 +195,7 @@ export class AotCompiler {
private _compileComponent(
compMeta: CompileDirectiveMetadata, ngModule: CompileNgModuleMetadata,
directiveIdentifiers: CompileIdentifierMetadata[], componentStyles: CompiledStylesheet,
directiveIdentifiers: CompileIdentifierMetadata[], componentStyles: CompiledStylesheet|null,
fileSuffix: string,
targetStatements: o.Statement[]): {viewClassVar: string, compRenderTypeVar: string} {
const directives =
@ -204,8 +204,8 @@ export class AotCompiler {
pipe => this._metadataResolver.getPipeSummary(pipe.reference));
const {template: parsedTemplate, pipes: usedPipes} = this._templateParser.parse(
compMeta, compMeta.template.template, directives, pipes, ngModule.schemas,
templateSourceUrl(ngModule.type, compMeta, compMeta.template));
compMeta, compMeta.template !.template !, directives, pipes, ngModule.schemas,
templateSourceUrl(ngModule.type, compMeta, compMeta.template !));
const stylesExpr = componentStyles ? o.variable(componentStyles.stylesVar) : o.literalArr([]);
const viewResult =
this._viewCompiler.compileComponent(compMeta, parsedTemplate, stylesExpr, usedPipes);
@ -221,8 +221,9 @@ export class AotCompiler {
fileUrl: string, stylesCompileResult: CompiledStylesheet, fileSuffix: string): GeneratedFile {
_resolveStyleStatements(this._symbolResolver, stylesCompileResult, fileSuffix);
return this._codegenSourceModule(
fileUrl, _stylesModuleUrl(
stylesCompileResult.meta.moduleUrl, stylesCompileResult.isShimmed, fileSuffix),
fileUrl,
_stylesModuleUrl(
stylesCompileResult.meta.moduleUrl !, stylesCompileResult.isShimmed, fileSuffix),
stylesCompileResult.statements, [stylesCompileResult.stylesVar]);
}

View File

@ -70,15 +70,16 @@ export function createAotCompiler(compilerHost: AotCompilerHost, options: AotCom
console, symbolCache, staticReflector);
// TODO(vicb): do not pass options.i18nFormat here
const importResolver = {
getImportAs: (symbol: StaticSymbol) => symbolResolver.getImportAs(symbol),
getImportAs: (symbol: StaticSymbol) => symbolResolver.getImportAs(symbol) !,
fileNameToModuleName: (fileName: string, containingFilePath: string) =>
compilerHost.fileNameToModuleName(fileName, containingFilePath),
getTypeArity: (symbol: StaticSymbol) => symbolResolver.getTypeArity(symbol)
getTypeArity: (symbol: StaticSymbol) => symbolResolver.getTypeArity(symbol) !
};
const viewCompiler = new ViewCompiler(config, elementSchemaRegistry);
const compiler = new AotCompiler(
config, compilerHost, resolver, tmplParser, new StyleCompiler(urlResolver), viewCompiler,
new NgModuleCompiler(), new TypeScriptEmitter(importResolver), summaryResolver,
options.locale, options.i18nFormat, options.genFilePreamble, symbolResolver);
options.locale || null, options.i18nFormat || null, options.genFilePreamble || null,
symbolResolver);
return {compiler, reflector: staticReflector};
}

View File

@ -20,8 +20,7 @@ export interface AotCompilerHost extends StaticSymbolResolverHost, AotSummaryRes
*
* See ImportResolver.
*/
fileNameToModuleName(importedFilePath: string, containingFilePath: string): string
/*|null*/;
fileNameToModuleName(importedFilePath: string, containingFilePath: string): string|null;
/**
* Loads a resource (e.g. html / css)

View File

@ -41,7 +41,7 @@ export class StaticAndDynamicReflectionCapabilities {
getter(name: string): ɵGetterFn { return this.dynamicDelegate.getter(name); }
setter(name: string): ɵSetterFn { return this.dynamicDelegate.setter(name); }
method(name: string): ɵMethodFn { return this.dynamicDelegate.method(name); }
importUri(type: any): string { return this.staticDelegate.importUri(type); }
importUri(type: any): string { return this.staticDelegate.importUri(type) !; }
resourceUri(type: any): string { return this.staticDelegate.resourceUri(type); }
resolveIdentifier(name: string, moduleUrl: string, members: string[], runtime: any) {
return this.staticDelegate.resolveIdentifier(name, moduleUrl, members);

View File

@ -47,7 +47,7 @@ export class StaticReflector implements ɵReflectorReader {
private symbolResolver: StaticSymbolResolver,
knownMetadataClasses: {name: string, filePath: string, ctor: any}[] = [],
knownMetadataFunctions: {name: string, filePath: string, fn: any}[] = [],
private errorRecorder?: (error: any, fileName: string) => void) {
private errorRecorder?: (error: any, fileName?: string) => void) {
this.initializeConversionMap();
knownMetadataClasses.forEach(
(kc) => this._registerDecoratorOrConstructor(
@ -67,7 +67,7 @@ export class StaticReflector implements ɵReflectorReader {
this.annotationNames.set(Injectable, 'Injectable');
}
importUri(typeOrFunc: StaticSymbol): string {
importUri(typeOrFunc: StaticSymbol): string|null {
const staticSymbol = this.findSymbolDeclaration(typeOrFunc);
return staticSymbol ? staticSymbol.filePath : null;
}
@ -129,14 +129,14 @@ export class StaticReflector implements ɵReflectorReader {
const summary = this.summaryResolver.resolveSummary(parentType);
if (summary && summary.type) {
const requiredAnnotationTypes =
this.annotationForParentClassWithSummaryKind.get(summary.type.summaryKind);
this.annotationForParentClassWithSummaryKind.get(summary.type.summaryKind !) !;
const typeHasRequiredAnnotation = requiredAnnotationTypes.some(
requiredType => ownAnnotations.some(ann => ann instanceof requiredType));
(requiredType: any) => ownAnnotations.some(ann => ann instanceof requiredType));
if (!typeHasRequiredAnnotation) {
this.reportError(
syntaxError(
`Class ${type.name} in ${type.filePath} extends from a ${CompileSummaryKind[summary.type.summaryKind]} in another compilation unit without duplicating the decorator. ` +
`Please add a ${requiredAnnotationTypes.map(type => this.annotationNames.get(type)).join(' or ')} decorator to the class.`),
`Class ${type.name} in ${type.filePath} extends from a ${CompileSummaryKind[summary.type.summaryKind!]} in another compilation unit without duplicating the decorator. ` +
`Please add a ${requiredAnnotationTypes.map((type: any) => this.annotationNames.get(type)).join(' or ')} decorator to the class.`),
type);
}
}
@ -155,7 +155,7 @@ export class StaticReflector implements ɵReflectorReader {
if (parentType) {
const parentPropMetadata = this.propMetadata(parentType);
Object.keys(parentPropMetadata).forEach((parentProp) => {
propMetadata[parentProp] = parentPropMetadata[parentProp];
propMetadata ![parentProp] = parentPropMetadata[parentProp];
});
}
@ -165,10 +165,10 @@ export class StaticReflector implements ɵReflectorReader {
const prop = (<any[]>propData)
.find(a => a['__symbolic'] == 'property' || a['__symbolic'] == 'method');
const decorators: any[] = [];
if (propMetadata[propName]) {
decorators.push(...propMetadata[propName]);
if (propMetadata ![propName]) {
decorators.push(...propMetadata ![propName]);
}
propMetadata[propName] = decorators;
propMetadata ![propName] = decorators;
if (prop && prop['decorators']) {
decorators.push(...this.simplify(type, prop['decorators']));
}
@ -206,7 +206,7 @@ export class StaticReflector implements ɵReflectorReader {
if (decorators) {
nestedResult.push(...decorators);
}
parameters.push(nestedResult);
parameters !.push(nestedResult);
});
} else if (parentType) {
parameters = this.parameters(parentType);
@ -232,7 +232,7 @@ export class StaticReflector implements ɵReflectorReader {
if (parentType) {
const parentMethodNames = this._methodNames(parentType);
Object.keys(parentMethodNames).forEach((parentProp) => {
methodNames[parentProp] = parentMethodNames[parentProp];
methodNames ![parentProp] = parentMethodNames[parentProp];
});
}
@ -240,14 +240,14 @@ export class StaticReflector implements ɵReflectorReader {
Object.keys(members).forEach((propName) => {
const propData = members[propName];
const isMethod = (<any[]>propData).some(a => a['__symbolic'] == 'method');
methodNames[propName] = methodNames[propName] || isMethod;
methodNames ![propName] = methodNames ![propName] || isMethod;
});
this.methodCache.set(type, methodNames);
}
return methodNames;
}
private findParentType(type: StaticSymbol, classMetadata: any): StaticSymbol|null {
private findParentType(type: StaticSymbol, classMetadata: any): StaticSymbol|undefined {
const parentType = this.trySimplify(type, classMetadata['extends']);
if (parentType instanceof StaticSymbol) {
return parentType;

View File

@ -31,14 +31,14 @@ export interface StaticSymbolResolverHost {
* @param modulePath is a string identifier for a module as an absolute path.
* @returns the metadata for the given module.
*/
getMetadataFor(modulePath: string): {[key: string]: any}[];
getMetadataFor(modulePath: string): {[key: string]: any}[]|undefined;
/**
* Converts a module name that is used in an `import` to a file path.
* I.e.
* `path/to/containingFile.ts` containing `import {...} from 'module-name'`.
*/
moduleNameToFileName(moduleName: string, containingFile: string): string /*|null*/;
moduleNameToFileName(moduleName: string, containingFile?: string): string|null;
}
const SUPPORTED_SCHEMA_VERSION = 3;
@ -64,17 +64,17 @@ export class StaticSymbolResolver {
constructor(
private host: StaticSymbolResolverHost, private staticSymbolCache: StaticSymbolCache,
private summaryResolver: SummaryResolver<StaticSymbol>,
private errorRecorder?: (error: any, fileName: string) => void) {}
private errorRecorder?: (error: any, fileName?: string) => void) {}
resolveSymbol(staticSymbol: StaticSymbol): ResolvedStaticSymbol {
if (staticSymbol.members.length > 0) {
return this._resolveSymbolMembers(staticSymbol);
return this._resolveSymbolMembers(staticSymbol) !;
}
let result = this.resolvedSymbols.get(staticSymbol);
if (result) {
return result;
}
result = this._resolveSymbolFromSummary(staticSymbol);
result = this._resolveSymbolFromSummary(staticSymbol) !;
if (result) {
return result;
}
@ -82,7 +82,7 @@ export class StaticSymbolResolver {
// have summaries, only .d.ts files. So we always need to check both, the summary
// and metadata.
this._createSymbolsOf(staticSymbol.filePath);
result = this.resolvedSymbols.get(staticSymbol);
result = this.resolvedSymbols.get(staticSymbol) !;
return result;
}
@ -95,7 +95,7 @@ export class StaticSymbolResolver {
*
* @param staticSymbol the symbol for which to generate a import symbol
*/
getImportAs(staticSymbol: StaticSymbol): StaticSymbol {
getImportAs(staticSymbol: StaticSymbol): StaticSymbol|null {
if (staticSymbol.members.length) {
const baseSymbol = this.getStaticSymbol(staticSymbol.filePath, staticSymbol.name);
const baseImportAs = this.getImportAs(baseSymbol);
@ -105,7 +105,7 @@ export class StaticSymbolResolver {
}
let result = this.summaryResolver.getImportAs(staticSymbol);
if (!result) {
result = this.importAs.get(staticSymbol);
result = this.importAs.get(staticSymbol) !;
}
return result;
}
@ -123,7 +123,7 @@ export class StaticSymbolResolver {
* getTypeArity returns the number of generic type parameters the given symbol
* has. If the symbol is not a type the result is null.
*/
getTypeArity(staticSymbol: StaticSymbol): number /*|null*/ {
getTypeArity(staticSymbol: StaticSymbol): number|null {
// If the file is a factory file, don't resolve the symbol as doing so would
// cause the metadata for an factory file to be loaded which doesn't exist.
// All references to generated classes must include the correct arity whenever
@ -163,7 +163,7 @@ export class StaticSymbolResolver {
}
}
private _resolveSymbolMembers(staticSymbol: StaticSymbol): ResolvedStaticSymbol {
private _resolveSymbolMembers(staticSymbol: StaticSymbol): ResolvedStaticSymbol|null {
const members = staticSymbol.members;
const baseResolvedSymbol =
this.resolveSymbol(this.getStaticSymbol(staticSymbol.filePath, staticSymbol.name));
@ -188,7 +188,7 @@ export class StaticSymbolResolver {
return null;
}
private _resolveSymbolFromSummary(staticSymbol: StaticSymbol): ResolvedStaticSymbol {
private _resolveSymbolFromSummary(staticSymbol: StaticSymbol): ResolvedStaticSymbol|null {
const summary = this.summaryResolver.resolveSummary(staticSymbol);
return summary ? new ResolvedStaticSymbol(staticSymbol, summary.metadata) : null;
}
@ -252,7 +252,7 @@ export class StaticSymbolResolver {
const originFilePath = this.resolveModule(origin, filePath);
if (!originFilePath) {
this.reportError(
new Error(`Couldn't resolve original symbol for ${origin} from ${filePath}`), null);
new Error(`Couldn't resolve original symbol for ${origin} from ${filePath}`));
} else {
this.symbolResourcePaths.set(symbol, originFilePath);
}
@ -337,7 +337,7 @@ export class StaticSymbolResolver {
}
let filePath: string;
if (module) {
filePath = self.resolveModule(module, sourceSymbol.filePath);
filePath = self.resolveModule(module, sourceSymbol.filePath) !;
if (!filePath) {
return {
__symbolic: 'error',
@ -381,7 +381,7 @@ export class StaticSymbolResolver {
return new ResolvedStaticSymbol(sourceSymbol, targetSymbol);
}
private reportError(error: Error, context: StaticSymbol, path?: string) {
private reportError(error: Error, context?: StaticSymbol, path?: string) {
if (this.errorRecorder) {
this.errorRecorder(error, (context && context.filePath) || path);
} else {
@ -413,7 +413,7 @@ export class StaticSymbolResolver {
const errorMessage = moduleMetadata['version'] == 2 ?
`Unsupported metadata version ${moduleMetadata['version']} for module ${module}. This module should be compiled with a newer version of ngc` :
`Metadata version mismatch for module ${module}, found version ${moduleMetadata['version']}, expected ${SUPPORTED_SCHEMA_VERSION}`;
this.reportError(new Error(errorMessage), null);
this.reportError(new Error(errorMessage));
}
this.metadataCache.set(module, moduleMetadata);
}
@ -426,20 +426,20 @@ export class StaticSymbolResolver {
this.reportError(
new Error(`Could not resolve module ${module}${containingFile ? ` relative to $ {
containingFile
} `: ''}`),
null);
} `: ''}`));
return this.getStaticSymbol(`ERROR:${module}`, symbolName);
}
return this.getStaticSymbol(filePath, symbolName);
}
private resolveModule(module: string, containingFile: string): string {
private resolveModule(module: string, containingFile?: string): string|null {
try {
return this.host.moduleNameToFileName(module, containingFile);
} catch (e) {
console.error(`Could not resolve module '${module}' relative to file ${containingFile}`);
this.reportError(e, null, containingFile);
this.reportError(e, undefined, containingFile);
}
return null;
}
}
@ -447,4 +447,4 @@ export class StaticSymbolResolver {
// See https://github.com/Microsoft/TypeScript/blob/master/src/compiler/utilities.ts
export function unescapeIdentifier(identifier: string): string {
return identifier.startsWith('___') ? identifier.substr(1) : identifier;
}
}

View File

@ -16,7 +16,7 @@ export interface AotSummaryResolverHost {
/**
* Loads an NgModule/Directive/Pipe summary file
*/
loadSummary(filePath: string): string /*|null*/;
loadSummary(filePath: string): string|null;
/**
* Returns whether a file is a source file or not.
@ -53,7 +53,7 @@ export class AotSummaryResolver implements SummaryResolver<StaticSymbol> {
let summary = this.summaryCache.get(staticSymbol);
if (!summary) {
this._loadSummaryFile(staticSymbol.filePath);
summary = this.summaryCache.get(staticSymbol);
summary = this.summaryCache.get(staticSymbol) !;
}
return summary;
}
@ -65,7 +65,7 @@ export class AotSummaryResolver implements SummaryResolver<StaticSymbol> {
getImportAs(staticSymbol: StaticSymbol): StaticSymbol {
staticSymbol.assertNoMembers();
return this.importAs.get(staticSymbol);
return this.importAs.get(staticSymbol) !;
}
private _loadSummaryFile(filePath: string) {
@ -75,7 +75,7 @@ export class AotSummaryResolver implements SummaryResolver<StaticSymbol> {
this.loadedFilePaths.add(filePath);
if (this.isLibraryFile(filePath)) {
const summaryFilePath = summaryFileName(filePath);
let json: string;
let json: string|null;
try {
json = this.host.loadSummary(summaryFilePath);
} catch (e) {

View File

@ -133,7 +133,7 @@ class Serializer extends ValueTransformer {
summaries: this.processedSummaries,
symbols: this.symbols.map((symbol, index) => {
symbol.assertNoMembers();
let importAs: string;
let importAs: string = undefined !;
if (this.summaryResolver.isLibraryFile(symbol.filePath)) {
importAs = `${symbol.name}_${index}`;
exportAs.push({symbol, exportAs: importAs});