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

@ -33,7 +33,7 @@ export class CompilerHost implements AotCompilerHost {
private resolverCache = new Map<string, ModuleMetadata[]>();
private bundleIndexCache = new Map<string, boolean>();
private bundleIndexNames = new Set<string>();
private moduleFileNames = new Map<string, string>();
private moduleFileNames = new Map<string, string|null>();
protected resolveModuleNameHost: CompilerHostContext;
constructor(
@ -71,7 +71,7 @@ export class CompilerHost implements AotCompilerHost {
moduleNameToFileName(m: string, containingFile: string): string|null {
const key = m + ':' + (containingFile || '');
let result = this.moduleFileNames.get(key);
let result: string|null = this.moduleFileNames.get(key) || null;
if (!result) {
if (!containingFile || !containingFile.length) {
if (m.indexOf('.') === 0) {
@ -183,7 +183,7 @@ export class CompilerHost implements AotCompilerHost {
return sf;
}
getMetadataFor(filePath: string): ModuleMetadata[] {
getMetadataFor(filePath: string): ModuleMetadata[]|undefined {
if (!this.context.fileExists(filePath)) {
// If the file doesn't exists then we cannot return metadata for the file.
// This will occur if the user refernced a declared module for which no file
@ -263,6 +263,7 @@ export class CompilerHost implements AotCompilerHost {
if (this.context.fileExists(filePath)) {
return this.context.readFile(filePath);
}
return null;
}
getOutputFileName(sourceFilePath: string): string {
@ -287,7 +288,7 @@ export class CompilerHost implements AotCompilerHost {
calculateEmitPath(filePath: string): string {
// Write codegen in a directory structure matching the sources.
let root = this.options.basePath;
let root = this.options.basePath !;
for (const eachRootDir of this.options.rootDirs || []) {
if (this.options.trace) {
console.error(`Check if ${filePath} is under rootDirs element ${eachRootDir}`);
@ -373,7 +374,7 @@ export class ModuleResolutionHostAdapter extends CompilerHostContextAdapter impl
constructor(private host: ts.ModuleResolutionHost) {
super();
if (host.directoryExists) {
this.directoryExists = (directoryName: string) => host.directoryExists(directoryName);
this.directoryExists = (directoryName: string) => host.directoryExists !(directoryName);
}
}

View File

@ -23,7 +23,7 @@ function extract(
ngOptions: tsc.AngularCompilerOptions, cliOptions: tsc.I18nExtractionCliOptions,
program: ts.Program, host: ts.CompilerHost): Promise<void> {
return Extractor.create(ngOptions, program, host, cliOptions.locale)
.extract(cliOptions.i18nFormat, cliOptions.outFile);
.extract(cliOptions.i18nFormat !, cliOptions.outFile);
}
// Entry point

View File

@ -92,9 +92,9 @@ export class NgTools_InternalApi_NG_2 {
const hostContext: CompilerHostContext =
new CustomLoaderModuleResolutionHostAdapter(options.readResource, options.host);
const cliOptions: NgcCliOptions = {
i18nFormat: options.i18nFormat,
i18nFile: options.i18nFile,
locale: options.locale,
i18nFormat: options.i18nFormat !,
i18nFile: options.i18nFile !,
locale: options.locale !,
basePath: options.basePath
};
@ -148,6 +148,6 @@ export class NgTools_InternalApi_NG_2 {
const extractor = Extractor.create(
options.angularCompilerOptions, options.program, options.host, locale, hostContext);
return extractor.extract(options.i18nFormat, options.outFile || null);
return extractor.extract(options.i18nFormat !, options.outFile || null);
}
}

View File

@ -33,7 +33,8 @@ export type LazyRouteMap = {
// A route definition. Normally the short form 'path/to/module#ModuleClassName' is used by
// the user, and this is a helper class to extract information from it.
export class RouteDef {
private constructor(public readonly path: string, public readonly className: string = null) {}
private constructor(public readonly path: string, public readonly className: string|null = null) {
}
toString() {
return (this.className === null || this.className == 'default') ?
@ -58,7 +59,7 @@ export function listLazyRoutesOfModule(
const entryRouteDef = RouteDef.fromString(entryModule);
const containingFile = _resolveModule(entryRouteDef.path, entryRouteDef.path, host);
const modulePath = `./${containingFile.replace(/^(.*)\//, '')}`;
const className = entryRouteDef.className;
const className = entryRouteDef.className !;
// List loadChildren of this single module.
const appStaticSymbol = reflector.findDeclaration(modulePath, className, containingFile);

View File

@ -40,7 +40,7 @@ export class PathMappedCompilerHost extends CompilerHost {
return fileName;
}
moduleNameToFileName(m: string, containingFile: string) {
moduleNameToFileName(m: string, containingFile: string): string|null {
if (!containingFile || !containingFile.length) {
if (m.indexOf('.') === 0) {
throw new Error('Resolution of relative paths requires a containing file.');
@ -59,6 +59,7 @@ export class PathMappedCompilerHost extends CompilerHost {
return this.getCanonicalFileName(resolved.resolvedFileName);
}
}
return null;
}
/**
@ -90,7 +91,7 @@ export class PathMappedCompilerHost extends CompilerHost {
const importModuleName = importedFile.replace(EXT, '');
const parts = importModuleName.split(path.sep).filter(p => !!p);
let foundRelativeImport: string;
let foundRelativeImport: string = undefined !;
for (let index = parts.length - 1; index >= 0; index--) {
let candidate = parts.slice(index, parts.length).join(path.sep);
if (resolvable(candidate)) {
@ -135,5 +136,6 @@ export class PathMappedCompilerHost extends CompilerHost {
return metadata ? [metadata] : [];
}
}
return null !;
}
}

View File

@ -4,6 +4,7 @@
"declaration": true,
"experimentalDecorators": true,
"noImplicitAny": true,
"strictNullChecks": true,
"module": "commonjs",
"outDir": "../../dist/packages/compiler-cli",
"paths": {

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});

View File

@ -22,7 +22,8 @@ const HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))|(\@[-\w]+)$/;
export class CompileAnimationEntryMetadata {
constructor(
public name: string = null, public definitions: CompileAnimationStateMetadata[] = null) {}
public name: string|null = null,
public definitions: CompileAnimationStateMetadata[]|null = null) {}
}
export abstract class CompileAnimationStateMetadata {}
@ -49,7 +50,8 @@ export class CompileAnimationKeyframesSequenceMetadata extends CompileAnimationM
export class CompileAnimationStyleMetadata extends CompileAnimationMetadata {
constructor(
public offset: number, public styles: Array<string|{[key: string]: string | number}> = null) {
public offset: number,
public styles: Array<string|{[key: string]: string | number}>|null = null) {
super();
}
}
@ -57,21 +59,21 @@ export class CompileAnimationStyleMetadata extends CompileAnimationMetadata {
export class CompileAnimationAnimateMetadata extends CompileAnimationMetadata {
constructor(
public timings: string|number = 0, public styles: CompileAnimationStyleMetadata|
CompileAnimationKeyframesSequenceMetadata = null) {
CompileAnimationKeyframesSequenceMetadata|null = null) {
super();
}
}
export abstract class CompileAnimationWithStepsMetadata extends CompileAnimationMetadata {
constructor(public steps: CompileAnimationMetadata[] = null) { super(); }
constructor(public steps: CompileAnimationMetadata[]|null = null) { super(); }
}
export class CompileAnimationSequenceMetadata extends CompileAnimationWithStepsMetadata {
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
constructor(steps: CompileAnimationMetadata[]|null = null) { super(steps); }
}
export class CompileAnimationGroupMetadata extends CompileAnimationWithStepsMetadata {
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
constructor(steps: CompileAnimationMetadata[]|null = null) { super(steps); }
}
@ -81,7 +83,8 @@ function _sanitizeIdentifier(name: string): string {
let _anonymousTypeIndex = 0;
export function identifierName(compileIdentifier: CompileIdentifierMetadata): string {
export function identifierName(compileIdentifier: CompileIdentifierMetadata | null | undefined):
string|null {
if (!compileIdentifier || !compileIdentifier.reference) {
return null;
}
@ -148,7 +151,7 @@ export enum CompileSummaryKind {
* the directive / module itself.
*/
export interface CompileTypeSummary {
summaryKind: CompileSummaryKind;
summaryKind: CompileSummaryKind|null;
type: CompileTypeMetadata;
}
@ -216,13 +219,13 @@ export interface CompileQueryMetadata {
* Metadata about a stylesheet
*/
export class CompileStylesheetMetadata {
moduleUrl: string;
moduleUrl: string|null;
styles: string[];
styleUrls: string[];
constructor(
{moduleUrl, styles,
styleUrls}: {moduleUrl?: string, styles?: string[], styleUrls?: string[]} = {}) {
this.moduleUrl = moduleUrl;
this.moduleUrl = moduleUrl || null;
this.styles = _normalizeArray(styles);
this.styleUrls = _normalizeArray(styleUrls);
}
@ -232,39 +235,38 @@ export class CompileStylesheetMetadata {
* Summary Metadata regarding compilation of a template.
*/
export interface CompileTemplateSummary {
animations: string[];
animations: string[]|null;
ngContentSelectors: string[];
encapsulation: ViewEncapsulation;
encapsulation: ViewEncapsulation|null;
}
/**
* Metadata regarding compilation of a template.
*/
export class CompileTemplateMetadata {
encapsulation: ViewEncapsulation;
template: string;
templateUrl: string;
encapsulation: ViewEncapsulation|null;
template: string|null;
templateUrl: string|null;
isInline: boolean;
styles: string[];
styleUrls: string[];
externalStylesheets: CompileStylesheetMetadata[];
animations: any[];
ngContentSelectors: string[];
interpolation: [string, string];
constructor(
{encapsulation, template, templateUrl, styles, styleUrls, externalStylesheets, animations,
ngContentSelectors, interpolation, isInline}: {
encapsulation?: ViewEncapsulation,
template?: string,
templateUrl?: string,
styles?: string[],
styleUrls?: string[],
externalStylesheets?: CompileStylesheetMetadata[],
ngContentSelectors?: string[],
animations?: any[],
interpolation?: [string, string],
isInline?: boolean
} = {}) {
interpolation: [string, string]|null;
constructor({encapsulation, template, templateUrl, styles, styleUrls, externalStylesheets,
animations, ngContentSelectors, interpolation, isInline}: {
encapsulation: ViewEncapsulation | null,
template: string|null,
templateUrl: string|null,
styles: string[],
styleUrls: string[],
externalStylesheets: CompileStylesheetMetadata[],
ngContentSelectors: string[],
animations: any[],
interpolation: [string, string]|null,
isInline: boolean
}) {
this.encapsulation = encapsulation;
this.template = template;
this.templateUrl = templateUrl;
@ -299,8 +301,8 @@ export interface CompileEntryComponentMetadata {
export interface CompileDirectiveSummary extends CompileTypeSummary {
type: CompileTypeMetadata;
isComponent: boolean;
selector: string;
exportAs: string;
selector: string|null;
exportAs: string|null;
inputs: {[key: string]: string};
outputs: {[key: string]: string};
hostListeners: {[key: string]: string};
@ -311,40 +313,39 @@ export interface CompileDirectiveSummary extends CompileTypeSummary {
queries: CompileQueryMetadata[];
viewQueries: CompileQueryMetadata[];
entryComponents: CompileEntryComponentMetadata[];
changeDetection: ChangeDetectionStrategy;
template: CompileTemplateSummary;
componentViewType: StaticSymbol|ProxyClass;
rendererType: StaticSymbol|RendererType2;
componentFactory: StaticSymbol|ComponentFactory<any>;
changeDetection: ChangeDetectionStrategy|null;
template: CompileTemplateSummary|null;
componentViewType: StaticSymbol|ProxyClass|null;
rendererType: StaticSymbol|RendererType2|null;
componentFactory: StaticSymbol|ComponentFactory<any>|null;
}
/**
* Metadata regarding compilation of a directive.
*/
export class CompileDirectiveMetadata {
static create(
{isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
providers, viewProviders, queries, viewQueries, entryComponents, template, componentViewType,
rendererType, componentFactory}: {
isHost?: boolean,
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
exportAs?: string,
changeDetection?: ChangeDetectionStrategy,
inputs?: string[],
outputs?: string[],
host?: {[key: string]: string},
providers?: CompileProviderMetadata[],
viewProviders?: CompileProviderMetadata[],
queries?: CompileQueryMetadata[],
viewQueries?: CompileQueryMetadata[],
entryComponents?: CompileEntryComponentMetadata[],
template?: CompileTemplateMetadata,
componentViewType?: StaticSymbol|ProxyClass,
rendererType?: StaticSymbol|RendererType2,
componentFactory?: StaticSymbol|ComponentFactory<any>,
} = {}): CompileDirectiveMetadata {
static create({isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs,
host, providers, viewProviders, queries, viewQueries, entryComponents, template,
componentViewType, rendererType, componentFactory}: {
isHost: boolean,
type: CompileTypeMetadata,
isComponent: boolean,
selector: string|null,
exportAs: string|null,
changeDetection: ChangeDetectionStrategy|null,
inputs: string[],
outputs: string[],
host: {[key: string]: string},
providers: CompileProviderMetadata[],
viewProviders: CompileProviderMetadata[],
queries: CompileQueryMetadata[],
viewQueries: CompileQueryMetadata[],
entryComponents: CompileEntryComponentMetadata[],
template: CompileTemplateMetadata,
componentViewType: StaticSymbol|ProxyClass|null,
rendererType: StaticSymbol|RendererType2|null,
componentFactory: StaticSymbol|ComponentFactory<any>|null,
}): CompileDirectiveMetadata {
const hostListeners: {[key: string]: string} = {};
const hostProperties: {[key: string]: string} = {};
const hostAttributes: {[key: string]: string} = {};
@ -403,9 +404,9 @@ export class CompileDirectiveMetadata {
isHost: boolean;
type: CompileTypeMetadata;
isComponent: boolean;
selector: string;
exportAs: string;
changeDetection: ChangeDetectionStrategy;
selector: string|null;
exportAs: string|null;
changeDetection: ChangeDetectionStrategy|null;
inputs: {[key: string]: string};
outputs: {[key: string]: string};
hostListeners: {[key: string]: string};
@ -417,37 +418,37 @@ export class CompileDirectiveMetadata {
viewQueries: CompileQueryMetadata[];
entryComponents: CompileEntryComponentMetadata[];
template: CompileTemplateMetadata;
template: CompileTemplateMetadata|null;
componentViewType: StaticSymbol|ProxyClass;
rendererType: StaticSymbol|RendererType2;
componentFactory: StaticSymbol|ComponentFactory<any>;
componentViewType: StaticSymbol|ProxyClass|null;
rendererType: StaticSymbol|RendererType2|null;
componentFactory: StaticSymbol|ComponentFactory<any>|null;
constructor({isHost, type, isComponent, selector, exportAs,
changeDetection, inputs, outputs, hostListeners, hostProperties,
hostAttributes, providers, viewProviders, queries, viewQueries,
entryComponents, template, componentViewType, rendererType, componentFactory}: {
isHost?: boolean,
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
exportAs?: string,
changeDetection?: ChangeDetectionStrategy,
inputs?: {[key: string]: string},
outputs?: {[key: string]: string},
hostListeners?: {[key: string]: string},
hostProperties?: {[key: string]: string},
hostAttributes?: {[key: string]: string},
providers?: CompileProviderMetadata[],
viewProviders?: CompileProviderMetadata[],
queries?: CompileQueryMetadata[],
viewQueries?: CompileQueryMetadata[],
entryComponents?: CompileEntryComponentMetadata[],
template?: CompileTemplateMetadata,
componentViewType?: StaticSymbol|ProxyClass,
rendererType?: StaticSymbol|RendererType2,
componentFactory?: StaticSymbol|ComponentFactory<any>,
} = {}) {
isHost: boolean,
type: CompileTypeMetadata,
isComponent: boolean,
selector: string|null,
exportAs: string|null,
changeDetection: ChangeDetectionStrategy|null,
inputs: {[key: string]: string},
outputs: {[key: string]: string},
hostListeners: {[key: string]: string},
hostProperties: {[key: string]: string},
hostAttributes: {[key: string]: string},
providers: CompileProviderMetadata[],
viewProviders: CompileProviderMetadata[],
queries: CompileQueryMetadata[],
viewQueries: CompileQueryMetadata[],
entryComponents: CompileEntryComponentMetadata[],
template: CompileTemplateMetadata|null,
componentViewType: StaticSymbol|ProxyClass|null,
rendererType: StaticSymbol|RendererType2|null,
componentFactory: StaticSymbol|ComponentFactory<any>|null,
}) {
this.isHost = !!isHost;
this.type = type;
this.isComponent = isComponent;
@ -503,7 +504,7 @@ export class CompileDirectiveMetadata {
export function createHostComponentMeta(
hostTypeReference: any, compMeta: CompileDirectiveMetadata,
hostViewType: StaticSymbol | ProxyClass): CompileDirectiveMetadata {
const template = CssSelector.parse(compMeta.selector)[0].getMatchingElementTemplate();
const template = CssSelector.parse(compMeta.selector !)[0].getMatchingElementTemplate();
return CompileDirectiveMetadata.create({
isHost: true,
type: {reference: hostTypeReference, diDeps: [], lifecycleHooks: []},
@ -516,7 +517,10 @@ export function createHostComponentMeta(
ngContentSelectors: [],
animations: [],
isInline: true,
externalStylesheets: [],
interpolation: null
}),
exportAs: null,
changeDetection: ChangeDetectionStrategy.Default,
inputs: [],
outputs: [],
@ -528,7 +532,9 @@ export function createHostComponentMeta(
queries: [],
viewQueries: [],
componentViewType: hostViewType,
rendererType: {id: '__Host__', encapsulation: ViewEncapsulation.None, styles: [], data: {}}
rendererType: {id: '__Host__', encapsulation: ViewEncapsulation.None, styles: [], data: {}},
entryComponents: [],
componentFactory: null
});
}
@ -544,10 +550,10 @@ export class CompilePipeMetadata {
pure: boolean;
constructor({type, name, pure}: {
type?: CompileTypeMetadata,
name?: string,
pure?: boolean,
} = {}) {
type: CompileTypeMetadata,
name: string,
pure: boolean,
}) {
this.type = type;
this.name = name;
this.pure = !!pure;
@ -598,29 +604,28 @@ export class CompileNgModuleMetadata {
importedModules: CompileNgModuleSummary[];
exportedModules: CompileNgModuleSummary[];
schemas: SchemaMetadata[];
id: string;
id: string|null;
transitiveModule: TransitiveCompileNgModuleMetadata;
constructor(
{type, providers, declaredDirectives, exportedDirectives, declaredPipes, exportedPipes,
entryComponents, bootstrapComponents, importedModules, exportedModules, schemas,
transitiveModule, id}: {
type?: CompileTypeMetadata,
providers?: CompileProviderMetadata[],
declaredDirectives?: CompileIdentifierMetadata[],
exportedDirectives?: CompileIdentifierMetadata[],
declaredPipes?: CompileIdentifierMetadata[],
exportedPipes?: CompileIdentifierMetadata[],
entryComponents?: CompileEntryComponentMetadata[],
bootstrapComponents?: CompileIdentifierMetadata[],
importedModules?: CompileNgModuleSummary[],
exportedModules?: CompileNgModuleSummary[],
transitiveModule?: TransitiveCompileNgModuleMetadata,
schemas?: SchemaMetadata[],
id?: string
} = {}) {
this.type = type;
constructor({type, providers, declaredDirectives, exportedDirectives, declaredPipes,
exportedPipes, entryComponents, bootstrapComponents, importedModules,
exportedModules, schemas, transitiveModule, id}: {
type: CompileTypeMetadata,
providers: CompileProviderMetadata[],
declaredDirectives: CompileIdentifierMetadata[],
exportedDirectives: CompileIdentifierMetadata[],
declaredPipes: CompileIdentifierMetadata[],
exportedPipes: CompileIdentifierMetadata[],
entryComponents: CompileEntryComponentMetadata[],
bootstrapComponents: CompileIdentifierMetadata[],
importedModules: CompileNgModuleSummary[],
exportedModules: CompileNgModuleSummary[],
transitiveModule: TransitiveCompileNgModuleMetadata,
schemas: SchemaMetadata[],
id: string|null
}) {
this.type = type || null;
this.declaredDirectives = _normalizeArray(declaredDirectives);
this.exportedDirectives = _normalizeArray(exportedDirectives);
this.declaredPipes = _normalizeArray(declaredPipes);
@ -631,19 +636,20 @@ export class CompileNgModuleMetadata {
this.importedModules = _normalizeArray(importedModules);
this.exportedModules = _normalizeArray(exportedModules);
this.schemas = _normalizeArray(schemas);
this.id = id;
this.transitiveModule = transitiveModule;
this.id = id || null;
this.transitiveModule = transitiveModule || null;
}
toSummary(): CompileNgModuleSummary {
const module = this.transitiveModule !;
return {
summaryKind: CompileSummaryKind.NgModule,
type: this.type,
entryComponents: this.transitiveModule.entryComponents,
providers: this.transitiveModule.providers,
modules: this.transitiveModule.modules,
exportedDirectives: this.transitiveModule.exportedDirectives,
exportedPipes: this.transitiveModule.exportedPipes
entryComponents: module.entryComponents,
providers: module.providers,
modules: module.modules,
exportedDirectives: module.exportedDirectives,
exportedPipes: module.exportedPipes
};
}
}
@ -706,33 +712,33 @@ export class TransitiveCompileNgModuleMetadata {
}
}
function _normalizeArray(obj: any[]): any[] {
function _normalizeArray(obj: any[] | undefined | null): any[] {
return obj || [];
}
export class ProviderMeta {
token: any;
useClass: Type<any>;
useClass: Type<any>|null;
useValue: any;
useExisting: any;
useFactory: Function;
dependencies: Object[];
useFactory: Function|null;
dependencies: Object[]|null;
multi: boolean;
constructor(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: {
useClass?: Type<any>,
useValue?: any,
useExisting?: any,
useFactory?: Function,
deps?: Object[],
useFactory?: Function|null,
deps?: Object[]|null,
multi?: boolean
}) {
this.token = token;
this.useClass = useClass;
this.useClass = useClass || null;
this.useValue = useValue;
this.useExisting = useExisting;
this.useFactory = useFactory;
this.dependencies = deps;
this.useFactory = useFactory || null;
this.dependencies = deps || null;
this.multi = !!multi;
}
}
@ -752,7 +758,7 @@ export function sourceUrl(url: string) {
export function templateSourceUrl(
ngModuleType: CompileIdentifierMetadata, compMeta: {type: CompileIdentifierMetadata},
templateMeta: {isInline: boolean, templateUrl: string}) {
templateMeta: {isInline: boolean, templateUrl: string | null}) {
let url: string;
if (templateMeta.isInline) {
if (compMeta.type.reference instanceof StaticSymbol) {
@ -763,7 +769,7 @@ export function templateSourceUrl(
url = `${identifierName(ngModuleType)}/${identifierName(compMeta.type)}.html`;
}
} else {
url = templateMeta.templateUrl;
url = templateMeta.templateUrl !;
}
// always prepend ng:// to make angular resources easy to find and not clobber
// user resources.
@ -771,7 +777,7 @@ export function templateSourceUrl(
}
export function sharedStylesheetJitUrl(meta: CompileStylesheetMetadata, id: number) {
const pathParts = meta.moduleUrl.split(/\/\\/g);
const pathParts = meta.moduleUrl !.split(/\/\\/g);
const baseName = pathParts[pathParts.length - 1];
return sourceUrl(`css/${id}${baseName}.ngstyle.js`);
}

View File

@ -13,7 +13,7 @@ import * as o from '../output/output_ast';
export class EventHandlerVars { static event = o.variable('$event'); }
export interface LocalResolver { getLocal(name: string): o.Expression; }
export interface LocalResolver { getLocal(name: string): o.Expression|null; }
export class ConvertActionBindingResult {
constructor(public stmts: o.Statement[], public allowDefault: o.ReadVarExpr) {}
@ -24,7 +24,7 @@ export class ConvertActionBindingResult {
* used in an action binding (e.g. an event handler).
*/
export function convertActionBinding(
localResolver: LocalResolver, implicitReceiver: o.Expression, action: cdAst.AST,
localResolver: LocalResolver | null, implicitReceiver: o.Expression, action: cdAst.AST,
bindingId: string): ConvertActionBindingResult {
if (!localResolver) {
localResolver = new DefaultLocalResolver();
@ -51,7 +51,7 @@ export function convertActionBinding(
flattenStatements(actionWithoutBuiltins.visit(visitor, _Mode.Statement), actionStmts);
prependTemporaryDecls(visitor.temporaryCount, bindingId, actionStmts);
const lastIndex = actionStmts.length - 1;
let preventDefaultVar: o.ReadVarExpr = null;
let preventDefaultVar: o.ReadVarExpr = null !;
if (lastIndex >= 0) {
const lastStatement = actionStmts[lastIndex];
const returnExpr = convertStmtIntoExpression(lastStatement);
@ -90,7 +90,7 @@ export class ConvertPropertyBindingResult {
* `convertPropertyBindingBuiltins`.
*/
export function convertPropertyBinding(
localResolver: LocalResolver, implicitReceiver: o.Expression,
localResolver: LocalResolver | null, implicitReceiver: o.Expression,
expressionWithoutBuiltins: cdAst.AST, bindingId: string): ConvertPropertyBindingResult {
if (!localResolver) {
localResolver = new DefaultLocalResolver();
@ -266,7 +266,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
if (ast instanceof BuiltinFunctionCall) {
fnResult = ast.converter(convertedArgs);
} else {
fnResult = this.visit(ast.target, _Mode.Expression).callFn(convertedArgs);
fnResult = this.visit(ast.target !, _Mode.Expression).callFn(convertedArgs);
}
return convertToStatementIfNeeded(mode, fnResult);
}
@ -321,7 +321,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
return convertToStatementIfNeeded(mode, o.literal(ast.value));
}
private _getLocal(name: string): o.Expression { return this._localResolver.getLocal(name); }
private _getLocal(name: string): o.Expression|null { return this._localResolver.getLocal(name); }
visitMethodCall(ast: cdAst.MethodCall, mode: _Mode): any {
const leftMostSafe = this.leftMostSafeNode(ast);
@ -439,7 +439,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
// which comes in as leftMostSafe to this routine.
let guardedExpression = this.visit(leftMostSafe.receiver, _Mode.Expression);
let temporary: o.ReadVarExpr;
let temporary: o.ReadVarExpr = undefined !;
if (this.needsTemporary(leftMostSafe.receiver)) {
// If the expression has method calls or pipes then we need to save the result into a
// temporary variable to avoid calling stateful or impure code more than once.
@ -577,7 +577,7 @@ function flattenStatements(arg: any, output: o.Statement[]) {
}
class DefaultLocalResolver implements LocalResolver {
getLocal(name: string): o.Expression {
getLocal(name: string): o.Expression|null {
if (name === EventHandlerVars.event.name) {
return EventHandlerVars.event;
}
@ -593,7 +593,7 @@ function createPreventDefaultVar(bindingId: string): o.ReadVarExpr {
return o.variable(`pd_${bindingId}`);
}
function convertStmtIntoExpression(stmt: o.Statement): o.Expression {
function convertStmtIntoExpression(stmt: o.Statement): o.Expression|null {
if (stmt instanceof o.ExpressionStatement) {
return stmt.expr;
} else if (stmt instanceof o.ReturnStatement) {

View File

@ -13,12 +13,12 @@ import {Identifiers, createIdentifier} from './identifiers';
export class CompilerConfig {
public defaultEncapsulation: ViewEncapsulation;
public defaultEncapsulation: ViewEncapsulation|null;
// Whether to support the `<template>` tag and the `template` attribute to define angular
// templates. They have been deprecated in 4.x, `<ng-template>` should be used instead.
public enableLegacyTemplate: boolean;
public useJit: boolean;
public missingTranslation: MissingTranslationStrategy;
public missingTranslation: MissingTranslationStrategy|null;
constructor(
{defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, missingTranslation,
@ -29,8 +29,8 @@ export class CompilerConfig {
enableLegacyTemplate?: boolean,
} = {}) {
this.defaultEncapsulation = defaultEncapsulation;
this.useJit = useJit;
this.missingTranslation = missingTranslation;
this.useJit = !!useJit;
this.missingTranslation = missingTranslation || null;
this.enableLegacyTemplate = enableLegacyTemplate !== false;
}
}

View File

@ -65,7 +65,7 @@ export abstract class CssRuleAst extends CssAst {
export class CssBlockRuleAst extends CssRuleAst {
constructor(
public location: ParseSourceSpan, public type: BlockType, public block: CssBlockAst,
public name: CssToken = null) {
public name: CssToken|null = null) {
super(location);
}
visit(visitor: CssAstVisitor, context?: any): any {

View File

@ -40,7 +40,7 @@ export enum CssLexerMode {
}
export class LexedCssResult {
constructor(public error: Error, public token: CssToken) {}
constructor(public error: Error|null, public token: CssToken) {}
}
export function generateErrorMessage(
@ -126,7 +126,7 @@ export class CssScanner {
/** @internal */
_currentMode: CssLexerMode = CssLexerMode.BLOCK;
/** @internal */
_currentError: Error = null;
_currentError: Error|null = null;
constructor(public input: string, private _trackComments: boolean = false) {
this.length = this.input.length;
@ -188,7 +188,7 @@ export class CssScanner {
}
}
consume(type: CssTokenType, value: string = null): LexedCssResult {
consume(type: CssTokenType, value: string|null = null): LexedCssResult {
const mode = this._currentMode;
this.setMode(_trackWhitespace(mode) ? CssLexerMode.ALL_TRACK_WS : CssLexerMode.ALL);
@ -197,7 +197,7 @@ export class CssScanner {
const previousLine = this.line;
const previousColumn = this.column;
let next: CssToken;
let next: CssToken = undefined !;
const output = this.scan();
if (output != null) {
// just incase the inner scan method returned an error
@ -225,7 +225,7 @@ export class CssScanner {
// mode so that the parser can recover...
this.setMode(mode);
let error: Error = null;
let error: Error|null = null;
if (!isMatchingType || (value != null && value != next.strValue)) {
let errorMessage =
CssTokenType[next.type] + ' does not match expected ' + CssTokenType[type] + ' value';
@ -244,7 +244,7 @@ export class CssScanner {
}
scan(): LexedCssResult {
scan(): LexedCssResult|null {
const trackWS = _trackWhitespace(this._currentMode);
if (this.index == 0 && !trackWS) { // first scan
this.consumeWhitespace();
@ -253,7 +253,7 @@ export class CssScanner {
const token = this._scan();
if (token == null) return null;
const error = this._currentError;
const error = this._currentError !;
this._currentError = null;
if (!trackWS) {
@ -263,7 +263,7 @@ export class CssScanner {
}
/** @internal */
_scan(): CssToken {
_scan(): CssToken|null {
let peek = this.peek;
let peekPeek = this.peekPeek;
if (peek == chars.$EOF) return null;
@ -317,7 +317,7 @@ export class CssScanner {
return this.error(`Unexpected character [${String.fromCharCode(peek)}]`);
}
scanComment(): CssToken {
scanComment(): CssToken|null {
if (this.assertCondition(
isCommentStart(this.peek, this.peekPeek), 'Expected comment start value')) {
return null;
@ -355,7 +355,7 @@ export class CssScanner {
return new CssToken(start, startingColumn, startingLine, CssTokenType.Whitespace, str);
}
scanString(): CssToken {
scanString(): CssToken|null {
if (this.assertCondition(
isStringStart(this.peek, this.peekPeek), 'Unexpected non-string starting value')) {
return null;
@ -405,7 +405,7 @@ export class CssScanner {
return new CssToken(start, startingColumn, this.line, CssTokenType.Number, strValue);
}
scanIdentifier(): CssToken {
scanIdentifier(): CssToken|null {
if (this.assertCondition(
isIdentifierStart(this.peek, this.peekPeek), 'Expected identifier starting value')) {
return null;
@ -436,7 +436,7 @@ export class CssScanner {
return new CssToken(start, startingColumn, this.line, CssTokenType.Identifier, strValue);
}
scanCharacter(): CssToken {
scanCharacter(): CssToken|null {
const start = this.index;
const startingColumn = this.column;
if (this.assertCondition(
@ -451,7 +451,7 @@ export class CssScanner {
return new CssToken(start, startingColumn, this.line, CssTokenType.Character, c);
}
scanAtExpression(): CssToken {
scanAtExpression(): CssToken|null {
if (this.assertCondition(this.peek == chars.$AT, 'Expected @ value')) {
return null;
}
@ -460,7 +460,7 @@ export class CssScanner {
const startingColumn = this.column;
this.advance();
if (isIdentifierStart(this.peek, this.peekPeek)) {
const ident = this.scanIdentifier();
const ident = this.scanIdentifier() !;
const strValue = '@' + ident.strValue;
return new CssToken(start, startingColumn, this.line, CssTokenType.AtKeyword, strValue);
} else {
@ -476,7 +476,8 @@ export class CssScanner {
return false;
}
error(message: string, errorTokenValue: string = null, doNotAdvance: boolean = false): CssToken {
error(message: string, errorTokenValue: string|null = null, doNotAdvance: boolean = false):
CssToken {
const index: number = this.index;
const column: number = this.column;
const line: number = this.line;

View File

@ -102,8 +102,8 @@ export class CssParser {
this._errors = [];
const result = new ParsedCssResult(errors, ast);
this._file = null;
this._scanner = null;
this._file = null as any;
this._scanner = null as any;
return result;
}
@ -115,14 +115,14 @@ export class CssParser {
this._scanner.setMode(CssLexerMode.BLOCK);
results.push(this._parseRule(delimiters));
}
let span: ParseSourceSpan = null;
let span: ParseSourceSpan|null = null;
if (results.length > 0) {
const firstRule = results[0];
// we collect the last token like so incase there was an
// EOF token that was emitted sometime during the lexing
span = this._generateSourceSpan(firstRule, this._lastToken);
}
return new CssStyleSheetAst(span, results);
return new CssStyleSheetAst(span !, results);
}
/** @internal */
@ -134,7 +134,7 @@ export class CssParser {
}
/** @internal */
_generateSourceSpan(start: CssToken|CssAst, end: CssToken|CssAst = null): ParseSourceSpan {
_generateSourceSpan(start: CssToken|CssAst, end: CssToken|CssAst|null = null): ParseSourceSpan {
let startLoc: ParseLocation;
if (start instanceof CssAst) {
startLoc = start.location.start;
@ -152,13 +152,13 @@ export class CssParser {
end = this._lastToken;
}
let endLine: number;
let endColumn: number;
let endIndex: number;
let endLine: number = -1;
let endColumn: number = -1;
let endIndex: number = -1;
if (end instanceof CssAst) {
endLine = end.location.end.line;
endColumn = end.location.end.col;
endIndex = end.location.end.offset;
endLine = end.location.end.line !;
endColumn = end.location.end.col !;
endIndex = end.location.end.offset !;
} else if (end instanceof CssToken) {
endLine = end.line;
endColumn = end.column;
@ -250,7 +250,7 @@ export class CssParser {
case BlockType.Viewport:
case BlockType.FontFace:
block = this._parseStyleBlock(delimiters);
block = this._parseStyleBlock(delimiters) !;
span = this._generateSourceSpan(startToken, block);
return new CssBlockRuleAst(span, type, block);
@ -290,7 +290,7 @@ export class CssParser {
span = this._generateSourceSpan(startToken, tokens[tokens.length - 1]);
query = new CssAtRulePredicateAst(span, strValue, tokens);
block = this._parseBlock(delimiters);
strValue = this._extractSourceContent(start, block.end.offset);
strValue = this._extractSourceContent(start, block.end.offset !);
span = this._generateSourceSpan(startToken, block);
return new CssBlockDefinitionRuleAst(span, strValue, type, query, block);
@ -373,7 +373,7 @@ export class CssParser {
/** @internal */
_scan(): CssToken {
const output = this._scanner.scan();
const output = this._scanner.scan() !;
const token = output.token;
const error = output.error;
if (error != null) {
@ -387,7 +387,7 @@ export class CssParser {
_getScannerIndex(): number { return this._scanner.index; }
/** @internal */
_consume(type: CssTokenType, value: string = null): CssToken {
_consume(type: CssTokenType, value: string|null = null): CssToken {
const output = this._scanner.consume(type, value);
const token = output.token;
const error = output.error;
@ -429,7 +429,7 @@ export class CssParser {
}
const stylesBlock = this._parseStyleBlock(delimiters | RBRACE_DELIM_FLAG);
const span = this._generateSourceSpan(stepTokens[0], stylesBlock);
const ast = new CssKeyframeDefinitionAst(span, stepTokens, stylesBlock);
const ast = new CssKeyframeDefinitionAst(span, stepTokens, stylesBlock !);
this._scanner.setMode(CssLexerMode.BLOCK);
return ast;
@ -520,7 +520,7 @@ export class CssParser {
const selectorCssTokens: CssToken[] = [];
const pseudoSelectors: CssPseudoSelectorAst[] = [];
let previousToken: CssToken;
let previousToken: CssToken = undefined !;
const selectorPartDelimiters = delimiters | SPACE_DELIM_FLAG;
let loopOverSelector = !characterContainsDelimiter(this._scanner.peek, selectorPartDelimiters);
@ -581,9 +581,9 @@ export class CssParser {
// this happens if the selector is not directly followed by
// a comma or curly brace without a space in between
let operator: CssToken = null;
let operator: CssToken|null = null;
let operatorScanCount = 0;
let lastOperatorToken: CssToken = null;
let lastOperatorToken: CssToken|null = null;
if (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
while (operator == null && !characterContainsDelimiter(this._scanner.peek, delimiters) &&
isSelectorOperatorCharacter(this._scanner.peek)) {
@ -653,8 +653,8 @@ export class CssParser {
// please note that `endToken` is reassigned multiple times below
// so please do not optimize the if statements into if/elseif
let startTokenOrAst: CssToken|CssAst = null;
let endTokenOrAst: CssToken|CssAst = null;
let startTokenOrAst: CssToken|CssAst|null = null;
let endTokenOrAst: CssToken|CssAst|null = null;
if (selectorCssTokens.length > 0) {
startTokenOrAst = startTokenOrAst || selectorCssTokens[0];
endTokenOrAst = selectorCssTokens[selectorCssTokens.length - 1];
@ -668,8 +668,8 @@ export class CssParser {
endTokenOrAst = operator;
}
const span = this._generateSourceSpan(startTokenOrAst, endTokenOrAst);
return new CssSimpleSelectorAst(span, selectorCssTokens, strValue, pseudoSelectors, operator);
const span = this._generateSourceSpan(startTokenOrAst !, endTokenOrAst);
return new CssSimpleSelectorAst(span, selectorCssTokens, strValue, pseudoSelectors, operator !);
}
/** @internal */
@ -698,7 +698,7 @@ export class CssParser {
const tokens: CssToken[] = [];
let wsStr = '';
let previous: CssToken;
let previous: CssToken = undefined !;
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
let token: CssToken;
if (previous != null && previous.type == CssTokenType.Identifier &&
@ -749,7 +749,7 @@ export class CssParser {
}
/** @internal */
_collectUntilDelim(delimiters: number, assertType: CssTokenType = null): CssToken[] {
_collectUntilDelim(delimiters: number, assertType: CssTokenType|null = null): CssToken[] {
const tokens: CssToken[] = [];
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
const val = assertType != null ? this._consume(assertType) : this._scan();
@ -782,7 +782,7 @@ export class CssParser {
}
/** @internal */
_parseStyleBlock(delimiters: number): CssStylesBlockAst {
_parseStyleBlock(delimiters: number): CssStylesBlockAst|null {
delimiters |= RBRACE_DELIM_FLAG | LBRACE_DELIM_FLAG;
this._scanner.setMode(CssLexerMode.STYLE_BLOCK);
@ -815,7 +815,7 @@ export class CssParser {
let prop = this._consume(CssTokenType.Identifier);
let parseValue: boolean = false;
let value: CssStyleValueAst = null;
let value: CssStyleValueAst|null = null;
let endToken: CssToken|CssStyleValueAst = prop;
// the colon value separates the prop from the style.
@ -865,7 +865,7 @@ export class CssParser {
}
const span = this._generateSourceSpan(prop, endToken);
return new CssDefinitionAst(span, prop, value);
return new CssDefinitionAst(span, prop, value !);
}
/** @internal */

View File

@ -7,6 +7,7 @@
*/
import {ViewEncapsulation, ɵstringify as stringify} from '@angular/core';
import {CompileAnimationEntryMetadata, CompileDirectiveMetadata, CompileStylesheetMetadata, CompileTemplateMetadata, templateSourceUrl} from './compile_metadata';
import {CompilerConfig} from './config';
import {CompilerInjectable} from './injectable';
@ -17,19 +18,19 @@ import {ResourceLoader} from './resource_loader';
import {extractStyleUrls, isStyleUrlResolvable} from './style_url_resolver';
import {PreparsedElementType, preparseElement} from './template_parser/template_preparser';
import {UrlResolver} from './url_resolver';
import {SyncAsyncResult, syntaxError} from './util';
import {SyncAsyncResult, isDefined, syntaxError} from './util';
export interface PrenormalizedTemplateMetadata {
ngModuleType: any;
componentType: any;
moduleUrl: string;
template?: string;
templateUrl?: string;
styles?: string[];
styleUrls?: string[];
interpolation?: [string, string];
encapsulation?: ViewEncapsulation;
animations?: CompileAnimationEntryMetadata[];
template: string|null;
templateUrl: string|null;
styles: string[];
styleUrls: string[];
interpolation: [string, string]|null;
encapsulation: ViewEncapsulation|null;
animations: CompileAnimationEntryMetadata[];
}
@CompilerInjectable()
@ -46,15 +47,16 @@ export class DirectiveNormalizer {
if (!normalizedDirective.isComponent) {
return;
}
this._resourceLoaderCache.delete(normalizedDirective.template.templateUrl);
normalizedDirective.template.externalStylesheets.forEach(
(stylesheet) => { this._resourceLoaderCache.delete(stylesheet.moduleUrl); });
const template = normalizedDirective.template !;
this._resourceLoaderCache.delete(template.templateUrl !);
template.externalStylesheets.forEach(
(stylesheet) => { this._resourceLoaderCache.delete(stylesheet.moduleUrl !); });
}
private _fetch(url: string): Promise<string> {
let result = this._resourceLoaderCache.get(url);
if (!result) {
result = this._resourceLoader.get(url);
result = this._resourceLoader.get(url) !;
this._resourceLoaderCache.set(url, result);
}
return result;
@ -62,10 +64,10 @@ export class DirectiveNormalizer {
normalizeTemplate(prenormData: PrenormalizedTemplateMetadata):
SyncAsyncResult<CompileTemplateMetadata> {
let normalizedTemplateSync: CompileTemplateMetadata = null;
let normalizedTemplateAsync: Promise<CompileTemplateMetadata>;
if (prenormData.template != null) {
if (prenormData.templateUrl != null) {
let normalizedTemplateSync: CompileTemplateMetadata = null !;
let normalizedTemplateAsync: Promise<CompileTemplateMetadata> = undefined !;
if (isDefined(prenormData.template)) {
if (isDefined(prenormData.templateUrl)) {
throw syntaxError(
`'${stringify(prenormData.componentType)}' component cannot define both template and templateUrl`);
}
@ -74,8 +76,8 @@ export class DirectiveNormalizer {
`The template specified for component ${stringify(prenormData.componentType)} is not a string`);
}
normalizedTemplateSync = this.normalizeTemplateSync(prenormData);
normalizedTemplateAsync = Promise.resolve(normalizedTemplateSync);
} else if (prenormData.templateUrl) {
normalizedTemplateAsync = Promise.resolve(normalizedTemplateSync !);
} else if (isDefined(prenormData.templateUrl)) {
if (typeof prenormData.templateUrl !== 'string') {
throw syntaxError(
`The templateUrl specified for component ${stringify(prenormData.componentType)} is not a string`);
@ -98,12 +100,12 @@ export class DirectiveNormalizer {
}
normalizeTemplateSync(prenomData: PrenormalizedTemplateMetadata): CompileTemplateMetadata {
return this.normalizeLoadedTemplate(prenomData, prenomData.template, prenomData.moduleUrl);
return this.normalizeLoadedTemplate(prenomData, prenomData.template !, prenomData.moduleUrl);
}
normalizeTemplateAsync(prenomData: PrenormalizedTemplateMetadata):
Promise<CompileTemplateMetadata> {
const templateUrl = this._urlResolver.resolve(prenomData.moduleUrl, prenomData.templateUrl);
const templateUrl = this._urlResolver.resolve(prenomData.moduleUrl, prenomData.templateUrl !);
return this._fetch(templateUrl)
.then((value) => this.normalizeLoadedTemplate(prenomData, value, templateUrl));
}
@ -112,7 +114,7 @@ export class DirectiveNormalizer {
prenormData: PrenormalizedTemplateMetadata, template: string,
templateAbsUrl: string): CompileTemplateMetadata {
const isInline = !!prenormData.template;
const interpolationConfig = InterpolationConfig.fromArray(prenormData.interpolation);
const interpolationConfig = InterpolationConfig.fromArray(prenormData.interpolation !);
const rootNodesAndErrors = this._htmlParser.parse(
template,
templateSourceUrl(
@ -154,7 +156,8 @@ export class DirectiveNormalizer {
templateUrl: templateAbsUrl, styles, styleUrls,
ngContentSelectors: visitor.ngContentSelectors,
animations: prenormData.animations,
interpolation: prenormData.interpolation, isInline
interpolation: prenormData.interpolation, isInline,
externalStylesheets: []
});
}
@ -193,17 +196,18 @@ export class DirectiveNormalizer {
}
normalizeStylesheet(stylesheet: CompileStylesheetMetadata): CompileStylesheetMetadata {
const moduleUrl = stylesheet.moduleUrl !;
const allStyleUrls = stylesheet.styleUrls.filter(isStyleUrlResolvable)
.map(url => this._urlResolver.resolve(stylesheet.moduleUrl, url));
.map(url => this._urlResolver.resolve(moduleUrl, url));
const allStyles = stylesheet.styles.map(style => {
const styleWithImports = extractStyleUrls(this._urlResolver, stylesheet.moduleUrl, style);
const styleWithImports = extractStyleUrls(this._urlResolver, moduleUrl, style);
allStyleUrls.push(...styleWithImports.styleUrls);
return styleWithImports.style;
});
return new CompileStylesheetMetadata(
{styles: allStyles, styleUrls: allStyleUrls, moduleUrl: stylesheet.moduleUrl});
{styles: allStyles, styleUrls: allStyleUrls, moduleUrl: moduleUrl});
}
}

View File

@ -30,7 +30,10 @@ export class DirectiveResolver {
/**
* Return {@link Directive} for a given `Type`.
*/
resolve(type: Type<any>, throwIfNotFound = true): Directive {
resolve(type: Type<any>): Directive;
resolve(type: Type<any>, throwIfNotFound: true): Directive;
resolve(type: Type<any>, throwIfNotFound: boolean): Directive|null;
resolve(type: Type<any>, throwIfNotFound = true): Directive|null {
const typeMetadata = this._reflector.annotations(resolveForwardRef(type));
if (typeMetadata) {
const metadata = findLast(typeMetadata, isDirectiveMetadata);
@ -100,7 +103,7 @@ export class DirectiveResolver {
return this._merge(dm, inputs, outputs, host, queries, directiveType);
}
private _extractPublicName(def: string) { return splitAtColon(def, [null, def])[1].trim(); }
private _extractPublicName(def: string) { return splitAtColon(def, [null !, def])[1].trim(); }
private _dedupeBindings(bindings: string[]): string[] {
const names = new Set<string>();
@ -166,7 +169,7 @@ function isDirectiveMetadata(type: any): type is Directive {
return type instanceof Directive;
}
export function findLast<T>(arr: T[], condition: (value: T) => boolean): T {
export function findLast<T>(arr: T[], condition: (value: T) => boolean): T|null {
for (let i = arr.length - 1; i >= 0; i--) {
if (condition(arr[i])) {
return arr[i];

View File

@ -185,7 +185,7 @@ export class SafeMethodCall extends AST {
}
export class FunctionCall extends AST {
constructor(span: ParseSpan, public target: AST, public args: any[]) { super(span); }
constructor(span: ParseSpan, public target: AST|null, public args: any[]) { super(span); }
visit(visitor: AstVisitor, context: any = null): any {
return visitor.visitFunctionCall(this, context);
}
@ -193,7 +193,7 @@ export class FunctionCall extends AST {
export class ASTWithSource extends AST {
constructor(
public ast: AST, public source: string, public location: string,
public ast: AST, public source: string|null, public location: string,
public errors: ParserError[]) {
super(new ParseSpan(0, source == null ? 0 : source.length));
}
@ -248,7 +248,7 @@ export class RecursiveAstVisitor implements AstVisitor {
return null;
}
visitFunctionCall(ast: FunctionCall, context: any): any {
ast.target.visit(this);
ast.target !.visit(this);
this.visitAll(ast.args, context);
return null;
}
@ -337,7 +337,7 @@ export class AstTransformer implements AstVisitor {
}
visitFunctionCall(ast: FunctionCall, context: any): AST {
return new FunctionCall(ast.span, ast.target.visit(this), this.visitAll(ast.args));
return new FunctionCall(ast.span, ast.target !.visit(this), this.visitAll(ast.args));
}
visitLiteralArray(ast: LiteralArray, context: any): AST {

View File

@ -76,7 +76,7 @@ export class Token {
toNumber(): number { return this.type == TokenType.Number ? this.numValue : -1; }
toString(): string {
toString(): string|null {
switch (this.type) {
case TokenType.Character:
case TokenType.Identifier:
@ -137,7 +137,7 @@ class _Scanner {
this.peek = ++this.index >= this.length ? chars.$EOF : this.input.charCodeAt(this.index);
}
scanToken(): Token {
scanToken(): Token|null {
const input = this.input, length = this.length;
let peek = this.peek, index = this.index;

View File

@ -90,7 +90,7 @@ export class Parser {
.parseChain();
}
private _parseQuote(input: string, location: any): AST {
private _parseQuote(input: string|null, location: any): AST|null {
if (input == null) return null;
const prefixSeparatorIndex = input.indexOf(':');
if (prefixSeparatorIndex == -1) return null;
@ -100,7 +100,7 @@ export class Parser {
return new Quote(new ParseSpan(0, input.length), prefix, uninterpretedExpression, location);
}
parseTemplateBindings(prefixToken: string, input: string, location: any):
parseTemplateBindings(prefixToken: string|null, input: string, location: any):
TemplateBindingParseResult {
const tokens = this._lexer.tokenize(input);
if (prefixToken) {
@ -117,7 +117,7 @@ export class Parser {
parseInterpolation(
input: string, location: any,
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG): ASTWithSource {
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG): ASTWithSource|null {
const split = this.splitInterpolation(input, location, interpolationConfig);
if (split == null) return null;
@ -142,7 +142,8 @@ export class Parser {
splitInterpolation(
input: string, location: string,
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG): SplitInterpolation {
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG): SplitInterpolation
|null {
const regexp = _createInterpolateRegExp(interpolationConfig);
const parts = input.split(regexp);
if (parts.length <= 1) {
@ -175,7 +176,7 @@ export class Parser {
return new SplitInterpolation(strings, expressions, offsets);
}
wrapLiteralPrimitive(input: string, location: any): ASTWithSource {
wrapLiteralPrimitive(input: string|null, location: any): ASTWithSource {
return new ASTWithSource(
new LiteralPrimitive(new ParseSpan(0, input == null ? 0 : input.length), input), input,
location, this.errors);
@ -186,8 +187,8 @@ export class Parser {
return i != null ? input.substring(0, i).trim() : input;
}
private _commentStart(input: string): number {
let outerQuote: number = null;
private _commentStart(input: string): number|null {
let outerQuote: number|null = null;
for (let i = 0; i < input.length - 1; i++) {
const char = input.charCodeAt(i);
const nextChar = input.charCodeAt(i + 1);
@ -288,7 +289,7 @@ export class _ParseAST {
this.error(`Missing expected operator ${operator}`);
}
expectIdentifierOrKeyword(): string {
expectIdentifierOrKeyword(): string|null {
const n = this.next;
if (!n.isIdentifier() && !n.isKeyword()) {
this.error(`Unexpected token ${n}, expected identifier or keyword`);
@ -298,7 +299,7 @@ export class _ParseAST {
return n.toString();
}
expectIdentifierOrKeywordOrString(): string {
expectIdentifierOrKeywordOrString(): string|null {
const n = this.next;
if (!n.isIdentifier() && !n.isKeyword() && !n.isString()) {
this.error(`Unexpected token ${n}, expected identifier, keyword, or string`);
@ -338,7 +339,7 @@ export class _ParseAST {
}
do {
const name = this.expectIdentifierOrKeyword();
const name = this.expectIdentifierOrKeyword() !;
const args: AST[] = [];
while (this.optionalCharacter(chars.$COLON)) {
args.push(this.parseExpression());
@ -607,7 +608,7 @@ export class _ParseAST {
if (!this.optionalCharacter(chars.$RBRACE)) {
this.rbracesExpected++;
do {
const key = this.expectIdentifierOrKeywordOrString();
const key = this.expectIdentifierOrKeywordOrString() !;
keys.push(key);
this.expectCharacter(chars.$COLON);
values.push(this.parsePipe());
@ -620,7 +621,7 @@ export class _ParseAST {
parseAccessMemberOrMethodCall(receiver: AST, isSafe: boolean = false): AST {
const start = receiver.span.start;
const id = this.expectIdentifierOrKeyword();
const id = this.expectIdentifierOrKeyword() !;
if (this.optionalCharacter(chars.$LPAREN)) {
this.rparensExpected++;
@ -683,7 +684,7 @@ export class _ParseAST {
parseTemplateBindings(): TemplateBindingParseResult {
const bindings: TemplateBinding[] = [];
let prefix: string = null;
let prefix: string = null !;
const warnings: string[] = [];
while (this.index < this.tokens.length) {
const start = this.inputIndex;
@ -701,8 +702,8 @@ export class _ParseAST {
}
}
this.optionalCharacter(chars.$COLON);
let name: string = null;
let expression: ASTWithSource = null;
let name: string = null !;
let expression: ASTWithSource = null !;
if (keyIsVar) {
if (this.optionalOperator('=')) {
name = this.expectTemplateBindingKey();
@ -726,7 +727,7 @@ export class _ParseAST {
const letStart = this.inputIndex;
this.advance(); // consume `as`
const letName = this.expectTemplateBindingKey(); // read local var name
bindings.push(new TemplateBinding(this.span(letStart), letName, true, key, null));
bindings.push(new TemplateBinding(this.span(letStart), letName, true, key, null !));
}
if (!this.optionalCharacter(chars.$SEMICOLON)) {
this.optionalCharacter(chars.$COMMA);
@ -735,12 +736,12 @@ export class _ParseAST {
return new TemplateBindingParseResult(bindings, warnings, this.errors);
}
error(message: string, index: number = null) {
error(message: string, index: number|null = null) {
this.errors.push(new ParserError(message, this.input, this.locationText(index), this.location));
this.skip();
}
private locationText(index: number = null) {
private locationText(index: number|null = null) {
if (index == null) index = this.index;
return (index < this.tokens.length) ? `at column ${this.tokens[index].index + 1} in` :
`at the end of the expression`;
@ -766,8 +767,8 @@ export class _ParseAST {
(this.rbracesExpected <= 0 || !n.isCharacter(chars.$RBRACE)) &&
(this.rbracketsExpected <= 0 || !n.isCharacter(chars.$RBRACKET))) {
if (this.next.isError()) {
this.errors.push(
new ParserError(this.next.toString(), this.input, this.locationText(), this.location));
this.errors.push(new ParserError(
this.next.toString() !, this.input, this.locationText(), this.location));
}
this.advance();
n = this.next;

View File

@ -70,11 +70,11 @@ export class Extractor {
}
});
compMetas.forEach(compMeta => {
const html = compMeta.template.template;
const html = compMeta.template !.template !;
const interpolationConfig =
InterpolationConfig.fromArray(compMeta.template.interpolation);
errors.push(
...this.messageBundle.updateFromTemplate(html, file.srcUrl, interpolationConfig));
InterpolationConfig.fromArray(compMeta.template !.interpolation);
errors.push(...this.messageBundle.updateFromTemplate(
html, file.srcUrl, interpolationConfig) !);
});
});

View File

@ -71,7 +71,7 @@ class _Visitor implements html.Visitor {
private _inIcu: boolean;
// set to void 0 when not in a section
private _msgCountAtSectionStart: number;
private _msgCountAtSectionStart: number|undefined;
private _errors: I18nError[];
private _mode: _VisitorMode;
@ -111,7 +111,7 @@ class _Visitor implements html.Visitor {
this._translations = translations;
// Construct a single fake root element
const wrapper = new html.Element('wrapper', [], nodes, null, null, null);
const wrapper = new html.Element('wrapper', [], nodes, undefined, undefined, undefined);
const translatedNode = wrapper.visit(this, null);
@ -179,7 +179,8 @@ class _Visitor implements html.Visitor {
this._inI18nBlock = true;
this._blockStartDepth = this._depth;
this._blockChildren = [];
this._blockMeaningAndDesc = comment.value.replace(_I18N_COMMENT_PREFIX_REGEXP, '').trim();
this._blockMeaningAndDesc =
comment.value !.replace(_I18N_COMMENT_PREFIX_REGEXP, '').trim();
this._openTranslatableSection(comment);
}
} else {
@ -187,7 +188,7 @@ class _Visitor implements html.Visitor {
if (this._depth == this._blockStartDepth) {
this._closeTranslatableSection(comment, this._blockChildren);
this._inI18nBlock = false;
const message = this._addMessage(this._blockChildren, this._blockMeaningAndDesc);
const message = this._addMessage(this._blockChildren, this._blockMeaningAndDesc) !;
// merge attributes in sections
const nodes = this._translateMessage(comment, message);
return html.visitAll(this, nodes);
@ -207,13 +208,13 @@ class _Visitor implements html.Visitor {
return text;
}
visitElement(el: html.Element, context: any): html.Element {
visitElement(el: html.Element, context: any): html.Element|null {
this._mayBeAddBlockChildren(el);
this._depth++;
const wasInI18nNode = this._inI18nNode;
const wasInImplicitNode = this._inImplicitNode;
let childNodes: html.Node[] = [];
let translatedChildNodes: html.Node[];
let translatedChildNodes: html.Node[] = undefined !;
// Extract:
// - top level nodes with the (implicit) "i18n" attribute if not already in a section
@ -228,7 +229,7 @@ class _Visitor implements html.Visitor {
if (!this._isInTranslatableSection && !this._inIcu) {
if (i18nAttr || isTopLevelImplicit) {
this._inI18nNode = true;
const message = this._addMessage(el.children, i18nMeta);
const message = this._addMessage(el.children, i18nMeta) !;
translatedChildNodes = this._translateMessage(el, message);
}
@ -274,6 +275,7 @@ class _Visitor implements html.Visitor {
el.name, translatedAttrs, childNodes, el.sourceSpan, el.startSourceSpan,
el.endSourceSpan);
}
return null;
}
visitAttribute(attribute: html.Attribute, context: any): any {
@ -286,7 +288,7 @@ class _Visitor implements html.Visitor {
this._inI18nNode = false;
this._depth = 0;
this._inIcu = false;
this._msgCountAtSectionStart = void 0;
this._msgCountAtSectionStart = undefined;
this._errors = [];
this._messages = [];
this._inImplicitNode = false;
@ -313,11 +315,11 @@ class _Visitor implements html.Visitor {
}
// add a translatable message
private _addMessage(ast: html.Node[], msgMeta?: string): i18n.Message {
private _addMessage(ast: html.Node[], msgMeta?: string): i18n.Message|null {
if (ast.length == 0 ||
ast.length == 1 && ast[0] instanceof html.Attribute && !(<html.Attribute>ast[0]).value) {
// Do not create empty messages
return;
return null;
}
const {meaning, description, id} = _parseMessageMeta(msgMeta);
@ -463,27 +465,27 @@ class _Visitor implements html.Visitor {
}
}
this._msgCountAtSectionStart = void 0;
this._msgCountAtSectionStart = undefined;
}
private _reportError(node: html.Node, msg: string): void {
this._errors.push(new I18nError(node.sourceSpan, msg));
this._errors.push(new I18nError(node.sourceSpan !, msg));
}
}
function _isOpeningComment(n: html.Node): boolean {
return n instanceof html.Comment && n.value && n.value.startsWith('i18n');
return !!(n instanceof html.Comment && n.value && n.value.startsWith('i18n'));
}
function _isClosingComment(n: html.Node): boolean {
return n instanceof html.Comment && n.value && n.value === '/i18n';
return !!(n instanceof html.Comment && n.value && n.value === '/i18n');
}
function _getI18nAttr(p: html.Element): html.Attribute {
function _getI18nAttr(p: html.Element): html.Attribute|null {
return p.attrs.find(attr => attr.name === _I18N_ATTR) || null;
}
function _parseMessageMeta(i18n: string): {meaning: string, description: string, id: string} {
function _parseMessageMeta(i18n?: string): {meaning: string, description: string, id: string} {
if (!i18n) return {meaning: '', description: '', id: ''};
const idIndex = i18n.indexOf(ID_SEPARATOR);

View File

@ -65,7 +65,7 @@ class _I18nVisitor implements html.Visitor {
const isVoid: boolean = getHtmlTagDefinition(el.name).isVoid;
const startPhName =
this._placeholderRegistry.getStartTagPlaceholderName(el.name, attrs, isVoid);
this._placeholderToContent[startPhName] = el.sourceSpan.toString();
this._placeholderToContent[startPhName] = el.sourceSpan !.toString();
let closePhName = '';
@ -75,7 +75,7 @@ class _I18nVisitor implements html.Visitor {
}
return new i18n.TagPlaceholder(
el.name, attrs, startPhName, closePhName, children, isVoid, el.sourceSpan);
el.name, attrs, startPhName, closePhName, children, isVoid, el.sourceSpan !);
}
visitAttribute(attribute: html.Attribute, context: any): i18n.Node {
@ -83,10 +83,10 @@ class _I18nVisitor implements html.Visitor {
}
visitText(text: html.Text, context: any): i18n.Node {
return this._visitTextWithInterpolation(text.value, text.sourceSpan);
return this._visitTextWithInterpolation(text.value, text.sourceSpan !);
}
visitComment(comment: html.Comment, context: any): i18n.Node { return null; }
visitComment(comment: html.Comment, context: any): i18n.Node|null { return null; }
visitExpansion(icu: html.Expansion, context: any): i18n.Node {
this._icuDepth++;

View File

@ -26,7 +26,7 @@ export class MessageBundle {
private _implicitAttrs: {[k: string]: string[]}, private _locale: string|null = null) {}
updateFromTemplate(html: string, url: string, interpolationConfig: InterpolationConfig):
ParseError[] {
ParseError[]|null {
const htmlParserResult = this._htmlParser.parse(html, url, true, interpolationConfig);
if (htmlParserResult.errors.length) {
@ -41,6 +41,7 @@ export class MessageBundle {
}
this._messages.push(...i18nParserResult.messages);
return null;
}
// Return the message in the internal format
@ -78,18 +79,18 @@ class MapPlaceholderNames extends i18n.CloneVisitor {
}
visitTagPlaceholder(ph: i18n.TagPlaceholder, mapper: PlaceholderMapper): i18n.TagPlaceholder {
const startName = mapper.toPublicName(ph.startName);
const closeName = ph.closeName ? mapper.toPublicName(ph.closeName) : ph.closeName;
const startName = mapper.toPublicName(ph.startName) !;
const closeName = ph.closeName ? mapper.toPublicName(ph.closeName) ! : ph.closeName;
const children = ph.children.map(n => n.visit(this, mapper));
return new i18n.TagPlaceholder(
ph.tag, ph.attrs, startName, closeName, children, ph.isVoid, ph.sourceSpan);
}
visitPlaceholder(ph: i18n.Placeholder, mapper: PlaceholderMapper): i18n.Placeholder {
return new i18n.Placeholder(ph.value, mapper.toPublicName(ph.name), ph.sourceSpan);
return new i18n.Placeholder(ph.value, mapper.toPublicName(ph.name) !, ph.sourceSpan);
}
visitIcuPlaceholder(ph: i18n.IcuPlaceholder, mapper: PlaceholderMapper): i18n.IcuPlaceholder {
return new i18n.IcuPlaceholder(ph.value, mapper.toPublicName(ph.name), ph.sourceSpan);
return new i18n.IcuPlaceholder(ph.value, mapper.toPublicName(ph.name) !, ph.sourceSpan);
}
}

View File

@ -21,7 +21,7 @@ export abstract class Serializer {
// Creates a name mapper, see `PlaceholderMapper`
// Returning `null` means that no name mapping is used.
createNameMapper(message: i18n.Message): PlaceholderMapper { return null; }
createNameMapper(message: i18n.Message): PlaceholderMapper|null { return null; }
}
/**
@ -31,9 +31,9 @@ export abstract class Serializer {
* It should be used for serialization format that put constraints on the placeholder names.
*/
export interface PlaceholderMapper {
toPublicName(internalName: string): string;
toPublicName(internalName: string): string|null;
toInternalName(publicName: string): string;
toInternalName(publicName: string): string|null;
}
/**
@ -50,13 +50,13 @@ export class SimplePlaceholderMapper extends i18n.RecurseVisitor implements Plac
message.nodes.forEach(node => node.visit(this));
}
toPublicName(internalName: string): string {
toPublicName(internalName: string): string|null {
return this.internalToPublic.hasOwnProperty(internalName) ?
this.internalToPublic[internalName] :
null;
}
toInternalName(publicName: string): string {
toInternalName(publicName: string): string|null {
return this.publicToInternal.hasOwnProperty(publicName) ? this.publicToInternal[publicName] :
null;
}

View File

@ -93,7 +93,7 @@ export class Xliff extends Serializer {
throw new Error(`xliff parse errors:\n${errors.join('\n')}`);
}
return {locale, i18nNodesByMsgId};
return {locale: locale !, i18nNodesByMsgId};
}
digest(message: i18n.Message): string { return digest(message); }
@ -150,7 +150,7 @@ class _WriteVisitor implements i18n.Visitor {
// TODO(vicb): add error management (structure)
// Extract messages as xml nodes from the xliff file
class XliffParser implements ml.Visitor {
private _unitMlString: string;
private _unitMlString: string|null;
private _errors: I18nError[];
private _msgIdToHtml: {[msgId: string]: string};
private _locale: string|null = null;
@ -174,7 +174,7 @@ class XliffParser implements ml.Visitor {
visitElement(element: ml.Element, context: any): any {
switch (element.name) {
case _UNIT_TAG:
this._unitMlString = null;
this._unitMlString = null !;
const idAttr = element.attrs.find((attr) => attr.name === 'id');
if (!idAttr) {
this._addError(element, `<${_UNIT_TAG}> misses the "id" attribute`);
@ -198,9 +198,9 @@ class XliffParser implements ml.Visitor {
break;
case _TARGET_TAG:
const innerTextStart = element.startSourceSpan.end.offset;
const innerTextEnd = element.endSourceSpan.start.offset;
const content = element.startSourceSpan.start.file.content;
const innerTextStart = element.startSourceSpan !.end.offset;
const innerTextEnd = element.endSourceSpan !.start.offset;
const content = element.startSourceSpan !.start.file.content;
const innerText = content.slice(innerTextStart, innerTextEnd);
this._unitMlString = innerText;
break;
@ -231,7 +231,7 @@ class XliffParser implements ml.Visitor {
visitExpansionCase(expansionCase: ml.ExpansionCase, context: any): any {}
private _addError(node: ml.Node, message: string): void {
this._errors.push(new I18nError(node.sourceSpan, message));
this._errors.push(new I18nError(node.sourceSpan !, message));
}
}
@ -253,19 +253,20 @@ class XmlToI18n implements ml.Visitor {
};
}
visitText(text: ml.Text, context: any) { return new i18n.Text(text.value, text.sourceSpan); }
visitText(text: ml.Text, context: any) { return new i18n.Text(text.value, text.sourceSpan !); }
visitElement(el: ml.Element, context: any): i18n.Placeholder {
visitElement(el: ml.Element, context: any): i18n.Placeholder|null {
if (el.name === _PLACEHOLDER_TAG) {
const nameAttr = el.attrs.find((attr) => attr.name === 'id');
if (nameAttr) {
return new i18n.Placeholder('', nameAttr.value, el.sourceSpan);
return new i18n.Placeholder('', nameAttr.value, el.sourceSpan !);
}
this._addError(el, `<${_PLACEHOLDER_TAG}> misses the "id" attribute`);
} else {
this._addError(el, `Unexpected tag`);
}
return null;
}
visitExpansion(icu: ml.Expansion, context: any) {
@ -290,7 +291,7 @@ class XmlToI18n implements ml.Visitor {
visitAttribute(attribute: ml.Attribute, context: any) {}
private _addError(node: ml.Node, message: string): void {
this._errors.push(new I18nError(node.sourceSpan, message));
this._errors.push(new I18nError(node.sourceSpan !, message));
}
}

View File

@ -49,7 +49,7 @@ export class Xtb extends Serializer {
throw new Error(`xtb parse errors:\n${errors.join('\n')}`);
}
return {locale, i18nNodesByMsgId};
return {locale: locale !, i18nNodesByMsgId};
}
digest(message: i18n.Message): string { return digest(message); }
@ -121,10 +121,10 @@ class XtbParser implements ml.Visitor {
if (this._msgIdToHtml.hasOwnProperty(id)) {
this._addError(element, `Duplicated translations for msg ${id}`);
} else {
const innerTextStart = element.startSourceSpan.end.offset;
const innerTextEnd = element.endSourceSpan.start.offset;
const content = element.startSourceSpan.start.file.content;
const innerText = content.slice(innerTextStart, innerTextEnd);
const innerTextStart = element.startSourceSpan !.end.offset;
const innerTextEnd = element.endSourceSpan !.start.offset;
const content = element.startSourceSpan !.start.file.content;
const innerText = content.slice(innerTextStart !, innerTextEnd !);
this._msgIdToHtml[id] = innerText;
}
}
@ -146,7 +146,7 @@ class XtbParser implements ml.Visitor {
visitExpansionCase(expansionCase: ml.ExpansionCase, context: any): any {}
private _addError(node: ml.Node, message: string): void {
this._errors.push(new I18nError(node.sourceSpan, message));
this._errors.push(new I18nError(node.sourceSpan !, message));
}
}
@ -168,7 +168,7 @@ class XmlToI18n implements ml.Visitor {
};
}
visitText(text: ml.Text, context: any) { return new i18n.Text(text.value, text.sourceSpan); }
visitText(text: ml.Text, context: any) { return new i18n.Text(text.value, text.sourceSpan !); }
visitExpansion(icu: ml.Expansion, context: any) {
const caseMap: {[value: string]: i18n.Node} = {};
@ -187,17 +187,18 @@ class XmlToI18n implements ml.Visitor {
};
}
visitElement(el: ml.Element, context: any): i18n.Placeholder {
visitElement(el: ml.Element, context: any): i18n.Placeholder|null {
if (el.name === _PLACEHOLDER_TAG) {
const nameAttr = el.attrs.find((attr) => attr.name === 'name');
if (nameAttr) {
return new i18n.Placeholder('', nameAttr.value, el.sourceSpan);
return new i18n.Placeholder('', nameAttr.value, el.sourceSpan !);
}
this._addError(el, `<${_PLACEHOLDER_TAG}> misses the "name" attribute`);
} else {
this._addError(el, `Unexpected tag`);
}
return null;
}
visitComment(comment: ml.Comment, context: any) {}
@ -205,6 +206,6 @@ class XmlToI18n implements ml.Visitor {
visitAttribute(attribute: ml.Attribute, context: any) {}
private _addError(node: ml.Node, message: string): void {
this._errors.push(new I18nError(node.sourceSpan, message));
this._errors.push(new I18nError(node.sourceSpan !, message));
}
}

View File

@ -26,7 +26,7 @@ export class TranslationBundle {
missingTranslationStrategy: MissingTranslationStrategy = MissingTranslationStrategy.Warning,
console?: Console) {
this._i18nToHtml = new I18nToHtmlVisitor(
_i18nNodesByMsgId, locale, digest, mapperFactory, missingTranslationStrategy, console);
_i18nNodesByMsgId, locale, digest, mapperFactory !, missingTranslationStrategy, console);
}
// Creates a `TranslationBundle` by parsing the given `content` with the `serializer`.
@ -36,7 +36,7 @@ export class TranslationBundle {
console?: Console): TranslationBundle {
const {locale, i18nNodesByMsgId} = serializer.load(content, url);
const digestFn = (m: i18n.Message) => serializer.digest(m);
const mapperFactory = (m: i18n.Message) => serializer.createNameMapper(m);
const mapperFactory = (m: i18n.Message) => serializer.createNameMapper(m) !;
return new TranslationBundle(
i18nNodesByMsgId, locale, digestFn, mapperFactory, missingTranslationStrategy, console);
}
@ -156,7 +156,7 @@ class I18nToHtmlVisitor implements i18n.Visitor {
// When there is a translation use its nodes as the source
// And create a mapper to convert serialized placeholder names to internal names
nodes = this._i18nNodesByMsgId[id];
this._mapper = (name: string) => mapper ? mapper.toInternalName(name) : name;
this._mapper = (name: string) => mapper ? mapper.toInternalName(name) ! : name;
} else {
// When no translation has been found
// - report an error / a warning / nothing,
@ -175,7 +175,7 @@ class I18nToHtmlVisitor implements i18n.Visitor {
this._mapper = (name: string) => name;
}
const text = nodes.map(node => node.visit(this)).join('');
const context = this._contextStack.pop();
const context = this._contextStack.pop() !;
this._srcMsg = context.msg;
this._mapper = context.mapper;
return text;

View File

@ -112,7 +112,7 @@ export class Identifiers {
static createComponentFactory: IdentifierSpec = {name: 'ɵccf', moduleUrl: CORE, runtime: ɵccf};
}
export function assetUrl(pkg: string, path: string = null, type: string = 'src'): string {
export function assetUrl(pkg: string, path: string | null = null, type: string = 'src'): string {
if (path == null) {
return `@angular/${pkg}`;
} else {

View File

@ -49,20 +49,20 @@ export class JitCompiler implements Compiler {
get injector(): Injector { return this._injector; }
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
return this._compileModuleAndComponents(moduleType, true).syncResult;
return this._compileModuleAndComponents(moduleType, true).syncResult !;
}
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
return this._compileModuleAndComponents(moduleType, false).asyncResult;
return this._compileModuleAndComponents(moduleType, false).asyncResult !;
}
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T> {
return this._compileModuleAndAllComponents(moduleType, true).syncResult;
return this._compileModuleAndAllComponents(moduleType, true).syncResult !;
}
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>):
Promise<ModuleWithComponentFactories<T>> {
return this._compileModuleAndAllComponents(moduleType, false).asyncResult;
return this._compileModuleAndAllComponents(moduleType, false).asyncResult !;
}
getNgContentSelectors(component: Type<any>): string[] {
@ -72,7 +72,7 @@ export class JitCompiler implements Compiler {
if (!template) {
throw new Error(`The component ${stringify(component)} is not yet compiled!`);
}
return template.compMeta.template.ngContentSelectors;
return template.compMeta.template !.ngContentSelectors;
}
private _compileModuleAndComponents<T>(moduleType: Type<T>, isSync: boolean):
@ -106,7 +106,7 @@ export class JitCompiler implements Compiler {
private _loadModules(mainModule: any, isSync: boolean): Promise<any> {
const loadingPromises: Promise<any>[] = [];
const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule);
const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule) !;
// Note: the loadingPromise for a module only includes the loading of the exported directives
// of imported modules.
// However, for runtime compilation, we want to transitively compile all modules,
@ -119,9 +119,9 @@ export class JitCompiler implements Compiler {
}
private _compileModule<T>(moduleType: Type<T>): NgModuleFactory<T> {
let ngModuleFactory = this._compiledNgModuleCache.get(moduleType);
let ngModuleFactory = this._compiledNgModuleCache.get(moduleType) !;
if (!ngModuleFactory) {
const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType);
const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType) !;
// Always provide a bound Compiler
const extraProviders = [this._metadataResolver.getProviderMetadata(new ProviderMeta(
Compiler, {useFactory: () => new ModuleBoundCompiler(this, moduleMeta.type.reference)}))];
@ -142,14 +142,14 @@ export class JitCompiler implements Compiler {
/**
* @internal
*/
_compileComponents(mainModule: Type<any>, allComponentFactories: ComponentFactory<any>[]) {
const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule);
_compileComponents(mainModule: Type<any>, allComponentFactories: ComponentFactory<any>[]|null) {
const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule) !;
const moduleByDirective = new Map<any, CompileNgModuleMetadata>();
const templates = new Set<CompiledTemplate>();
ngModule.transitiveModule.modules.forEach((localModuleSummary) => {
const localModuleMeta =
this._metadataResolver.getNgModuleMetadata(localModuleSummary.reference);
this._metadataResolver.getNgModuleMetadata(localModuleSummary.reference) !;
localModuleMeta.declaredDirectives.forEach((dirIdentifier) => {
moduleByDirective.set(dirIdentifier.reference, localModuleMeta);
const dirMeta = this._metadataResolver.getDirectiveMetadata(dirIdentifier.reference);
@ -166,19 +166,19 @@ export class JitCompiler implements Compiler {
});
ngModule.transitiveModule.modules.forEach((localModuleSummary) => {
const localModuleMeta =
this._metadataResolver.getNgModuleMetadata(localModuleSummary.reference);
this._metadataResolver.getNgModuleMetadata(localModuleSummary.reference) !;
localModuleMeta.declaredDirectives.forEach((dirIdentifier) => {
const dirMeta = this._metadataResolver.getDirectiveMetadata(dirIdentifier.reference);
if (dirMeta.isComponent) {
dirMeta.entryComponents.forEach((entryComponentType) => {
const moduleMeta = moduleByDirective.get(entryComponentType.componentType);
const moduleMeta = moduleByDirective.get(entryComponentType.componentType) !;
templates.add(
this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta));
});
}
});
localModuleMeta.entryComponents.forEach((entryComponentType) => {
const moduleMeta = moduleByDirective.get(entryComponentType.componentType);
const moduleMeta = moduleByDirective.get(entryComponentType.componentType) !;
templates.add(
this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta));
});
@ -245,7 +245,7 @@ export class JitCompiler implements Compiler {
const externalStylesheetsByModuleUrl = new Map<string, CompiledStylesheet>();
const stylesCompileResult = this._styleCompiler.compileComponent(compMeta);
stylesCompileResult.externalStylesheets.forEach(
(r) => { externalStylesheetsByModuleUrl.set(r.meta.moduleUrl, r); });
(r) => { externalStylesheetsByModuleUrl.set(r.meta.moduleUrl !, r); });
this._resolveStylesCompileResult(
stylesCompileResult.componentStylesheet, externalStylesheetsByModuleUrl);
const directives =
@ -253,8 +253,8 @@ export class JitCompiler implements Compiler {
const pipes = template.ngModule.transitiveModule.pipes.map(
pipe => this._metadataResolver.getPipeSummary(pipe.reference));
const {template: parsedTemplate, pipes: usedPipes} = this._templateParser.parse(
compMeta, compMeta.template.template, directives, pipes, template.ngModule.schemas,
templateSourceUrl(template.ngModule.type, template.compMeta, template.compMeta.template));
compMeta, compMeta.template !.template !, directives, pipes, template.ngModule.schemas,
templateSourceUrl(template.ngModule.type, template.compMeta, template.compMeta.template !));
const compileResult = this._viewCompiler.compileComponent(
compMeta, parsedTemplate, ir.variable(stylesCompileResult.componentStylesheet.stylesVar),
usedPipes);
@ -278,7 +278,7 @@ export class JitCompiler implements Compiler {
private _resolveStylesCompileResult(
result: CompiledStylesheet, externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>) {
result.dependencies.forEach((dep, i) => {
const nestedCompileResult = externalStylesheetsByModuleUrl.get(dep.moduleUrl);
const nestedCompileResult = externalStylesheetsByModuleUrl.get(dep.moduleUrl) !;
const nestedStylesArr = this._resolveAndEvalStylesCompileResult(
nestedCompileResult, externalStylesheetsByModuleUrl);
dep.valuePlaceholder.reference = nestedStylesArr;
@ -300,7 +300,7 @@ export class JitCompiler implements Compiler {
}
class CompiledTemplate {
private _viewClass: Function = null;
private _viewClass: Function = null !;
isCompiled = false;
constructor(

View File

@ -59,7 +59,7 @@ export const COMPILER_PROVIDERS: Array<any|Type<any>|{[k: string]: any}|any[]> =
useFactory: (parser: HtmlParser, translations: string, format: string, config: CompilerConfig,
console: Console) =>
new i18n.I18NHtmlParser(
parser, translations, format, config.missingTranslation, console),
parser, translations, format, config.missingTranslation !, console),
deps: [
baseHtmlParser,
[new Optional(), new Inject(TRANSLATIONS)],
@ -123,7 +123,7 @@ export class JitCompilerFactory implements CompilerFactory {
},
deps: []
},
opts.providers
opts.providers !
]);
return injector.get(Compiler);
}
@ -148,12 +148,12 @@ function _mergeOptions(optionsArr: CompilerOptions[]): CompilerOptions {
return {
useJit: _lastDefined(optionsArr.map(options => options.useJit)),
defaultEncapsulation: _lastDefined(optionsArr.map(options => options.defaultEncapsulation)),
providers: _mergeArrays(optionsArr.map(options => options.providers)),
providers: _mergeArrays(optionsArr.map(options => options.providers !)),
missingTranslation: _lastDefined(optionsArr.map(options => options.missingTranslation)),
};
}
function _lastDefined<T>(args: T[]): T {
function _lastDefined<T>(args: T[]): T|undefined {
for (let i = args.length - 1; i >= 0; i--) {
if (args[i] !== undefined) {
return args[i];

View File

@ -23,7 +23,7 @@ import {PipeResolver} from './pipe_resolver';
import {ElementSchemaRegistry} from './schema/element_schema_registry';
import {SummaryResolver} from './summary_resolver';
import {getUrlScheme} from './url_resolver';
import {MODULE_SUFFIX, ValueTransformer, syntaxError, visitValue} from './util';
import {MODULE_SUFFIX, ValueTransformer, noUndefined, syntaxError, visitValue} from './util';
export type ErrorCollector = (error: any, type?: any) => void;
export const ERROR_COLLECTOR_TOKEN = new InjectionToken('ErrorCollector');
@ -40,7 +40,7 @@ export class CompileMetadataResolver {
private _nonNormalizedDirectiveCache =
new Map<Type<any>, {annotation: Directive, metadata: cpl.CompileDirectiveMetadata}>();
private _directiveCache = new Map<Type<any>, cpl.CompileDirectiveMetadata>();
private _summaryCache = new Map<Type<any>, cpl.CompileTypeSummary>();
private _summaryCache = new Map<Type<any>, cpl.CompileTypeSummary|null>();
private _pipeCache = new Map<Type<any>, cpl.CompilePipeMetadata>();
private _ngModuleCache = new Map<Type<any>, cpl.CompileNgModuleMetadata>();
private _ngModuleOfTypes = new Map<Type<any>, Type<any>>();
@ -137,7 +137,7 @@ export class CompileMetadataResolver {
}
private getComponentFactory(
selector: string, dirType: any, inputs: {[key: string]: string},
selector: string, dirType: any, inputs: {[key: string]: string}|null,
outputs: {[key: string]: string}): StaticSymbol|ComponentFactory<any> {
if (dirType instanceof StaticSymbol) {
return this._staticSymbolCache.get(
@ -157,26 +157,27 @@ export class CompileMetadataResolver {
}
}
private _loadSummary(type: any, kind: cpl.CompileSummaryKind): cpl.CompileTypeSummary {
private _loadSummary(type: any, kind: cpl.CompileSummaryKind): cpl.CompileTypeSummary|null {
let typeSummary = this._summaryCache.get(type);
if (!typeSummary) {
const summary = this._summaryResolver.resolveSummary(type);
typeSummary = summary ? summary.type : null;
this._summaryCache.set(type, typeSummary);
this._summaryCache.set(type, typeSummary || null);
}
return typeSummary && typeSummary.summaryKind === kind ? typeSummary : null;
}
private _loadDirectiveMetadata(ngModuleType: any, directiveType: any, isSync: boolean):
Promise<any> {
Promise<any>|null {
if (this._directiveCache.has(directiveType)) {
return;
return null;
}
directiveType = resolveForwardRef(directiveType);
const {annotation, metadata} = this.getNonNormalizedDirectiveMetadata(directiveType);
const {annotation, metadata} = this.getNonNormalizedDirectiveMetadata(directiveType) !;
const createDirectiveMetadata = (templateMetadata: cpl.CompileTemplateMetadata) => {
const createDirectiveMetadata = (templateMetadata: cpl.CompileTemplateMetadata | null) => {
const normalizedDirMeta = new cpl.CompileDirectiveMetadata({
isHost: false,
type: metadata.type,
isComponent: metadata.isComponent,
selector: metadata.selector,
@ -198,7 +199,7 @@ export class CompileMetadataResolver {
template: templateMetadata
});
if (templateMetadata) {
this.initComponentFactory(metadata.componentFactory, templateMetadata.ngContentSelectors);
this.initComponentFactory(metadata.componentFactory !, templateMetadata.ngContentSelectors);
}
this._directiveCache.set(directiveType, normalizedDirMeta);
this._summaryCache.set(directiveType, normalizedDirMeta.toSummary());
@ -206,17 +207,18 @@ export class CompileMetadataResolver {
};
if (metadata.isComponent) {
const template = metadata.template !;
const templateMeta = this._directiveNormalizer.normalizeTemplate({
ngModuleType,
componentType: directiveType,
moduleUrl: componentModuleUrl(this._reflector, directiveType, annotation),
encapsulation: metadata.template.encapsulation,
template: metadata.template.template,
templateUrl: metadata.template.templateUrl,
styles: metadata.template.styles,
styleUrls: metadata.template.styleUrls,
animations: metadata.template.animations,
interpolation: metadata.template.interpolation
encapsulation: template.encapsulation,
template: template.template,
templateUrl: template.templateUrl,
styles: template.styles,
styleUrls: template.styleUrls,
animations: template.animations,
interpolation: template.interpolation
});
if (templateMeta.syncResult) {
createDirectiveMetadata(templateMeta.syncResult);
@ -226,7 +228,7 @@ export class CompileMetadataResolver {
this._reportError(componentStillLoadingError(directiveType), directiveType);
return null;
}
return templateMeta.asyncResult.then(createDirectiveMetadata);
return templateMeta.asyncResult !.then(createDirectiveMetadata);
}
} else {
// directive
@ -236,7 +238,7 @@ export class CompileMetadataResolver {
}
getNonNormalizedDirectiveMetadata(directiveType: any):
{annotation: Directive, metadata: cpl.CompileDirectiveMetadata} {
{annotation: Directive, metadata: cpl.CompileDirectiveMetadata}|null {
directiveType = resolveForwardRef(directiveType);
if (!directiveType) {
return null;
@ -249,7 +251,7 @@ export class CompileMetadataResolver {
if (!dirMeta) {
return null;
}
let nonNormalizedTemplateMetadata: cpl.CompileTemplateMetadata;
let nonNormalizedTemplateMetadata: cpl.CompileTemplateMetadata = undefined !;
if (dirMeta instanceof Component) {
// component
@ -260,25 +262,27 @@ export class CompileMetadataResolver {
const animations = dirMeta.animations;
nonNormalizedTemplateMetadata = new cpl.CompileTemplateMetadata({
encapsulation: dirMeta.encapsulation,
template: dirMeta.template,
templateUrl: dirMeta.templateUrl,
styles: dirMeta.styles,
styleUrls: dirMeta.styleUrls,
animations: animations,
interpolation: dirMeta.interpolation,
isInline: !!dirMeta.template
encapsulation: noUndefined(dirMeta.encapsulation),
template: noUndefined(dirMeta.template),
templateUrl: noUndefined(dirMeta.templateUrl),
styles: dirMeta.styles || [],
styleUrls: dirMeta.styleUrls || [],
animations: animations || [],
interpolation: noUndefined(dirMeta.interpolation),
isInline: !!dirMeta.template,
externalStylesheets: [],
ngContentSelectors: []
});
}
let changeDetectionStrategy: ChangeDetectionStrategy = null;
let changeDetectionStrategy: ChangeDetectionStrategy = null !;
let viewProviders: cpl.CompileProviderMetadata[] = [];
let entryComponentMetadata: cpl.CompileEntryComponentMetadata[] = [];
let selector = dirMeta.selector;
if (dirMeta instanceof Component) {
// Component
changeDetectionStrategy = dirMeta.changeDetection;
changeDetectionStrategy = dirMeta.changeDetection !;
if (dirMeta.viewProviders) {
viewProviders = this._getProvidersMetadata(
dirMeta.viewProviders, entryComponentMetadata,
@ -286,7 +290,7 @@ export class CompileMetadataResolver {
}
if (dirMeta.entryComponents) {
entryComponentMetadata = flattenAndDedupeArray(dirMeta.entryComponents)
.map((type) => this._getEntryComponentMetadata(type))
.map((type) => this._getEntryComponentMetadata(type) !)
.concat(entryComponentMetadata);
}
if (!selector) {
@ -317,24 +321,25 @@ export class CompileMetadataResolver {
}
const metadata = cpl.CompileDirectiveMetadata.create({
isHost: false,
selector: selector,
exportAs: dirMeta.exportAs,
exportAs: noUndefined(dirMeta.exportAs),
isComponent: !!nonNormalizedTemplateMetadata,
type: this._getTypeMetadata(directiveType),
template: nonNormalizedTemplateMetadata,
changeDetection: changeDetectionStrategy,
inputs: dirMeta.inputs,
outputs: dirMeta.outputs,
host: dirMeta.host,
providers: providers,
viewProviders: viewProviders,
queries: queries,
viewQueries: viewQueries,
inputs: dirMeta.inputs || [],
outputs: dirMeta.outputs || [],
host: dirMeta.host || {},
providers: providers || [],
viewProviders: viewProviders || [],
queries: queries || [],
viewQueries: viewQueries || [],
entryComponents: entryComponentMetadata,
componentViewType: nonNormalizedTemplateMetadata ? this.getComponentViewClass(directiveType) :
undefined,
rendererType: nonNormalizedTemplateMetadata ? this.getRendererType(directiveType) : undefined,
componentFactory: undefined
null,
rendererType: nonNormalizedTemplateMetadata ? this.getRendererType(directiveType) : null,
componentFactory: null
});
if (nonNormalizedTemplateMetadata) {
metadata.componentFactory =
@ -350,7 +355,7 @@ export class CompileMetadataResolver {
* This assumes `loadNgModuleDirectiveAndPipeMetadata` has been called first.
*/
getDirectiveMetadata(directiveType: any): cpl.CompileDirectiveMetadata {
const dirMeta = this._directiveCache.get(directiveType);
const dirMeta = this._directiveCache.get(directiveType) !;
if (!dirMeta) {
this._reportError(
syntaxError(
@ -376,8 +381,8 @@ export class CompileMetadataResolver {
isPipe(type: any) { return this._pipeResolver.isPipe(type); }
getNgModuleSummary(moduleType: any): cpl.CompileNgModuleSummary {
let moduleSummary =
getNgModuleSummary(moduleType: any): cpl.CompileNgModuleSummary|null {
let moduleSummary: cpl.CompileNgModuleSummary|null =
<cpl.CompileNgModuleSummary>this._loadSummary(moduleType, cpl.CompileSummaryKind.NgModule);
if (!moduleSummary) {
const moduleMeta = this.getNgModuleMetadata(moduleType, false);
@ -408,7 +413,7 @@ export class CompileMetadataResolver {
return Promise.all(loading);
}
getNgModuleMetadata(moduleType: any, throwIfNotFound = true): cpl.CompileNgModuleMetadata {
getNgModuleMetadata(moduleType: any, throwIfNotFound = true): cpl.CompileNgModuleMetadata|null {
moduleType = resolveForwardRef(moduleType);
let compileMeta = this._ngModuleCache.get(moduleType);
if (compileMeta) {
@ -430,7 +435,7 @@ export class CompileMetadataResolver {
if (meta.imports) {
flattenAndDedupeArray(meta.imports).forEach((importedType) => {
let importedModuleType: Type<any>;
let importedModuleType: Type<any> = undefined !;
if (isValidType(importedType)) {
importedModuleType = importedType;
} else if (importedType && importedType.ngModule) {
@ -543,7 +548,7 @@ export class CompileMetadataResolver {
if (meta.entryComponents) {
entryComponents.push(...flattenAndDedupeArray(meta.entryComponents)
.map(type => this._getEntryComponentMetadata(type)));
.map(type => this._getEntryComponentMetadata(type) !));
}
if (meta.bootstrap) {
@ -560,7 +565,7 @@ export class CompileMetadataResolver {
}
entryComponents.push(
...bootstrapComponents.map(type => this._getEntryComponentMetadata(type.reference)));
...bootstrapComponents.map(type => this._getEntryComponentMetadata(type.reference) !));
if (meta.schemas) {
schemas.push(...flattenAndDedupeArray(meta.schemas));
@ -579,11 +584,11 @@ export class CompileMetadataResolver {
importedModules,
exportedModules,
transitiveModule,
id: meta.id,
id: meta.id || null,
});
entryComponents.forEach((id) => transitiveModule.addEntryComponent(id));
providers.forEach((provider) => transitiveModule.addProvider(provider, compileMeta.type));
providers.forEach((provider) => transitiveModule.addProvider(provider, compileMeta !.type));
transitiveModule.addModule(compileMeta.type);
this._ngModuleCache.set(moduleType, compileMeta);
return compileMeta;
@ -690,7 +695,7 @@ export class CompileMetadataResolver {
};
}
private _getInjectableMetadata(type: Type<any>, dependencies: any[] = null):
private _getInjectableMetadata(type: Type<any>, dependencies: any[]|null = null):
cpl.CompileTypeMetadata {
const typeSummary = this._loadSummary(type, cpl.CompileSummaryKind.Injectable);
if (typeSummary) {
@ -699,8 +704,9 @@ export class CompileMetadataResolver {
return this._getTypeMetadata(type, dependencies);
}
private _getTypeMetadata(type: Type<any>, dependencies: any[] = null, throwOnUnknownDeps = true):
cpl.CompileTypeMetadata {
private _getTypeMetadata(
type: Type<any>, dependencies: any[]|null = null,
throwOnUnknownDeps = true): cpl.CompileTypeMetadata {
const identifier = this._getIdentifierMetadata(type);
return {
reference: identifier.reference,
@ -710,7 +716,7 @@ export class CompileMetadataResolver {
};
}
private _getFactoryMetadata(factory: Function, dependencies: any[] = null):
private _getFactoryMetadata(factory: Function, dependencies: any[]|null = null):
cpl.CompileFactoryMetadata {
factory = resolveForwardRef(factory);
return {reference: factory, diDeps: this._getDependenciesMetadata(factory, dependencies)};
@ -720,7 +726,7 @@ export class CompileMetadataResolver {
* Gets the metadata for the given pipe.
* This assumes `loadNgModuleDirectiveAndPipeMetadata` has been called first.
*/
getPipeMetadata(pipeType: any): cpl.CompilePipeMetadata {
getPipeMetadata(pipeType: any): cpl.CompilePipeMetadata|null {
const pipeMeta = this._pipeCache.get(pipeType);
if (!pipeMeta) {
this._reportError(
@ -728,7 +734,7 @@ export class CompileMetadataResolver {
`Illegal state: getPipeMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Pipe ${stringifyType(pipeType)}.`),
pipeType);
}
return pipeMeta;
return pipeMeta || null;
}
getPipeSummary(pipeType: any): cpl.CompilePipeSummary {
@ -753,12 +759,12 @@ export class CompileMetadataResolver {
private _loadPipeMetadata(pipeType: any): cpl.CompilePipeMetadata {
pipeType = resolveForwardRef(pipeType);
const pipeAnnotation = this._pipeResolver.resolve(pipeType);
const pipeAnnotation = this._pipeResolver.resolve(pipeType) !;
const pipeMeta = new cpl.CompilePipeMetadata({
type: this._getTypeMetadata(pipeType),
name: pipeAnnotation.name,
pure: pipeAnnotation.pure
pure: !!pipeAnnotation.pure
});
this._pipeCache.set(pipeType, pipeMeta);
this._summaryCache.set(pipeType, pipeMeta.toSummary());
@ -766,7 +772,7 @@ export class CompileMetadataResolver {
}
private _getDependenciesMetadata(
typeOrFunc: Type<any>|Function, dependencies: any[],
typeOrFunc: Type<any>|Function, dependencies: any[]|null,
throwOnUnknownDeps = true): cpl.CompileDiDependencyMetadata[] {
let hasUnknownDeps = false;
const params = dependencies || this._reflector.parameters(typeOrFunc) || [];
@ -804,7 +810,7 @@ export class CompileMetadataResolver {
}
if (token == null) {
hasUnknownDeps = true;
return null;
return null !;
}
return {
@ -853,7 +859,7 @@ export class CompileMetadataResolver {
this._getProvidersMetadata(provider, targetEntryComponents, debugInfo, compileProviders);
} else {
provider = resolveForwardRef(provider);
let providerMeta: cpl.ProviderMeta;
let providerMeta: cpl.ProviderMeta = undefined !;
if (provider && typeof provider === 'object' && provider.hasOwnProperty('provide')) {
this._validateProvider(provider);
providerMeta = new cpl.ProviderMeta(provider.provide, provider);
@ -933,25 +939,26 @@ export class CompileMetadataResolver {
}
private _getEntryComponentMetadata(dirType: any, throwIfNotFound = true):
cpl.CompileEntryComponentMetadata {
cpl.CompileEntryComponentMetadata|null {
const dirMeta = this.getNonNormalizedDirectiveMetadata(dirType);
if (dirMeta && dirMeta.metadata.isComponent) {
return {componentType: dirType, componentFactory: dirMeta.metadata.componentFactory};
return {componentType: dirType, componentFactory: dirMeta.metadata.componentFactory !};
}
const dirSummary =
<cpl.CompileDirectiveSummary>this._loadSummary(dirType, cpl.CompileSummaryKind.Directive);
if (dirSummary && dirSummary.isComponent) {
return {componentType: dirType, componentFactory: dirSummary.componentFactory};
return {componentType: dirType, componentFactory: dirSummary.componentFactory !};
}
if (throwIfNotFound) {
throw syntaxError(`${dirType.name} cannot be used as an entry component.`);
}
return null;
}
getProviderMetadata(provider: cpl.ProviderMeta): cpl.CompileProviderMetadata {
let compileDeps: cpl.CompileDiDependencyMetadata[];
let compileTypeMetadata: cpl.CompileTypeMetadata = null;
let compileFactoryMetadata: cpl.CompileFactoryMetadata = null;
let compileDeps: cpl.CompileDiDependencyMetadata[] = undefined !;
let compileTypeMetadata: cpl.CompileTypeMetadata = null !;
let compileFactoryMetadata: cpl.CompileFactoryMetadata = null !;
let token: cpl.CompileTokenMetadata = this._getTokenMetadata(provider.token);
if (provider.useClass) {
@ -971,7 +978,7 @@ export class CompileMetadataResolver {
useClass: compileTypeMetadata,
useValue: provider.useValue,
useFactory: compileFactoryMetadata,
useExisting: provider.useExisting ? this._getTokenMetadata(provider.useExisting) : null,
useExisting: provider.useExisting ? this._getTokenMetadata(provider.useExisting) : undefined,
deps: compileDeps,
multi: provider.multi
};
@ -1016,7 +1023,7 @@ export class CompileMetadataResolver {
selectors,
first: q.first,
descendants: q.descendants, propertyName,
read: q.read ? this._getTokenMetadata(q.read) : null
read: q.read ? this._getTokenMetadata(q.read) : null !
};
}
@ -1078,7 +1085,7 @@ export function componentModuleUrl(
`If you're using Webpack you should inline the template and the styles, see https://goo.gl/X2J8zc.`);
}
return reflector.importUri(type);
return reflector.importUri(type) !;
}
function extractIdentifiers(value: any, targetIdentifiers: cpl.CompileIdentifierMetadata[]) {

View File

@ -9,12 +9,12 @@
import {ParseSourceSpan} from '../parse_util';
export interface Node {
sourceSpan: ParseSourceSpan;
sourceSpan: ParseSourceSpan|null;
visit(visitor: Visitor, context: any): any;
}
export class Text implements Node {
constructor(public value: string, public sourceSpan: ParseSourceSpan) {}
constructor(public value: string, public sourceSpan: ParseSourceSpan|null) {}
visit(visitor: Visitor, context: any): any { return visitor.visitText(this, context); }
}
@ -43,13 +43,14 @@ export class Attribute implements Node {
export class Element implements Node {
constructor(
public name: string, public attrs: Attribute[], public children: Node[],
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
public endSourceSpan: ParseSourceSpan) {}
public sourceSpan: ParseSourceSpan|null = null,
public startSourceSpan: ParseSourceSpan|null = null,
public endSourceSpan: ParseSourceSpan|null = null) {}
visit(visitor: Visitor, context: any): any { return visitor.visitElement(this, context); }
}
export class Comment implements Node {
constructor(public value: string, public sourceSpan: ParseSourceSpan) {}
constructor(public value: string|null, public sourceSpan: ParseSourceSpan) {}
visit(visitor: Visitor, context: any): any { return visitor.visitComment(this, context); }
}
@ -70,7 +71,7 @@ export function visitAll(visitor: Visitor, nodes: Node[], context: any = null):
const result: any[] = [];
const visit = visitor.visit ?
(ast: Node) => visitor.visit(ast, context) || ast.visit(visitor, context) :
(ast: Node) => visitor.visit !(ast, context) || ast.visit(visitor, context) :
(ast: Node) => ast.visit(visitor, context);
nodes.forEach(ast => {
const astResult = visit(ast);

View File

@ -14,7 +14,7 @@ export class HtmlTagDefinition implements TagDefinition {
closedByParent: boolean = false;
requiredParents: {[key: string]: boolean};
parentToAdd: string;
implicitNamespacePrefix: string;
implicitNamespacePrefix: string|null;
contentType: TagContentType;
isVoid: boolean;
ignoreFirstLf: boolean;
@ -43,7 +43,7 @@ export class HtmlTagDefinition implements TagDefinition {
this.parentToAdd = requiredParents[0];
requiredParents.forEach(tagName => this.requiredParents[tagName] = true);
}
this.implicitNamespacePrefix = implicitNamespacePrefix;
this.implicitNamespacePrefix = implicitNamespacePrefix || null;
this.contentType = contentType;
this.ignoreFirstLf = ignoreFirstLf;
}

View File

@ -9,7 +9,7 @@
import {assertInterpolationSymbols} from '../assertions';
export class InterpolationConfig {
static fromArray(markers: [string, string]): InterpolationConfig {
static fromArray(markers: [string, string]|null): InterpolationConfig {
if (!markers) {
return DEFAULT_INTERPOLATION_CONFIG;
}

View File

@ -198,8 +198,8 @@ class _Tokenizer {
const token =
new Token(this._currentTokenType, parts, new ParseSourceSpan(this._currentTokenStart, end));
this.tokens.push(token);
this._currentTokenStart = null;
this._currentTokenType = null;
this._currentTokenStart = null !;
this._currentTokenType = null !;
return token;
}
@ -208,8 +208,8 @@ class _Tokenizer {
msg += ` (Do you have an unescaped "{" in your template? Use "{{ '{' }}") to escape it.)`;
}
const error = new TokenError(msg, this._currentTokenType, span);
this._currentTokenStart = null;
this._currentTokenType = null;
this._currentTokenStart = null !;
this._currentTokenType = null !;
return new _ControlFlowError(error);
}
@ -402,7 +402,7 @@ class _Tokenizer {
private _consumePrefixAndName(): string[] {
const nameOrPrefixStart = this._index;
let prefix: string = null;
let prefix: string = null !;
while (this._peek !== chars.$COLON && !isPrefixEnd(this._peek)) {
this._advance();
}
@ -473,7 +473,7 @@ class _Tokenizer {
return this._attemptCharCode(chars.$GT);
});
this._beginToken(TokenType.TAG_CLOSE, textToken.sourceSpan.end);
this._endToken([null, lowercaseTagName]);
this._endToken([null !, lowercaseTagName]);
}
private _consumeTagOpenStart(start: ParseLocation) {
@ -697,7 +697,7 @@ function toUpperCaseCharCode(code: number): number {
function mergeTextTokens(srcTokens: Token[]): Token[] {
const dstTokens: Token[] = [];
let lastDstToken: Token;
let lastDstToken: Token|undefined = undefined;
for (let i = 0; i < srcTokens.length; i++) {
const token = srcTokens[i];
if (lastDstToken && lastDstToken.type == TokenType.TEXT && token.type == TokenType.TEXT) {

View File

@ -14,11 +14,13 @@ import * as lex from './lexer';
import {TagDefinition, getNsPrefix, mergeNsAndName} from './tags';
export class TreeError extends ParseError {
static create(elementName: string, span: ParseSourceSpan, msg: string): TreeError {
static create(elementName: string|null, span: ParseSourceSpan, msg: string): TreeError {
return new TreeError(elementName, span, msg);
}
constructor(public elementName: string, span: ParseSourceSpan, msg: string) { super(span, msg); }
constructor(public elementName: string|null, span: ParseSourceSpan, msg: string) {
super(span, msg);
}
}
export class ParseTreeResult {
@ -93,7 +95,7 @@ class _TreeBuilder {
return prev;
}
private _advanceIf(type: lex.TokenType): lex.Token {
private _advanceIf(type: lex.TokenType): lex.Token|null {
if (this._peek.type === type) {
return this._advance();
}
@ -138,7 +140,7 @@ class _TreeBuilder {
this._advance();
}
private _parseExpansionCase(): html.ExpansionCase {
private _parseExpansionCase(): html.ExpansionCase|null {
const value = this._advance();
// read {
@ -170,7 +172,7 @@ class _TreeBuilder {
value.parts[0], parsedExp.rootNodes, sourceSpan, value.sourceSpan, expSourceSpan);
}
private _collectExpansionExpTokens(start: lex.Token): lex.Token[] {
private _collectExpansionExpTokens(start: lex.Token): lex.Token[]|null {
const exp: lex.Token[] = [];
const expansionFormStack = [lex.TokenType.EXPANSION_CASE_EXP_START];
@ -263,7 +265,7 @@ class _TreeBuilder {
}
const end = this._peek.sourceSpan.start;
const span = new ParseSourceSpan(startTagToken.sourceSpan.start, end);
const el = new html.Element(fullName, attrs, [], span, span, null);
const el = new html.Element(fullName, attrs, [], span, span, undefined);
this._pushElement(el);
if (selfClosing) {
this._popElement(fullName);
@ -297,7 +299,7 @@ class _TreeBuilder {
endTagToken.parts[0], endTagToken.parts[1], this._getParentElement());
if (this._getParentElement()) {
this._getParentElement().endSourceSpan = endTagToken.sourceSpan;
this._getParentElement() !.endSourceSpan = endTagToken.sourceSpan;
}
if (this.getTagDefinition(fullName).isVoid) {
@ -330,7 +332,7 @@ class _TreeBuilder {
const fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]);
let end = attrName.sourceSpan.end;
let value = '';
let valueSpan: ParseSourceSpan;
let valueSpan: ParseSourceSpan = undefined !;
if (this._peek.type === lex.TokenType.ATTR_VALUE) {
const valueToken = this._advance();
value = valueToken.parts[0];
@ -341,7 +343,7 @@ class _TreeBuilder {
fullName, value, new ParseSourceSpan(attrName.sourceSpan.start, end), valueSpan);
}
private _getParentElement(): html.Element {
private _getParentElement(): html.Element|null {
return this._elementStack.length > 0 ? this._elementStack[this._elementStack.length - 1] : null;
}
@ -351,7 +353,7 @@ class _TreeBuilder {
* `<ng-container>` elements are skipped as they are not rendered as DOM element.
*/
private _getParentElementSkippingContainers(): {parent: html.Element, container: html.Element} {
let container: html.Element = null;
let container: html.Element = null !;
for (let i = this._elementStack.length - 1; i >= 0; i--) {
if (this._elementStack[i].name !== 'ng-container') {
@ -397,10 +399,10 @@ class _TreeBuilder {
}
}
private _getElementFullName(prefix: string, localName: string, parentElement: html.Element):
private _getElementFullName(prefix: string, localName: string, parentElement: html.Element|null):
string {
if (prefix == null) {
prefix = this.getTagDefinition(localName).implicitNamespacePrefix;
prefix = this.getTagDefinition(localName).implicitNamespacePrefix !;
if (prefix == null && parentElement != null) {
prefix = getNsPrefix(parentElement.name);
}

View File

@ -17,7 +17,7 @@ export interface TagDefinition {
closedByParent: boolean;
requiredParents: {[key: string]: boolean};
parentToAdd: string;
implicitNamespacePrefix: string;
implicitNamespacePrefix: string|null;
contentType: TagContentType;
isVoid: boolean;
ignoreFirstLf: boolean;
@ -28,7 +28,7 @@ export interface TagDefinition {
isClosedByChild(name: string): boolean;
}
export function splitNsName(elementName: string): [string, string] {
export function splitNsName(elementName: string): [string | null, string] {
if (elementName[0] != ':') {
return [null, elementName];
}
@ -42,269 +42,274 @@ export function splitNsName(elementName: string): [string, string] {
return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
}
export function getNsPrefix(fullName: string): string {
return fullName === null ? null : splitNsName(fullName)[0];
}
export function getNsPrefix(fullName: string): string
export function getNsPrefix(fullName: null): null;
export function getNsPrefix(fullName: string | null): string |
null {
return fullName === null ? null : splitNsName(fullName)[0];
}
export function mergeNsAndName(prefix: string, localName: string): string {
return prefix ? `:${prefix}:${localName}` : localName;
}
export function mergeNsAndName(prefix: string, localName: string):
string {
return prefix ? `:${prefix}:${localName}` : localName;
}
// see http://www.w3.org/TR/html51/syntax.html#named-character-references
// see https://html.spec.whatwg.org/multipage/entities.json
// This list is not exhaustive to keep the compiler footprint low.
// The `&#123;` / `&#x1ab;` syntax should be used when the named character reference does not exist.
export const NAMED_ENTITIES: {[k: string]: string} = {
'Aacute': '\u00C1',
'aacute': '\u00E1',
'Acirc': '\u00C2',
'acirc': '\u00E2',
'acute': '\u00B4',
'AElig': '\u00C6',
'aelig': '\u00E6',
'Agrave': '\u00C0',
'agrave': '\u00E0',
'alefsym': '\u2135',
'Alpha': '\u0391',
'alpha': '\u03B1',
'amp': '&',
'and': '\u2227',
'ang': '\u2220',
'apos': '\u0027',
'Aring': '\u00C5',
'aring': '\u00E5',
'asymp': '\u2248',
'Atilde': '\u00C3',
'atilde': '\u00E3',
'Auml': '\u00C4',
'auml': '\u00E4',
'bdquo': '\u201E',
'Beta': '\u0392',
'beta': '\u03B2',
'brvbar': '\u00A6',
'bull': '\u2022',
'cap': '\u2229',
'Ccedil': '\u00C7',
'ccedil': '\u00E7',
'cedil': '\u00B8',
'cent': '\u00A2',
'Chi': '\u03A7',
'chi': '\u03C7',
'circ': '\u02C6',
'clubs': '\u2663',
'cong': '\u2245',
'copy': '\u00A9',
'crarr': '\u21B5',
'cup': '\u222A',
'curren': '\u00A4',
'dagger': '\u2020',
'Dagger': '\u2021',
'darr': '\u2193',
'dArr': '\u21D3',
'deg': '\u00B0',
'Delta': '\u0394',
'delta': '\u03B4',
'diams': '\u2666',
'divide': '\u00F7',
'Eacute': '\u00C9',
'eacute': '\u00E9',
'Ecirc': '\u00CA',
'ecirc': '\u00EA',
'Egrave': '\u00C8',
'egrave': '\u00E8',
'empty': '\u2205',
'emsp': '\u2003',
'ensp': '\u2002',
'Epsilon': '\u0395',
'epsilon': '\u03B5',
'equiv': '\u2261',
'Eta': '\u0397',
'eta': '\u03B7',
'ETH': '\u00D0',
'eth': '\u00F0',
'Euml': '\u00CB',
'euml': '\u00EB',
'euro': '\u20AC',
'exist': '\u2203',
'fnof': '\u0192',
'forall': '\u2200',
'frac12': '\u00BD',
'frac14': '\u00BC',
'frac34': '\u00BE',
'frasl': '\u2044',
'Gamma': '\u0393',
'gamma': '\u03B3',
'ge': '\u2265',
'gt': '>',
'harr': '\u2194',
'hArr': '\u21D4',
'hearts': '\u2665',
'hellip': '\u2026',
'Iacute': '\u00CD',
'iacute': '\u00ED',
'Icirc': '\u00CE',
'icirc': '\u00EE',
'iexcl': '\u00A1',
'Igrave': '\u00CC',
'igrave': '\u00EC',
'image': '\u2111',
'infin': '\u221E',
'int': '\u222B',
'Iota': '\u0399',
'iota': '\u03B9',
'iquest': '\u00BF',
'isin': '\u2208',
'Iuml': '\u00CF',
'iuml': '\u00EF',
'Kappa': '\u039A',
'kappa': '\u03BA',
'Lambda': '\u039B',
'lambda': '\u03BB',
'lang': '\u27E8',
'laquo': '\u00AB',
'larr': '\u2190',
'lArr': '\u21D0',
'lceil': '\u2308',
'ldquo': '\u201C',
'le': '\u2264',
'lfloor': '\u230A',
'lowast': '\u2217',
'loz': '\u25CA',
'lrm': '\u200E',
'lsaquo': '\u2039',
'lsquo': '\u2018',
'lt': '<',
'macr': '\u00AF',
'mdash': '\u2014',
'micro': '\u00B5',
'middot': '\u00B7',
'minus': '\u2212',
'Mu': '\u039C',
'mu': '\u03BC',
'nabla': '\u2207',
'nbsp': '\u00A0',
'ndash': '\u2013',
'ne': '\u2260',
'ni': '\u220B',
'not': '\u00AC',
'notin': '\u2209',
'nsub': '\u2284',
'Ntilde': '\u00D1',
'ntilde': '\u00F1',
'Nu': '\u039D',
'nu': '\u03BD',
'Oacute': '\u00D3',
'oacute': '\u00F3',
'Ocirc': '\u00D4',
'ocirc': '\u00F4',
'OElig': '\u0152',
'oelig': '\u0153',
'Ograve': '\u00D2',
'ograve': '\u00F2',
'oline': '\u203E',
'Omega': '\u03A9',
'omega': '\u03C9',
'Omicron': '\u039F',
'omicron': '\u03BF',
'oplus': '\u2295',
'or': '\u2228',
'ordf': '\u00AA',
'ordm': '\u00BA',
'Oslash': '\u00D8',
'oslash': '\u00F8',
'Otilde': '\u00D5',
'otilde': '\u00F5',
'otimes': '\u2297',
'Ouml': '\u00D6',
'ouml': '\u00F6',
'para': '\u00B6',
'permil': '\u2030',
'perp': '\u22A5',
'Phi': '\u03A6',
'phi': '\u03C6',
'Pi': '\u03A0',
'pi': '\u03C0',
'piv': '\u03D6',
'plusmn': '\u00B1',
'pound': '\u00A3',
'prime': '\u2032',
'Prime': '\u2033',
'prod': '\u220F',
'prop': '\u221D',
'Psi': '\u03A8',
'psi': '\u03C8',
'quot': '\u0022',
'radic': '\u221A',
'rang': '\u27E9',
'raquo': '\u00BB',
'rarr': '\u2192',
'rArr': '\u21D2',
'rceil': '\u2309',
'rdquo': '\u201D',
'real': '\u211C',
'reg': '\u00AE',
'rfloor': '\u230B',
'Rho': '\u03A1',
'rho': '\u03C1',
'rlm': '\u200F',
'rsaquo': '\u203A',
'rsquo': '\u2019',
'sbquo': '\u201A',
'Scaron': '\u0160',
'scaron': '\u0161',
'sdot': '\u22C5',
'sect': '\u00A7',
'shy': '\u00AD',
'Sigma': '\u03A3',
'sigma': '\u03C3',
'sigmaf': '\u03C2',
'sim': '\u223C',
'spades': '\u2660',
'sub': '\u2282',
'sube': '\u2286',
'sum': '\u2211',
'sup': '\u2283',
'sup1': '\u00B9',
'sup2': '\u00B2',
'sup3': '\u00B3',
'supe': '\u2287',
'szlig': '\u00DF',
'Tau': '\u03A4',
'tau': '\u03C4',
'there4': '\u2234',
'Theta': '\u0398',
'theta': '\u03B8',
'thetasym': '\u03D1',
'thinsp': '\u2009',
'THORN': '\u00DE',
'thorn': '\u00FE',
'tilde': '\u02DC',
'times': '\u00D7',
'trade': '\u2122',
'Uacute': '\u00DA',
'uacute': '\u00FA',
'uarr': '\u2191',
'uArr': '\u21D1',
'Ucirc': '\u00DB',
'ucirc': '\u00FB',
'Ugrave': '\u00D9',
'ugrave': '\u00F9',
'uml': '\u00A8',
'upsih': '\u03D2',
'Upsilon': '\u03A5',
'upsilon': '\u03C5',
'Uuml': '\u00DC',
'uuml': '\u00FC',
'weierp': '\u2118',
'Xi': '\u039E',
'xi': '\u03BE',
'Yacute': '\u00DD',
'yacute': '\u00FD',
'yen': '\u00A5',
'yuml': '\u00FF',
'Yuml': '\u0178',
'Zeta': '\u0396',
'zeta': '\u03B6',
'zwj': '\u200D',
'zwnj': '\u200C',
};
// see http://www.w3.org/TR/html51/syntax.html#named-character-references
// see https://html.spec.whatwg.org/multipage/entities.json
// This list is not exhaustive to keep the compiler footprint low.
// The `&#123;` / `&#x1ab;` syntax should be used when the named character reference does not
// exist.
export const NAMED_ENTITIES: {[k: string]: string} = {
'Aacute': '\u00C1',
'aacute': '\u00E1',
'Acirc': '\u00C2',
'acirc': '\u00E2',
'acute': '\u00B4',
'AElig': '\u00C6',
'aelig': '\u00E6',
'Agrave': '\u00C0',
'agrave': '\u00E0',
'alefsym': '\u2135',
'Alpha': '\u0391',
'alpha': '\u03B1',
'amp': '&',
'and': '\u2227',
'ang': '\u2220',
'apos': '\u0027',
'Aring': '\u00C5',
'aring': '\u00E5',
'asymp': '\u2248',
'Atilde': '\u00C3',
'atilde': '\u00E3',
'Auml': '\u00C4',
'auml': '\u00E4',
'bdquo': '\u201E',
'Beta': '\u0392',
'beta': '\u03B2',
'brvbar': '\u00A6',
'bull': '\u2022',
'cap': '\u2229',
'Ccedil': '\u00C7',
'ccedil': '\u00E7',
'cedil': '\u00B8',
'cent': '\u00A2',
'Chi': '\u03A7',
'chi': '\u03C7',
'circ': '\u02C6',
'clubs': '\u2663',
'cong': '\u2245',
'copy': '\u00A9',
'crarr': '\u21B5',
'cup': '\u222A',
'curren': '\u00A4',
'dagger': '\u2020',
'Dagger': '\u2021',
'darr': '\u2193',
'dArr': '\u21D3',
'deg': '\u00B0',
'Delta': '\u0394',
'delta': '\u03B4',
'diams': '\u2666',
'divide': '\u00F7',
'Eacute': '\u00C9',
'eacute': '\u00E9',
'Ecirc': '\u00CA',
'ecirc': '\u00EA',
'Egrave': '\u00C8',
'egrave': '\u00E8',
'empty': '\u2205',
'emsp': '\u2003',
'ensp': '\u2002',
'Epsilon': '\u0395',
'epsilon': '\u03B5',
'equiv': '\u2261',
'Eta': '\u0397',
'eta': '\u03B7',
'ETH': '\u00D0',
'eth': '\u00F0',
'Euml': '\u00CB',
'euml': '\u00EB',
'euro': '\u20AC',
'exist': '\u2203',
'fnof': '\u0192',
'forall': '\u2200',
'frac12': '\u00BD',
'frac14': '\u00BC',
'frac34': '\u00BE',
'frasl': '\u2044',
'Gamma': '\u0393',
'gamma': '\u03B3',
'ge': '\u2265',
'gt': '>',
'harr': '\u2194',
'hArr': '\u21D4',
'hearts': '\u2665',
'hellip': '\u2026',
'Iacute': '\u00CD',
'iacute': '\u00ED',
'Icirc': '\u00CE',
'icirc': '\u00EE',
'iexcl': '\u00A1',
'Igrave': '\u00CC',
'igrave': '\u00EC',
'image': '\u2111',
'infin': '\u221E',
'int': '\u222B',
'Iota': '\u0399',
'iota': '\u03B9',
'iquest': '\u00BF',
'isin': '\u2208',
'Iuml': '\u00CF',
'iuml': '\u00EF',
'Kappa': '\u039A',
'kappa': '\u03BA',
'Lambda': '\u039B',
'lambda': '\u03BB',
'lang': '\u27E8',
'laquo': '\u00AB',
'larr': '\u2190',
'lArr': '\u21D0',
'lceil': '\u2308',
'ldquo': '\u201C',
'le': '\u2264',
'lfloor': '\u230A',
'lowast': '\u2217',
'loz': '\u25CA',
'lrm': '\u200E',
'lsaquo': '\u2039',
'lsquo': '\u2018',
'lt': '<',
'macr': '\u00AF',
'mdash': '\u2014',
'micro': '\u00B5',
'middot': '\u00B7',
'minus': '\u2212',
'Mu': '\u039C',
'mu': '\u03BC',
'nabla': '\u2207',
'nbsp': '\u00A0',
'ndash': '\u2013',
'ne': '\u2260',
'ni': '\u220B',
'not': '\u00AC',
'notin': '\u2209',
'nsub': '\u2284',
'Ntilde': '\u00D1',
'ntilde': '\u00F1',
'Nu': '\u039D',
'nu': '\u03BD',
'Oacute': '\u00D3',
'oacute': '\u00F3',
'Ocirc': '\u00D4',
'ocirc': '\u00F4',
'OElig': '\u0152',
'oelig': '\u0153',
'Ograve': '\u00D2',
'ograve': '\u00F2',
'oline': '\u203E',
'Omega': '\u03A9',
'omega': '\u03C9',
'Omicron': '\u039F',
'omicron': '\u03BF',
'oplus': '\u2295',
'or': '\u2228',
'ordf': '\u00AA',
'ordm': '\u00BA',
'Oslash': '\u00D8',
'oslash': '\u00F8',
'Otilde': '\u00D5',
'otilde': '\u00F5',
'otimes': '\u2297',
'Ouml': '\u00D6',
'ouml': '\u00F6',
'para': '\u00B6',
'permil': '\u2030',
'perp': '\u22A5',
'Phi': '\u03A6',
'phi': '\u03C6',
'Pi': '\u03A0',
'pi': '\u03C0',
'piv': '\u03D6',
'plusmn': '\u00B1',
'pound': '\u00A3',
'prime': '\u2032',
'Prime': '\u2033',
'prod': '\u220F',
'prop': '\u221D',
'Psi': '\u03A8',
'psi': '\u03C8',
'quot': '\u0022',
'radic': '\u221A',
'rang': '\u27E9',
'raquo': '\u00BB',
'rarr': '\u2192',
'rArr': '\u21D2',
'rceil': '\u2309',
'rdquo': '\u201D',
'real': '\u211C',
'reg': '\u00AE',
'rfloor': '\u230B',
'Rho': '\u03A1',
'rho': '\u03C1',
'rlm': '\u200F',
'rsaquo': '\u203A',
'rsquo': '\u2019',
'sbquo': '\u201A',
'Scaron': '\u0160',
'scaron': '\u0161',
'sdot': '\u22C5',
'sect': '\u00A7',
'shy': '\u00AD',
'Sigma': '\u03A3',
'sigma': '\u03C3',
'sigmaf': '\u03C2',
'sim': '\u223C',
'spades': '\u2660',
'sub': '\u2282',
'sube': '\u2286',
'sum': '\u2211',
'sup': '\u2283',
'sup1': '\u00B9',
'sup2': '\u00B2',
'sup3': '\u00B3',
'supe': '\u2287',
'szlig': '\u00DF',
'Tau': '\u03A4',
'tau': '\u03C4',
'there4': '\u2234',
'Theta': '\u0398',
'theta': '\u03B8',
'thetasym': '\u03D1',
'thinsp': '\u2009',
'THORN': '\u00DE',
'thorn': '\u00FE',
'tilde': '\u02DC',
'times': '\u00D7',
'trade': '\u2122',
'Uacute': '\u00DA',
'uacute': '\u00FA',
'uarr': '\u2191',
'uArr': '\u21D1',
'Ucirc': '\u00DB',
'ucirc': '\u00FB',
'Ugrave': '\u00D9',
'ugrave': '\u00F9',
'uml': '\u00A8',
'upsih': '\u03D2',
'Upsilon': '\u03A5',
'upsilon': '\u03C5',
'Uuml': '\u00DC',
'uuml': '\u00FC',
'weierp': '\u2118',
'Xi': '\u039E',
'xi': '\u03BE',
'Yacute': '\u00DD',
'yacute': '\u00FD',
'yen': '\u00A5',
'yuml': '\u00FF',
'Yuml': '\u0178',
'Zeta': '\u0396',
'zeta': '\u03B6',
'zwj': '\u200D',
'zwnj': '\u200C',
};

View File

@ -15,6 +15,6 @@ export class XmlParser extends Parser {
constructor() { super(getXmlTagDefinition); }
parse(source: string, url: string, parseExpansionForms: boolean = false): ParseTreeResult {
return super.parse(source, url, parseExpansionForms, null);
return super.parse(source, url, parseExpansionForms);
}
}

View File

@ -63,7 +63,7 @@ export class NgModuleCompiler {
[o.variable(injectorClass.name), o.importExpr(ngModuleMeta.type)],
o.importType(
createIdentifier(Identifiers.NgModuleFactory),
[o.importType(ngModuleMeta.type)], [o.TypeModifier.Const])))
[o.importType(ngModuleMeta.type) !], [o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final]);
const stmts: o.Statement[] = [injectorClass, ngModuleFactoryStmt];
@ -106,7 +106,7 @@ class _InjectorBuilder implements ClassBuilder {
if (resolvedProvider.lifecycleHooks.indexOf(ɵLifecycleHooks.OnDestroy) !== -1) {
let callNgOnDestroy: o.Expression = instance.callMethod('ngOnDestroy', []);
if (!resolvedProvider.eager) {
callNgOnDestroy = this._lazyProps.get(instance.name).and(callNgOnDestroy);
callNgOnDestroy = this._lazyProps.get(instance.name) !.and(callNgOnDestroy);
}
this._destroyStmts.push(callNgOnDestroy.toStmt());
}
@ -116,7 +116,7 @@ class _InjectorBuilder implements ClassBuilder {
build(): o.ClassStmt {
const getMethodStmts: o.Statement[] = this._tokens.map((token) => {
const providerExpr = this._instances.get(tokenReference(token));
const providerExpr = this._instances.get(tokenReference(token)) !;
return new o.IfStmt(
InjectMethodVars.token.identical(createDiTokenExpression(token)),
[new o.ReturnStatement(providerExpr)]);
@ -124,13 +124,13 @@ class _InjectorBuilder implements ClassBuilder {
const methods = [
new o.ClassMethod(
'createInternal', [], this._createStmts.concat(new o.ReturnStatement(
this._instances.get(this._ngModuleMeta.type.reference))),
this._instances.get(this._ngModuleMeta.type.reference) !)),
o.importType(this._ngModuleMeta.type)),
new o.ClassMethod(
'getInternal',
[
new o.FnParam(InjectMethodVars.token.name, o.DYNAMIC_TYPE),
new o.FnParam(InjectMethodVars.notFoundResult.name, o.DYNAMIC_TYPE)
new o.FnParam(InjectMethodVars.token.name !, o.DYNAMIC_TYPE),
new o.FnParam(InjectMethodVars.notFoundResult.name !, o.DYNAMIC_TYPE)
],
getMethodStmts.concat([new o.ReturnStatement(InjectMethodVars.notFoundResult)]),
o.DYNAMIC_TYPE),
@ -150,7 +150,8 @@ class _InjectorBuilder implements ClassBuilder {
ctorParams: [new o.FnParam(
InjectorProps.parent.name, o.importType(createIdentifier(Identifiers.Injector)))],
parent: o.importExpr(
createIdentifier(Identifiers.NgModuleInjector), [o.importType(this._ngModuleMeta.type)]),
createIdentifier(Identifiers.NgModuleInjector),
[o.importType(this._ngModuleMeta.type) !]),
parentArgs: parentArgs,
builders: [{methods}, this]
});
@ -186,7 +187,7 @@ class _InjectorBuilder implements ClassBuilder {
type = new o.ArrayType(o.DYNAMIC_TYPE);
} else {
resolvedProviderValueExpr = providerValueExpressions[0];
type = providerValueExpressions[0].type;
type = providerValueExpressions[0].type !;
}
if (!type) {
type = o.DYNAMIC_TYPE;
@ -211,7 +212,7 @@ class _InjectorBuilder implements ClassBuilder {
}
private _getDependency(dep: CompileDiDependencyMetadata): o.Expression {
let result: o.Expression = null;
let result: o.Expression = null !;
if (dep.isValue) {
result = o.literal(dep.value);
}
@ -226,11 +227,11 @@ class _InjectorBuilder implements ClassBuilder {
}
if (!result) {
result = this._instances.get(tokenReference(dep.token));
result = this._instances.get(tokenReference(dep.token !)) !;
}
}
if (!result) {
const args = [createDiTokenExpression(dep.token)];
const args = [createDiTokenExpression(dep.token !)];
if (dep.isOptional) {
args.push(o.NULL_EXPR);
}
@ -244,7 +245,7 @@ function createDiTokenExpression(token: CompileTokenMetadata): o.Expression {
if (token.value != null) {
return o.literal(token.value);
} else {
return o.importExpr(token.identifier);
return o.importExpr(token.identifier !);
}
}

View File

@ -23,7 +23,7 @@ export class NgModuleResolver {
isNgModule(type: any) { return this._reflector.annotations(type).some(_isNgModuleMetadata); }
resolve(type: Type<any>, throwIfNotFound = true): NgModule {
resolve(type: Type<any>, throwIfNotFound = true): NgModule|null {
const ngModuleMeta: NgModule = findLast(this._reflector.annotations(type), _isNgModuleMetadata);
if (ngModuleMeta) {

View File

@ -14,18 +14,18 @@ import {SourceMapGenerator} from './source_map';
const _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g;
const _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i;
const _INDENT_WITH = ' ';
export const CATCH_ERROR_VAR = o.variable('error');
export const CATCH_STACK_VAR = o.variable('stack');
export const CATCH_ERROR_VAR = o.variable('error', null, null);
export const CATCH_STACK_VAR = o.variable('stack', null, null);
export abstract class OutputEmitter {
abstract emitStatements(
srcFilePath: string, genFilePath: string, stmts: o.Statement[], exportedVars: string[],
preamble?: string): string;
preamble?: string|null): string;
}
class _EmittedLine {
parts: string[] = [];
srcSpans: ParseSourceSpan[] = [];
srcSpans: (ParseSourceSpan|null)[] = [];
constructor(public indent: number) {}
}
@ -45,13 +45,13 @@ export class EmitterVisitorContext {
isExportedVar(varName: string): boolean { return this._exportedVars.indexOf(varName) !== -1; }
println(from?: {sourceSpan?: ParseSourceSpan}|null, lastPart: string = ''): void {
this.print(from, lastPart, true);
println(from?: {sourceSpan: ParseSourceSpan | null}|null, lastPart: string = ''): void {
this.print(from || null, lastPart, true);
}
lineIsEmpty(): boolean { return this._currentLine.parts.length === 0; }
print(from: {sourceSpan?: ParseSourceSpan}|null, part: string, newLine: boolean = false) {
print(from: {sourceSpan: ParseSourceSpan | null}|null, part: string, newLine: boolean = false) {
if (part.length > 0) {
this._currentLine.parts.push(part);
this._currentLine.srcSpans.push(from && from.sourceSpan || null);
@ -79,9 +79,9 @@ export class EmitterVisitorContext {
pushClass(clazz: o.ClassStmt) { this._classes.push(clazz); }
popClass(): o.ClassStmt { return this._classes.pop(); }
popClass(): o.ClassStmt { return this._classes.pop() !; }
get currentClass(): o.ClassStmt {
get currentClass(): o.ClassStmt|null {
return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null;
}
@ -130,7 +130,7 @@ export class EmitterVisitorContext {
}
while (spanIdx < spans.length) {
const span = spans[spanIdx];
const span = spans[spanIdx] !;
const source = span.start.file;
const sourceLine = span.start.line;
const sourceCol = span.start.col;
@ -286,7 +286,7 @@ export abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.Ex
return null;
}
visitReadVarExpr(ast: o.ReadVarExpr, ctx: EmitterVisitorContext): any {
let varName = ast.name;
let varName = ast.name !;
if (ast.builtin != null) {
switch (ast.builtin) {
case o.BuiltinVar.Super:
@ -296,10 +296,10 @@ export abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.Ex
varName = 'this';
break;
case o.BuiltinVar.CatchError:
varName = CATCH_ERROR_VAR.name;
varName = CATCH_ERROR_VAR.name !;
break;
case o.BuiltinVar.CatchStack:
varName = CATCH_STACK_VAR.name;
varName = CATCH_STACK_VAR.name !;
break;
default:
throw new Error(`Unknown builtin variable ${ast.builtin}`);
@ -335,7 +335,7 @@ export abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.Ex
ctx.print(ast, '? ');
ast.trueCase.visitExpression(this, ctx);
ctx.print(ast, ': ');
ast.falseCase.visitExpression(this, ctx);
ast.falseCase !.visitExpression(this, ctx);
ctx.print(ast, `)`);
return null;
}

View File

@ -70,7 +70,7 @@ export abstract class AbstractJsEmitterVisitor extends AbstractEmitterVisitor {
ctx.println(stmt, `};`);
}
visitReadVarExpr(ast: o.ReadVarExpr, ctx: EmitterVisitorContext): string {
visitReadVarExpr(ast: o.ReadVarExpr, ctx: EmitterVisitorContext): string|null {
if (ast.builtin === o.BuiltinVar.This) {
ctx.print(ast, 'self');
} else if (ast.builtin === o.BuiltinVar.Super) {
@ -91,10 +91,10 @@ export abstract class AbstractJsEmitterVisitor extends AbstractEmitterVisitor {
ast.value.visitExpression(this, ctx);
return null;
}
visitInvokeFunctionExpr(expr: o.InvokeFunctionExpr, ctx: EmitterVisitorContext): string {
visitInvokeFunctionExpr(expr: o.InvokeFunctionExpr, ctx: EmitterVisitorContext): string|null {
const fnExpr = expr.fn;
if (fnExpr instanceof o.ReadVarExpr && fnExpr.builtin === o.BuiltinVar.Super) {
ctx.currentClass.parent.visitExpression(this, ctx);
ctx.currentClass !.parent !.visitExpression(this, ctx);
ctx.print(expr, `.call(this`);
if (expr.args.length > 0) {
ctx.print(expr, `, `);

View File

@ -31,16 +31,16 @@ export function createClassStmt(config: {
new o.ClassMethod(null, config.ctorParams || [], superCtorStmts.concat(builder.ctorStmts));
return new o.ClassStmt(
config.name, config.parent, builder.fields, builder.getters, ctor, builder.methods,
config.name, config.parent || null, builder.fields, builder.getters, ctor, builder.methods,
config.modifiers || [], config.sourceSpan);
}
function concatClassBuilderParts(builders: ClassBuilderPart[]) {
return {
fields: [].concat(...builders.map(builder => builder.fields || [])),
methods: [].concat(...builders.map(builder => builder.methods || [])),
getters: [].concat(...builders.map(builder => builder.getters || [])),
ctorStmts: [].concat(...builders.map(builder => builder.ctorStmts || [])),
fields: [].concat(...(builders.map((builder => builder.fields || [])) as any)),
methods: [].concat(...(builders.map(builder => builder.methods || []) as any)),
getters: [].concat(...(builders.map(builder => builder.getters || []) as any)),
ctorStmts: [].concat(...(builders.map(builder => builder.ctorStmts || []) as any)),
};
}

View File

@ -16,14 +16,14 @@ export enum TypeModifier {
}
export abstract class Type {
constructor(public modifiers: TypeModifier[] = null) {
constructor(public modifiers: TypeModifier[]|null = null) {
if (!modifiers) {
this.modifiers = [];
}
}
abstract visitType(visitor: TypeVisitor, context: any): any;
hasModifier(modifier: TypeModifier): boolean { return this.modifiers.indexOf(modifier) !== -1; }
hasModifier(modifier: TypeModifier): boolean { return this.modifiers !.indexOf(modifier) !== -1; }
}
export enum BuiltinTypeName {
@ -37,14 +37,16 @@ export enum BuiltinTypeName {
}
export class BuiltinType extends Type {
constructor(public name: BuiltinTypeName, modifiers: TypeModifier[] = null) { super(modifiers); }
constructor(public name: BuiltinTypeName, modifiers: TypeModifier[]|null = null) {
super(modifiers);
}
visitType(visitor: TypeVisitor, context: any): any {
return visitor.visitBuiltintType(this, context);
}
}
export class ExpressionType extends Type {
constructor(public value: Expression, modifiers: TypeModifier[] = null) { super(modifiers); }
constructor(public value: Expression, modifiers: TypeModifier[]|null = null) { super(modifiers); }
visitType(visitor: TypeVisitor, context: any): any {
return visitor.visitExpressionType(this, context);
}
@ -52,7 +54,7 @@ export class ExpressionType extends Type {
export class ArrayType extends Type {
constructor(public of : Type, modifiers: TypeModifier[] = null) { super(modifiers); }
constructor(public of : Type, modifiers: TypeModifier[]|null = null) { super(modifiers); }
visitType(visitor: TypeVisitor, context: any): any {
return visitor.visitArrayType(this, context);
}
@ -60,7 +62,11 @@ export class ArrayType extends Type {
export class MapType extends Type {
constructor(public valueType: Type, modifiers: TypeModifier[] = null) { super(modifiers); }
public valueType: Type|null;
constructor(valueType: Type|null|undefined, modifiers: TypeModifier[]|null = null) {
super(modifiers);
this.valueType = valueType || null;
}
visitType(visitor: TypeVisitor, context: any): any { return visitor.visitMapType(this, context); }
}
@ -101,92 +107,99 @@ export enum BinaryOperator {
export abstract class Expression {
constructor(public type: Type, public sourceSpan?: ParseSourceSpan) {}
public type: Type|null;
public sourceSpan: ParseSourceSpan|null;
constructor(type: Type|null|undefined, sourceSpan?: ParseSourceSpan|null) {
this.type = type || null;
this.sourceSpan = sourceSpan || null;
}
abstract visitExpression(visitor: ExpressionVisitor, context: any): any;
prop(name: string, sourceSpan?: ParseSourceSpan): ReadPropExpr {
prop(name: string, sourceSpan?: ParseSourceSpan|null): ReadPropExpr {
return new ReadPropExpr(this, name, null, sourceSpan);
}
key(index: Expression, type: Type = null, sourceSpan?: ParseSourceSpan): ReadKeyExpr {
key(index: Expression, type?: Type|null, sourceSpan?: ParseSourceSpan|null): ReadKeyExpr {
return new ReadKeyExpr(this, index, type, sourceSpan);
}
callMethod(name: string|BuiltinMethod, params: Expression[], sourceSpan?: ParseSourceSpan):
callMethod(name: string|BuiltinMethod, params: Expression[], sourceSpan?: ParseSourceSpan|null):
InvokeMethodExpr {
return new InvokeMethodExpr(this, name, params, null, sourceSpan);
}
callFn(params: Expression[], sourceSpan?: ParseSourceSpan): InvokeFunctionExpr {
callFn(params: Expression[], sourceSpan?: ParseSourceSpan|null): InvokeFunctionExpr {
return new InvokeFunctionExpr(this, params, null, sourceSpan);
}
instantiate(params: Expression[], type: Type = null, sourceSpan?: ParseSourceSpan):
instantiate(params: Expression[], type?: Type|null, sourceSpan?: ParseSourceSpan|null):
InstantiateExpr {
return new InstantiateExpr(this, params, type, sourceSpan);
}
conditional(trueCase: Expression, falseCase: Expression = null, sourceSpan?: ParseSourceSpan):
ConditionalExpr {
conditional(
trueCase: Expression, falseCase: Expression|null = null,
sourceSpan?: ParseSourceSpan|null): ConditionalExpr {
return new ConditionalExpr(this, trueCase, falseCase, null, sourceSpan);
}
equals(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
equals(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Equals, this, rhs, null, sourceSpan);
}
notEquals(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
notEquals(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.NotEquals, this, rhs, null, sourceSpan);
}
identical(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
identical(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Identical, this, rhs, null, sourceSpan);
}
notIdentical(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
notIdentical(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.NotIdentical, this, rhs, null, sourceSpan);
}
minus(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
minus(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Minus, this, rhs, null, sourceSpan);
}
plus(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
plus(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Plus, this, rhs, null, sourceSpan);
}
divide(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
divide(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Divide, this, rhs, null, sourceSpan);
}
multiply(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
multiply(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Multiply, this, rhs, null, sourceSpan);
}
modulo(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
modulo(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Modulo, this, rhs, null, sourceSpan);
}
and(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
and(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.And, this, rhs, null, sourceSpan);
}
or(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
or(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Or, this, rhs, null, sourceSpan);
}
lower(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
lower(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Lower, this, rhs, null, sourceSpan);
}
lowerEquals(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
lowerEquals(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.LowerEquals, this, rhs, null, sourceSpan);
}
bigger(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
bigger(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.Bigger, this, rhs, null, sourceSpan);
}
biggerEquals(rhs: Expression, sourceSpan?: ParseSourceSpan): BinaryOperatorExpr {
biggerEquals(rhs: Expression, sourceSpan?: ParseSourceSpan|null): BinaryOperatorExpr {
return new BinaryOperatorExpr(BinaryOperator.BiggerEquals, this, rhs, null, sourceSpan);
}
isBlank(sourceSpan?: ParseSourceSpan): Expression {
isBlank(sourceSpan?: ParseSourceSpan|null): Expression {
// Note: We use equals by purpose here to compare to null and undefined in JS.
// We use the typed null to allow strictNullChecks to narrow types.
return this.equals(TYPED_NULL_EXPR, sourceSpan);
}
cast(type: Type, sourceSpan?: ParseSourceSpan): Expression {
cast(type: Type, sourceSpan?: ParseSourceSpan|null): Expression {
return new CastExpr(this, type, sourceSpan);
}
toStmt(): Statement { return new ExpressionStatement(this); }
toStmt(): Statement { return new ExpressionStatement(this, null); }
}
export enum BuiltinVar {
@ -197,10 +210,10 @@ export enum BuiltinVar {
}
export class ReadVarExpr extends Expression {
public name: string;
public builtin: BuiltinVar;
public name: string|null;
public builtin: BuiltinVar|null;
constructor(name: string|BuiltinVar, type: Type = null, sourceSpan?: ParseSourceSpan) {
constructor(name: string|BuiltinVar, type?: Type|null, sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
if (typeof name === 'string') {
this.name = name;
@ -215,6 +228,9 @@ export class ReadVarExpr extends Expression {
}
set(value: Expression): WriteVarExpr {
if (!this.name) {
throw new Error(`Built in variable ${this.builtin} can not be assigned to.`)
}
return new WriteVarExpr(this.name, value, null, this.sourceSpan);
}
}
@ -223,7 +239,7 @@ export class ReadVarExpr extends Expression {
export class WriteVarExpr extends Expression {
public value: Expression;
constructor(
public name: string, value: Expression, type: Type = null, sourceSpan?: ParseSourceSpan) {
public name: string, value: Expression, type?: Type|null, sourceSpan?: ParseSourceSpan|null) {
super(type || value.type, sourceSpan);
this.value = value;
}
@ -232,7 +248,7 @@ export class WriteVarExpr extends Expression {
return visitor.visitWriteVarExpr(this, context);
}
toDeclStmt(type: Type = null, modifiers: StmtModifier[] = null): DeclareVarStmt {
toDeclStmt(type?: Type|null, modifiers?: StmtModifier[]|null): DeclareVarStmt {
return new DeclareVarStmt(this.name, this.value, type, modifiers, this.sourceSpan);
}
}
@ -241,8 +257,8 @@ export class WriteVarExpr extends Expression {
export class WriteKeyExpr extends Expression {
public value: Expression;
constructor(
public receiver: Expression, public index: Expression, value: Expression, type: Type = null,
sourceSpan?: ParseSourceSpan) {
public receiver: Expression, public index: Expression, value: Expression, type?: Type|null,
sourceSpan?: ParseSourceSpan|null) {
super(type || value.type, sourceSpan);
this.value = value;
}
@ -255,8 +271,8 @@ export class WriteKeyExpr extends Expression {
export class WritePropExpr extends Expression {
public value: Expression;
constructor(
public receiver: Expression, public name: string, value: Expression, type: Type = null,
sourceSpan?: ParseSourceSpan) {
public receiver: Expression, public name: string, value: Expression, type?: Type|null,
sourceSpan?: ParseSourceSpan|null) {
super(type || value.type, sourceSpan);
this.value = value;
}
@ -272,11 +288,11 @@ export enum BuiltinMethod {
}
export class InvokeMethodExpr extends Expression {
public name: string;
public builtin: BuiltinMethod;
public name: string|null;
public builtin: BuiltinMethod|null;
constructor(
public receiver: Expression, method: string|BuiltinMethod, public args: Expression[],
type: Type = null, sourceSpan?: ParseSourceSpan) {
type?: Type|null, sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
if (typeof method === 'string') {
this.name = method;
@ -294,8 +310,8 @@ export class InvokeMethodExpr extends Expression {
export class InvokeFunctionExpr extends Expression {
constructor(
public fn: Expression, public args: Expression[], type: Type = null,
sourceSpan?: ParseSourceSpan) {
public fn: Expression, public args: Expression[], type?: Type|null,
sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@ -306,8 +322,8 @@ export class InvokeFunctionExpr extends Expression {
export class InstantiateExpr extends Expression {
constructor(
public classExpr: Expression, public args: Expression[], type?: Type,
sourceSpan?: ParseSourceSpan) {
public classExpr: Expression, public args: Expression[], type?: Type|null,
sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@ -317,7 +333,7 @@ export class InstantiateExpr extends Expression {
export class LiteralExpr extends Expression {
constructor(public value: any, type: Type = null, sourceSpan?: ParseSourceSpan) {
constructor(public value: any, type?: Type|null, sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@ -328,8 +344,8 @@ export class LiteralExpr extends Expression {
export class ExternalExpr extends Expression {
constructor(
public value: CompileIdentifierMetadata, type: Type = null, public typeParams: Type[] = null,
sourceSpan?: ParseSourceSpan) {
public value: CompileIdentifierMetadata, type?: Type|null,
public typeParams: Type[]|null = null, sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@ -341,8 +357,8 @@ export class ExternalExpr extends Expression {
export class ConditionalExpr extends Expression {
public trueCase: Expression;
constructor(
public condition: Expression, trueCase: Expression, public falseCase: Expression = null,
type: Type = null, sourceSpan?: ParseSourceSpan) {
public condition: Expression, trueCase: Expression, public falseCase: Expression|null = null,
type?: Type|null, sourceSpan?: ParseSourceSpan|null) {
super(type || trueCase.type, sourceSpan);
this.trueCase = trueCase;
}
@ -353,7 +369,7 @@ export class ConditionalExpr extends Expression {
export class NotExpr extends Expression {
constructor(public condition: Expression, sourceSpan?: ParseSourceSpan) {
constructor(public condition: Expression, sourceSpan?: ParseSourceSpan|null) {
super(BOOL_TYPE, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@ -362,7 +378,7 @@ export class NotExpr extends Expression {
}
export class CastExpr extends Expression {
constructor(public value: Expression, type: Type, sourceSpan?: ParseSourceSpan) {
constructor(public value: Expression, type?: Type|null, sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@ -372,21 +388,21 @@ export class CastExpr extends Expression {
export class FnParam {
constructor(public name: string, public type: Type = null) {}
constructor(public name: string, public type: Type|null = null) {}
}
export class FunctionExpr extends Expression {
constructor(
public params: FnParam[], public statements: Statement[], type: Type = null,
sourceSpan?: ParseSourceSpan) {
public params: FnParam[], public statements: Statement[], type?: Type|null,
sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
return visitor.visitFunctionExpr(this, context);
}
toDeclStmt(name: string, modifiers: StmtModifier[] = null): DeclareFunctionStmt {
toDeclStmt(name: string, modifiers: StmtModifier[]|null = null): DeclareFunctionStmt {
return new DeclareFunctionStmt(
name, this.params, this.statements, this.type, modifiers, this.sourceSpan);
}
@ -396,8 +412,8 @@ export class FunctionExpr extends Expression {
export class BinaryOperatorExpr extends Expression {
public lhs: Expression;
constructor(
public operator: BinaryOperator, lhs: Expression, public rhs: Expression, type: Type = null,
sourceSpan?: ParseSourceSpan) {
public operator: BinaryOperator, lhs: Expression, public rhs: Expression, type?: Type|null,
sourceSpan?: ParseSourceSpan|null) {
super(type || lhs.type, sourceSpan);
this.lhs = lhs;
}
@ -409,8 +425,8 @@ export class BinaryOperatorExpr extends Expression {
export class ReadPropExpr extends Expression {
constructor(
public receiver: Expression, public name: string, type: Type = null,
sourceSpan?: ParseSourceSpan) {
public receiver: Expression, public name: string, type?: Type|null,
sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@ -424,8 +440,8 @@ export class ReadPropExpr extends Expression {
export class ReadKeyExpr extends Expression {
constructor(
public receiver: Expression, public index: Expression, type: Type = null,
sourceSpan?: ParseSourceSpan) {
public receiver: Expression, public index: Expression, type?: Type|null,
sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@ -439,7 +455,7 @@ export class ReadKeyExpr extends Expression {
export class LiteralArrayExpr extends Expression {
public entries: Expression[];
constructor(entries: Expression[], type: Type = null, sourceSpan?: ParseSourceSpan) {
constructor(entries: Expression[], type?: Type|null, sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
this.entries = entries;
}
@ -453,9 +469,9 @@ export class LiteralMapEntry {
}
export class LiteralMapExpr extends Expression {
public valueType: Type = null;
public valueType: Type|null = null;
constructor(
public entries: LiteralMapEntry[], type: MapType = null, sourceSpan?: ParseSourceSpan) {
public entries: LiteralMapEntry[], type?: MapType|null, sourceSpan?: ParseSourceSpan|null) {
super(type, sourceSpan);
if (type) {
this.valueType = type.valueType;
@ -467,7 +483,7 @@ export class LiteralMapExpr extends Expression {
}
export class CommaExpr extends Expression {
constructor(public parts: Expression[], sourceSpan?: ParseSourceSpan) {
constructor(public parts: Expression[], sourceSpan?: ParseSourceSpan|null) {
super(parts[parts.length - 1].type, sourceSpan);
}
visitExpression(visitor: ExpressionVisitor, context: any): any {
@ -497,12 +513,12 @@ export interface ExpressionVisitor {
visitCommaExpr(ast: CommaExpr, context: any): any;
}
export const THIS_EXPR = new ReadVarExpr(BuiltinVar.This);
export const SUPER_EXPR = new ReadVarExpr(BuiltinVar.Super);
export const CATCH_ERROR_VAR = new ReadVarExpr(BuiltinVar.CatchError);
export const CATCH_STACK_VAR = new ReadVarExpr(BuiltinVar.CatchStack);
export const NULL_EXPR = new LiteralExpr(null, null);
export const TYPED_NULL_EXPR = new LiteralExpr(null, INFERRED_TYPE);
export const THIS_EXPR = new ReadVarExpr(BuiltinVar.This, null, null);
export const SUPER_EXPR = new ReadVarExpr(BuiltinVar.Super, null, null);
export const CATCH_ERROR_VAR = new ReadVarExpr(BuiltinVar.CatchError, null, null);
export const CATCH_STACK_VAR = new ReadVarExpr(BuiltinVar.CatchStack, null, null);
export const NULL_EXPR = new LiteralExpr(null, null, null);
export const TYPED_NULL_EXPR = new LiteralExpr(null, INFERRED_TYPE, null);
//// Statements
export enum StmtModifier {
@ -511,23 +527,24 @@ export enum StmtModifier {
}
export abstract class Statement {
constructor(public modifiers: StmtModifier[] = null, public sourceSpan?: ParseSourceSpan) {
if (!modifiers) {
this.modifiers = [];
}
public modifiers: StmtModifier[];
public sourceSpan: ParseSourceSpan|null;
constructor(modifiers?: StmtModifier[]|null, sourceSpan?: ParseSourceSpan|null) {
this.modifiers = modifiers || [];
this.sourceSpan = sourceSpan || null;
}
abstract visitStatement(visitor: StatementVisitor, context: any): any;
hasModifier(modifier: StmtModifier): boolean { return this.modifiers.indexOf(modifier) !== -1; }
hasModifier(modifier: StmtModifier): boolean { return this.modifiers !.indexOf(modifier) !== -1; }
}
export class DeclareVarStmt extends Statement {
public type: Type;
public type: Type|null;
constructor(
public name: string, public value: Expression, type: Type = null,
modifiers: StmtModifier[] = null, sourceSpan?: ParseSourceSpan) {
public name: string, public value: Expression, type?: Type|null,
modifiers: StmtModifier[]|null = null, sourceSpan?: ParseSourceSpan|null) {
super(modifiers, sourceSpan);
this.type = type || value.type;
}
@ -538,10 +555,12 @@ export class DeclareVarStmt extends Statement {
}
export class DeclareFunctionStmt extends Statement {
public type: Type|null;
constructor(
public name: string, public params: FnParam[], public statements: Statement[],
public type: Type = null, modifiers: StmtModifier[] = null, sourceSpan?: ParseSourceSpan) {
type?: Type|null, modifiers: StmtModifier[]|null = null, sourceSpan?: ParseSourceSpan|null) {
super(modifiers, sourceSpan);
this.type = type || null;
}
visitStatement(visitor: StatementVisitor, context: any): any {
@ -550,7 +569,9 @@ export class DeclareFunctionStmt extends Statement {
}
export class ExpressionStatement extends Statement {
constructor(public expr: Expression, sourceSpan?: ParseSourceSpan) { super(null, sourceSpan); }
constructor(public expr: Expression, sourceSpan?: ParseSourceSpan|null) {
super(null, sourceSpan);
}
visitStatement(visitor: StatementVisitor, context: any): any {
return visitor.visitExpressionStmt(this, context);
@ -559,23 +580,27 @@ export class ExpressionStatement extends Statement {
export class ReturnStatement extends Statement {
constructor(public value: Expression, sourceSpan?: ParseSourceSpan) { super(null, sourceSpan); }
constructor(public value: Expression, sourceSpan?: ParseSourceSpan|null) {
super(null, sourceSpan);
}
visitStatement(visitor: StatementVisitor, context: any): any {
return visitor.visitReturnStmt(this, context);
}
}
export class AbstractClassPart {
constructor(public type: Type = null, public modifiers: StmtModifier[]) {
public type: Type|null;
constructor(type: Type|null|undefined, public modifiers: StmtModifier[]|null) {
if (!modifiers) {
this.modifiers = [];
}
this.type = type || null;
}
hasModifier(modifier: StmtModifier): boolean { return this.modifiers.indexOf(modifier) !== -1; }
hasModifier(modifier: StmtModifier): boolean { return this.modifiers !.indexOf(modifier) !== -1; }
}
export class ClassField extends AbstractClassPart {
constructor(public name: string, type: Type = null, modifiers: StmtModifier[] = null) {
constructor(public name: string, type?: Type|null, modifiers: StmtModifier[]|null = null) {
super(type, modifiers);
}
}
@ -583,8 +608,8 @@ export class ClassField extends AbstractClassPart {
export class ClassMethod extends AbstractClassPart {
constructor(
public name: string, public params: FnParam[], public body: Statement[], type: Type = null,
modifiers: StmtModifier[] = null) {
public name: string|null, public params: FnParam[], public body: Statement[],
type?: Type|null, modifiers: StmtModifier[]|null = null) {
super(type, modifiers);
}
}
@ -592,8 +617,8 @@ export class ClassMethod extends AbstractClassPart {
export class ClassGetter extends AbstractClassPart {
constructor(
public name: string, public body: Statement[], type: Type = null,
modifiers: StmtModifier[] = null) {
public name: string, public body: Statement[], type?: Type|null,
modifiers: StmtModifier[]|null = null) {
super(type, modifiers);
}
}
@ -601,10 +626,10 @@ export class ClassGetter extends AbstractClassPart {
export class ClassStmt extends Statement {
constructor(
public name: string, public parent: Expression, public fields: ClassField[],
public name: string, public parent: Expression|null, public fields: ClassField[],
public getters: ClassGetter[], public constructorMethod: ClassMethod,
public methods: ClassMethod[], modifiers: StmtModifier[] = null,
sourceSpan?: ParseSourceSpan) {
public methods: ClassMethod[], modifiers: StmtModifier[]|null = null,
sourceSpan?: ParseSourceSpan|null) {
super(modifiers, sourceSpan);
}
visitStatement(visitor: StatementVisitor, context: any): any {
@ -616,7 +641,7 @@ export class ClassStmt extends Statement {
export class IfStmt extends Statement {
constructor(
public condition: Expression, public trueCase: Statement[],
public falseCase: Statement[] = [], sourceSpan?: ParseSourceSpan) {
public falseCase: Statement[] = [], sourceSpan?: ParseSourceSpan|null) {
super(null, sourceSpan);
}
visitStatement(visitor: StatementVisitor, context: any): any {
@ -626,7 +651,9 @@ export class IfStmt extends Statement {
export class CommentStmt extends Statement {
constructor(public comment: string, sourceSpan?: ParseSourceSpan) { super(null, sourceSpan); }
constructor(public comment: string, sourceSpan?: ParseSourceSpan|null) {
super(null, sourceSpan);
}
visitStatement(visitor: StatementVisitor, context: any): any {
return visitor.visitCommentStmt(this, context);
}
@ -635,7 +662,8 @@ export class CommentStmt extends Statement {
export class TryCatchStmt extends Statement {
constructor(
public bodyStmts: Statement[], public catchStmts: Statement[], sourceSpan?: ParseSourceSpan) {
public bodyStmts: Statement[], public catchStmts: Statement[],
sourceSpan?: ParseSourceSpan|null) {
super(null, sourceSpan);
}
visitStatement(visitor: StatementVisitor, context: any): any {
@ -645,7 +673,9 @@ export class TryCatchStmt extends Statement {
export class ThrowStmt extends Statement {
constructor(public error: Expression, sourceSpan?: ParseSourceSpan) { super(null, sourceSpan); }
constructor(public error: Expression, sourceSpan?: ParseSourceSpan|null) {
super(null, sourceSpan);
}
visitStatement(visitor: StatementVisitor, context: any): any {
return visitor.visitThrowStmt(this, context);
}
@ -697,7 +727,7 @@ export class AstTransformer implements StatementVisitor, ExpressionVisitor {
const method = ast.builtin || ast.name;
return this.transformExpr(
new InvokeMethodExpr(
ast.receiver.visitExpression(this, context), method,
ast.receiver.visitExpression(this, context), method !,
this.visitAllExpressions(ast.args, context), ast.type, ast.sourceSpan),
context);
}
@ -729,7 +759,7 @@ export class AstTransformer implements StatementVisitor, ExpressionVisitor {
new ConditionalExpr(
ast.condition.visitExpression(this, context),
ast.trueCase.visitExpression(this, context),
ast.falseCase.visitExpression(this, context), ast.type, ast.sourceSpan),
ast.falseCase !.visitExpression(this, context), ast.type, ast.sourceSpan),
context);
}
@ -784,7 +814,7 @@ export class AstTransformer implements StatementVisitor, ExpressionVisitor {
const entries = ast.entries.map(
(entry): LiteralMapEntry => new LiteralMapEntry(
entry.key, entry.value.visitExpression(this, context), entry.quoted, ));
const mapType = new MapType(ast.valueType);
const mapType = new MapType(ast.valueType, null);
return this.transformExpr(new LiteralMapExpr(entries, mapType, ast.sourceSpan), context);
}
visitCommaExpr(ast: CommaExpr, context: any): any {
@ -822,7 +852,7 @@ export class AstTransformer implements StatementVisitor, ExpressionVisitor {
}
visitDeclareClassStmt(stmt: ClassStmt, context: any): any {
const parent = stmt.parent.visitExpression(this, context);
const parent = stmt.parent !.visitExpression(this, context);
const getters = stmt.getters.map(
getter => new ClassGetter(
getter.name, this.visitAllStatements(getter.body, context), getter.type,
@ -911,7 +941,7 @@ export class RecursiveAstVisitor implements StatementVisitor, ExpressionVisitor
visitConditionalExpr(ast: ConditionalExpr, context: any): any {
ast.condition.visitExpression(this, context);
ast.trueCase.visitExpression(this, context);
ast.falseCase.visitExpression(this, context);
ast.falseCase !.visitExpression(this, context);
return ast;
}
visitNotExpr(ast: NotExpr, context: any): any {
@ -972,7 +1002,7 @@ export class RecursiveAstVisitor implements StatementVisitor, ExpressionVisitor
return stmt;
}
visitDeclareClassStmt(stmt: ClassStmt, context: any): any {
stmt.parent.visitExpression(this, context);
stmt.parent !.visitExpression(this, context);
stmt.getters.forEach(getter => this.visitAllStatements(getter.body, context));
if (stmt.constructorMethod) {
this.visitAllStatements(stmt.constructorMethod.body, context);
@ -1018,13 +1048,15 @@ class _ReadVarVisitor extends RecursiveAstVisitor {
return stmt;
}
visitReadVarExpr(ast: ReadVarExpr, context: any): any {
this.varNames.add(ast.name);
if (ast.name) {
this.varNames.add(ast.name);
}
return null;
}
}
export function applySourceSpanToStatementIfNeeded(
stmt: Statement, sourceSpan: ParseSourceSpan): Statement {
stmt: Statement, sourceSpan: ParseSourceSpan | null): Statement {
if (!sourceSpan) {
return stmt;
}
@ -1033,7 +1065,7 @@ export function applySourceSpanToStatementIfNeeded(
}
export function applySourceSpanToExpressionIfNeeded(
expr: Expression, sourceSpan: ParseSourceSpan): Expression {
expr: Expression, sourceSpan: ParseSourceSpan | null): Expression {
if (!sourceSpan) {
return expr;
}
@ -1069,48 +1101,51 @@ class _ApplySourceSpanTransformer extends AstTransformer {
}
export function variable(
name: string, type: Type = null, sourceSpan?: ParseSourceSpan): ReadVarExpr {
name: string, type?: Type | null, sourceSpan?: ParseSourceSpan | null): ReadVarExpr {
return new ReadVarExpr(name, type, sourceSpan);
}
export function importExpr(
id: CompileIdentifierMetadata, typeParams: Type[] = null,
sourceSpan?: ParseSourceSpan): ExternalExpr {
id: CompileIdentifierMetadata, typeParams: Type[] | null = null,
sourceSpan?: ParseSourceSpan | null): ExternalExpr {
return new ExternalExpr(id, null, typeParams, sourceSpan);
}
export function importType(
id: CompileIdentifierMetadata, typeParams: Type[] = null,
typeModifiers: TypeModifier[] = null): ExpressionType {
return id != null ? expressionType(importExpr(id, typeParams), typeModifiers) : null;
id: CompileIdentifierMetadata, typeParams: Type[] | null = null,
typeModifiers: TypeModifier[] | null = null): ExpressionType|null {
return id != null ? expressionType(importExpr(id, typeParams, null), typeModifiers) : null;
}
export function expressionType(
expr: Expression, typeModifiers: TypeModifier[] = null): ExpressionType {
return expr != null ? new ExpressionType(expr, typeModifiers) : null;
expr: Expression, typeModifiers: TypeModifier[] | null = null): ExpressionType|null {
return expr != null ? new ExpressionType(expr, typeModifiers) ! : null;
}
export function literalArr(
values: Expression[], type: Type = null, sourceSpan?: ParseSourceSpan): LiteralArrayExpr {
values: Expression[], type?: Type | null,
sourceSpan?: ParseSourceSpan | null): LiteralArrayExpr {
return new LiteralArrayExpr(values, type, sourceSpan);
}
export function literalMap(
values: [string, Expression][], type: MapType = null, quoted: boolean = false): LiteralMapExpr {
values: [string, Expression][], type: MapType | null = null,
quoted: boolean = false): LiteralMapExpr {
return new LiteralMapExpr(
values.map(entry => new LiteralMapEntry(entry[0], entry[1], quoted)), type);
values.map(entry => new LiteralMapEntry(entry[0], entry[1], quoted)), type, null);
}
export function not(expr: Expression, sourceSpan?: ParseSourceSpan): NotExpr {
export function not(expr: Expression, sourceSpan?: ParseSourceSpan | null): NotExpr {
return new NotExpr(expr, sourceSpan);
}
export function fn(
params: FnParam[], body: Statement[], type: Type = null,
sourceSpan?: ParseSourceSpan): FunctionExpr {
params: FnParam[], body: Statement[], type?: Type | null,
sourceSpan?: ParseSourceSpan | null): FunctionExpr {
return new FunctionExpr(params, body, type, sourceSpan);
}
export function literal(value: any, type: Type = null, sourceSpan?: ParseSourceSpan): LiteralExpr {
export function literal(
value: any, type?: Type | null, sourceSpan?: ParseSourceSpan | null): LiteralExpr {
return new LiteralExpr(value, type, sourceSpan);
}

View File

@ -33,7 +33,7 @@ function _executeFunctionStatements(
class _ExecutionContext {
constructor(
public parent: _ExecutionContext, public instance: any, public className: string,
public parent: _ExecutionContext|null, public instance: any, public className: string|null,
public vars: Map<string, any>) {}
createChildWihtLocalVars(): _ExecutionContext {
@ -62,7 +62,7 @@ function createDynamicClass(
_classStmt.methods.forEach(function(method: o.ClassMethod) {
const paramNames = method.params.map(param => param.name);
// Note: use `function` instead of arrow function to capture `this`
propertyDescriptors[method.name] = {
propertyDescriptors[method.name !] = {
writable: false,
configurable: false,
value: function(...args: any[]) {
@ -100,12 +100,12 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
currCtx.vars.set(expr.name, value);
return value;
}
currCtx = currCtx.parent;
currCtx = currCtx.parent !;
}
throw new Error(`Not declared variable ${expr.name}`);
}
visitReadVarExpr(ast: o.ReadVarExpr, ctx: _ExecutionContext): any {
let varName = ast.name;
let varName = ast.name !;
if (ast.builtin != null) {
switch (ast.builtin) {
case o.BuiltinVar.Super:
@ -127,7 +127,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
if (currCtx.vars.has(varName)) {
return currCtx.vars.get(varName);
}
currCtx = currCtx.parent;
currCtx = currCtx.parent !;
}
throw new Error(`Not declared variable ${varName}`);
}
@ -164,7 +164,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
throw new Error(`Unknown builtin method ${expr.builtin}`);
}
} else {
result = receiver[expr.name].apply(receiver, args);
result = receiver[expr.name !].apply(receiver, args);
}
return result;
}
@ -312,7 +312,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
return expressions.map((expr) => expr.visitExpression(this, ctx));
}
visitAllStatements(statements: o.Statement[], ctx: _ExecutionContext): ReturnValue {
visitAllStatements(statements: o.Statement[], ctx: _ExecutionContext): ReturnValue|null {
for (let i = 0; i < statements.length; i++) {
const stmt = statements[i];
const val = stmt.visitStatement(this, ctx);

View File

@ -16,17 +16,16 @@ export abstract class ImportResolver {
* Converts a file path to a module name that can be used as an `import.
* I.e. `path/to/importedFile.ts` should be imported by `path/to/containingFile.ts`.
*/
abstract fileNameToModuleName(importedFilePath: string, containingFilePath: string): string
/*|null*/;
abstract fileNameToModuleName(importedFilePath: string, containingFilePath: string): string|null;
/**
* Converts the given StaticSymbol into another StaticSymbol that should be used
* to generate the import from.
*/
abstract getImportAs(symbol: StaticSymbol): StaticSymbol /*|null*/;
abstract getImportAs(symbol: StaticSymbol): StaticSymbol|null;
/**
* Determine the arity of a type.
*/
abstract getTypeArity(symbol: StaticSymbol): number /*|null*/;
abstract getTypeArity(symbol: StaticSymbol): number|null;
}

View File

@ -25,12 +25,12 @@ export type SourceMap = {
file?: string,
sourceRoot: string,
sources: string[],
sourcesContent: string[],
sourcesContent: (string | null)[],
mappings: string,
};
export class SourceMapGenerator {
private sourcesContent: Map<string, string> = new Map();
private sourcesContent: Map<string, string|null> = new Map();
private lines: Segment[][] = [];
private lastCol0: number = 0;
private hasMappings = false;
@ -83,7 +83,7 @@ export class SourceMapGenerator {
const sourcesIndex = new Map<string, number>();
const sources: string[] = [];
const sourcesContent: string[] = [];
const sourcesContent: (string | null)[] = [];
Array.from(this.sourcesContent.keys()).forEach((url: string, i: number) => {
sourcesIndex.set(url, i);
@ -109,14 +109,14 @@ export class SourceMapGenerator {
if (segment.sourceUrl != null) {
// zero-based index into the “sources” list
segAsStr +=
toBase64VLQ(sourcesIndex.get(segment.sourceUrl) - lastSourceIndex);
lastSourceIndex = sourcesIndex.get(segment.sourceUrl);
toBase64VLQ(sourcesIndex.get(segment.sourceUrl) ! - lastSourceIndex);
lastSourceIndex = sourcesIndex.get(segment.sourceUrl) !;
// the zero-based starting line in the original source
segAsStr += toBase64VLQ(segment.sourceLine0 - lastSourceLine0);
lastSourceLine0 = segment.sourceLine0;
segAsStr += toBase64VLQ(segment.sourceLine0 ! - lastSourceLine0);
lastSourceLine0 = segment.sourceLine0 !;
// the zero-based starting column in the original source
segAsStr += toBase64VLQ(segment.sourceCol0 - lastSourceCol0);
lastSourceCol0 = segment.sourceCol0;
segAsStr += toBase64VLQ(segment.sourceCol0 ! - lastSourceCol0);
lastSourceCol0 = segment.sourceCol0 !;
}
return segAsStr;

View File

@ -20,7 +20,7 @@ export function debugOutputAstAsTypeScript(ast: o.Statement | o.Expression | o.T
string {
const converter = new _TsEmitterVisitor(_debugFilePath, {
fileNameToModuleName(filePath: string, containingFilePath: string) { return filePath; },
getImportAs(symbol: StaticSymbol) { return null; },
getImportAs(symbol: StaticSymbol | null) { return null; },
getTypeArity: symbol => null
});
const ctx = EmitterVisitorContext.createRoot([]);
@ -89,8 +89,8 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
importsWithPrefixes = new Map<string, string>();
reexports = new Map<string, {name: string, as: string}[]>();
visitType(t: o.Type, ctx: EmitterVisitorContext, defaultType: string = 'any') {
if (t != null) {
visitType(t: o.Type|null, ctx: EmitterVisitorContext, defaultType: string = 'any') {
if (t) {
this.typeExpression++;
t.visitType(this, ctx);
this.typeExpression--;
@ -133,7 +133,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
if (ctx.isExportedVar(stmt.name) && stmt.value instanceof o.ExternalExpr && !stmt.type) {
// check for a reexport
const {name, filePath, members} = this._resolveStaticSymbol(stmt.value.value);
if (members.length === 0 && filePath !== this._genFilePath) {
if (members !.length === 0 && filePath !== this._genFilePath) {
let reexports = this.reexports.get(filePath);
if (!reexports) {
reexports = [];
@ -161,7 +161,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
visitCastExpr(ast: o.CastExpr, ctx: EmitterVisitorContext): any {
ctx.print(ast, `(<`);
ast.type.visitType(this, ctx);
ast.type !.visitType(this, ctx);
ctx.print(ast, `>`);
ast.value.visitExpression(this, ctx);
ctx.print(ast, `)`);
@ -290,7 +290,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
ctx.println(stmt, `} catch (${CATCH_ERROR_VAR.name}) {`);
ctx.incIndent();
const catchStmts =
[<o.Statement>CATCH_STACK_VAR.set(CATCH_ERROR_VAR.prop('stack')).toDeclStmt(null, [
[<o.Statement>CATCH_STACK_VAR.set(CATCH_ERROR_VAR.prop('stack', null)).toDeclStmt(null, [
o.StmtModifier.Final
])].concat(stmt.catchStmts);
this.visitAllStatements(catchStmts, ctx);
@ -386,7 +386,8 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
}
private _visitIdentifier(
value: CompileIdentifierMetadata, typeParams: o.Type[], ctx: EmitterVisitorContext): void {
value: CompileIdentifierMetadata, typeParams: o.Type[]|null,
ctx: EmitterVisitorContext): void {
const {name, filePath, members, arity} = this._resolveStaticSymbol(value);
if (filePath != this._genFilePath) {
let prefix = this.importsWithPrefixes.get(filePath);
@ -396,10 +397,10 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
}
ctx.print(null, `${prefix}.`);
}
if (members.length) {
if (members !.length) {
ctx.print(null, name);
ctx.print(null, '.');
ctx.print(null, members.join('.'));
ctx.print(null, members !.join('.'));
} else {
ctx.print(null, name);
}
@ -415,7 +416,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
if (suppliedParameters > 0 || additionalParameters > 0) {
ctx.print(null, `<`);
if (suppliedParameters > 0) {
this.visitAllObjects(type => type.visitType(this, ctx), typeParams, ctx, ',');
this.visitAllObjects(type => type.visitType(this, ctx), typeParams !, ctx, ',');
}
if (additionalParameters > 0) {
for (let i = 0; i < additionalParameters; i++) {
@ -428,7 +429,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
}
}
private _printColonType(type: o.Type, ctx: EmitterVisitorContext, defaultType?: string) {
private _printColonType(type: o.Type|null, ctx: EmitterVisitorContext, defaultType?: string) {
if (type !== o.INFERRED_TYPE) {
ctx.print(null, ':');
this.visitType(type, ctx, defaultType);

View File

@ -13,7 +13,7 @@ import * as o from './output_ast';
export const QUOTED_KEYS = '$quoted$';
export function convertValueToOutputAst(value: any, type: o.Type = null): o.Expression {
export function convertValueToOutputAst(value: any, type: o.Type | null = null): o.Expression {
return visitValue(value, new _ValueOutputAstTransformer(), type);
}

View File

@ -51,7 +51,7 @@ export class ParseLocation {
// Return the source around the location
// Up to `maxChars` or `maxLines` on each side of the location
getContext(maxChars: number, maxLines: number): {before: string, after: string} {
getContext(maxChars: number, maxLines: number): {before: string, after: string}|null {
const content = this.file.content;
let startOffset = this.offset;
@ -101,7 +101,7 @@ export class ParseSourceFile {
export class ParseSourceSpan {
constructor(
public start: ParseLocation, public end: ParseLocation, public details: string = null) {}
public start: ParseLocation, public end: ParseLocation, public details: string|null = null) {}
toString(): string {
return this.start.file.content.substring(this.start.offset, this.end.offset);
@ -133,6 +133,5 @@ export function typeSourceSpan(kind: string, type: CompileIdentifierMetadata): P
`in ${kind} ${identifierName(type)}`;
const sourceFile = new ParseSourceFile('', sourceFileName);
return new ParseSourceSpan(
new ParseLocation(sourceFile, null, null, null),
new ParseLocation(sourceFile, null, null, null));
new ParseLocation(sourceFile, -1, -1, -1), new ParseLocation(sourceFile, -1, -1, -1));
}

View File

@ -33,7 +33,7 @@ export class PipeResolver {
/**
* Return {@link Pipe} for a given `Type`.
*/
resolve(type: Type<any>, throwIfNotFound = true): Pipe {
resolve(type: Type<any>, throwIfNotFound = true): Pipe|null {
const metas = this._reflector.annotations(resolveForwardRef(type));
if (metas) {
const annotation = findLast(metas, _isPipeMetadata);

View File

@ -135,7 +135,7 @@ export class ProviderElementContext {
const result: QueryWithId[] = [];
let currentEl: ProviderElementContext = this;
let distance = 0;
let queries: QueryWithId[];
let queries: QueryWithId[]|undefined;
while (currentEl !== null) {
queries = currentEl._contentQueries.get(tokenReference(token));
if (queries) {
@ -156,7 +156,7 @@ export class ProviderElementContext {
private _getOrCreateLocalProvider(
requestingProviderType: ProviderAstType, token: CompileTokenMetadata,
eager: boolean): ProviderAst {
eager: boolean): ProviderAst|null {
const resolvedProvider = this._allProviders.get(tokenReference(token));
if (!resolvedProvider || ((requestingProviderType === ProviderAstType.Directive ||
requestingProviderType === ProviderAstType.PublicService) &&
@ -178,25 +178,25 @@ export class ProviderElementContext {
this._seenProviders.set(tokenReference(token), true);
const transformedProviders = resolvedProvider.providers.map((provider) => {
let transformedUseValue = provider.useValue;
let transformedUseExisting = provider.useExisting;
let transformedDeps: CompileDiDependencyMetadata[];
let transformedUseExisting = provider.useExisting !;
let transformedDeps: CompileDiDependencyMetadata[] = undefined !;
if (provider.useExisting != null) {
const existingDiDep = this._getDependency(
resolvedProvider.providerType, {token: provider.useExisting}, eager);
resolvedProvider.providerType, {token: provider.useExisting}, eager) !;
if (existingDiDep.token != null) {
transformedUseExisting = existingDiDep.token;
} else {
transformedUseExisting = null;
transformedUseExisting = null !;
transformedUseValue = existingDiDep.value;
}
} else if (provider.useFactory) {
const deps = provider.deps || provider.useFactory.diDeps;
transformedDeps =
deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep, eager));
deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep, eager) !);
} else if (provider.useClass) {
const deps = provider.deps || provider.useClass.diDeps;
transformedDeps =
deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep, eager));
deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep, eager) !);
}
return _transformProvider(provider, {
useExisting: transformedUseExisting,
@ -212,9 +212,9 @@ export class ProviderElementContext {
private _getLocalDependency(
requestingProviderType: ProviderAstType, dep: CompileDiDependencyMetadata,
eager: boolean = null): CompileDiDependencyMetadata {
eager: boolean = false): CompileDiDependencyMetadata|null {
if (dep.isAttribute) {
const attrValue = this._attrs[dep.token.value];
const attrValue = this._attrs[dep.token !.value];
return {isValue: true, value: attrValue == null ? null : attrValue};
}
@ -246,10 +246,10 @@ export class ProviderElementContext {
private _getDependency(
requestingProviderType: ProviderAstType, dep: CompileDiDependencyMetadata,
eager: boolean = null): CompileDiDependencyMetadata {
eager: boolean = false): CompileDiDependencyMetadata|null {
let currElement: ProviderElementContext = this;
let currEager: boolean = eager;
let result: CompileDiDependencyMetadata = null;
let result: CompileDiDependencyMetadata|null = null;
if (!dep.isSkipSelf) {
result = this._getLocalDependency(requestingProviderType, dep, eager);
}
@ -270,8 +270,8 @@ export class ProviderElementContext {
// check @Host restriction
if (!result) {
if (!dep.isHost || this.viewContext.component.isHost ||
this.viewContext.component.type.reference === tokenReference(dep.token) ||
this.viewContext.viewProviders.get(tokenReference(dep.token)) != null) {
this.viewContext.component.type.reference === tokenReference(dep.token !) ||
this.viewContext.viewProviders.get(tokenReference(dep.token !)) != null) {
result = dep;
} else {
result = dep.isOptional ? result = {isValue: true, value: null} : null;
@ -280,7 +280,7 @@ export class ProviderElementContext {
}
if (!result) {
this.viewContext.errors.push(
new ProviderError(`No provider for ${tokenName(dep.token)}`, this._sourceSpan));
new ProviderError(`No provider for ${tokenName(dep.token!)}`, this._sourceSpan));
}
return result;
}
@ -319,7 +319,7 @@ export class NgModuleProviderAnalyzer {
return Array.from(this._transformedProviders.values());
}
private _getOrCreateLocalProvider(token: CompileTokenMetadata, eager: boolean): ProviderAst {
private _getOrCreateLocalProvider(token: CompileTokenMetadata, eager: boolean): ProviderAst|null {
const resolvedProvider = this._allProviders.get(tokenReference(token));
if (!resolvedProvider) {
return null;
@ -337,15 +337,15 @@ export class NgModuleProviderAnalyzer {
this._seenProviders.set(tokenReference(token), true);
const transformedProviders = resolvedProvider.providers.map((provider) => {
let transformedUseValue = provider.useValue;
let transformedUseExisting = provider.useExisting;
let transformedDeps: CompileDiDependencyMetadata[];
let transformedUseExisting = provider.useExisting !;
let transformedDeps: CompileDiDependencyMetadata[] = undefined !;
if (provider.useExisting != null) {
const existingDiDep =
this._getDependency({token: provider.useExisting}, eager, resolvedProvider.sourceSpan);
if (existingDiDep.token != null) {
transformedUseExisting = existingDiDep.token;
} else {
transformedUseExisting = null;
transformedUseExisting = null !;
transformedUseValue = existingDiDep.value;
}
} else if (provider.useFactory) {
@ -370,7 +370,7 @@ export class NgModuleProviderAnalyzer {
}
private _getDependency(
dep: CompileDiDependencyMetadata, eager: boolean = null,
dep: CompileDiDependencyMetadata, eager: boolean = false,
requestorSourceSpan: ParseSourceSpan): CompileDiDependencyMetadata {
let foundLocal = false;
if (!dep.isSkipSelf && dep.token != null) {
@ -389,7 +389,7 @@ export class NgModuleProviderAnalyzer {
result = {isValue: true, value: null};
} else {
this._errors.push(
new ProviderError(`No provider for ${tokenName(dep.token)}`, requestorSourceSpan));
new ProviderError(`No provider for ${tokenName(dep.token!)}`, requestorSourceSpan));
}
}
return result;
@ -464,7 +464,7 @@ function _resolveProviders(
[];
const isUseValue = !(provider.useClass || provider.useExisting || provider.useFactory);
resolvedProvider = new ProviderAst(
provider.token, provider.multi, eager || isUseValue, [provider], providerType,
provider.token, !!provider.multi, eager || isUseValue, [provider], providerType,
lifecycleHooks, sourceSpan);
targetProvidersByToken.set(tokenReference(provider.token), resolvedProvider);
} else {

View File

@ -11,5 +11,5 @@
* to load templates.
*/
export class ResourceLoader {
get(url: string): Promise<string> { return null; }
get(url: string): Promise<string>|null { return null; }
}

View File

@ -386,7 +386,7 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry {
{error: string, value: string} {
let unit: string = '';
const strVal = val.toString().trim();
let errorMsg: string = null;
let errorMsg: string = null !;
if (_isPixelDimensionStyle(camelCaseProp) && val !== 0 && val !== '0') {
if (typeof val === 'number') {

View File

@ -26,7 +26,7 @@ const _SELECTOR_REGEXP = new RegExp(
* of selecting subsets out of them.
*/
export class CssSelector {
element: string = null;
element: string|null = null;
classNames: string[] = [];
attrs: string[] = [];
notSelectors: CssSelector[] = [];
@ -41,7 +41,7 @@ export class CssSelector {
res.push(cssSel);
};
let cssSelector = new CssSelector();
let match: string[];
let match: string[]|null;
let current = cssSelector;
let inNot = false;
_SELECTOR_REGEXP.lastIndex = 0;
@ -86,7 +86,7 @@ export class CssSelector {
hasElementSelector(): boolean { return !!this.element; }
setElement(element: string = null) { this.element = element; }
setElement(element: string|null = null) { this.element = element; }
/** Gets a template string for an element that matches the selector. */
getMatchingElementTemplate(): string {
@ -147,7 +147,7 @@ export class SelectorMatcher {
private _listContexts: SelectorListContext[] = [];
addSelectables(cssSelectors: CssSelector[], callbackCtxt?: any) {
let listContext: SelectorListContext = null;
let listContext: SelectorListContext = null !;
if (cssSelectors.length > 1) {
listContext = new SelectorListContext(cssSelectors);
this._listContexts.push(listContext);
@ -243,9 +243,10 @@ export class SelectorMatcher {
* @param matchedCallback This callback will be called with the object handed into `addSelectable`
* @return boolean true if a match was found
*/
match(cssSelector: CssSelector, matchedCallback: (c: CssSelector, a: any) => void): boolean {
match(cssSelector: CssSelector, matchedCallback: ((c: CssSelector, a: any) => void)|null):
boolean {
let result = false;
const element = cssSelector.element;
const element = cssSelector.element !;
const classNames = cssSelector.classNames;
const attrs = cssSelector.attrs;
@ -273,7 +274,7 @@ export class SelectorMatcher {
const name = attrs[i];
const value = attrs[i + 1];
const terminalValuesMap = this._attrValueMap.get(name);
const terminalValuesMap = this._attrValueMap.get(name) !;
if (value) {
result =
this._matchTerminal(terminalValuesMap, '', cssSelector, matchedCallback) || result;
@ -281,7 +282,7 @@ export class SelectorMatcher {
result =
this._matchTerminal(terminalValuesMap, value, cssSelector, matchedCallback) || result;
const partialValuesMap = this._attrValuePartialMap.get(name);
const partialValuesMap = this._attrValuePartialMap.get(name) !;
if (value) {
result = this._matchPartial(partialValuesMap, '', cssSelector, matchedCallback) || result;
}
@ -295,13 +296,13 @@ export class SelectorMatcher {
/** @internal */
_matchTerminal(
map: Map<string, SelectorContext[]>, name: string, cssSelector: CssSelector,
matchedCallback: (c: CssSelector, a: any) => void): boolean {
matchedCallback: ((c: CssSelector, a: any) => void)|null): boolean {
if (!map || typeof name !== 'string') {
return false;
}
let selectables: SelectorContext[] = map.get(name) || [];
const starSelectables: SelectorContext[] = map.get('*');
const starSelectables: SelectorContext[] = map.get('*') !;
if (starSelectables) {
selectables = selectables.concat(starSelectables);
}
@ -320,7 +321,7 @@ export class SelectorMatcher {
/** @internal */
_matchPartial(
map: Map<string, SelectorMatcher>, name: string, cssSelector: CssSelector,
matchedCallback: (c: CssSelector, a: any) => void): boolean {
matchedCallback: ((c: CssSelector, a: any) => void)|null): boolean {
if (!map || typeof name !== 'string') {
return false;
}
@ -353,7 +354,7 @@ export class SelectorContext {
this.notSelectors = selector.notSelectors;
}
finalize(cssSelector: CssSelector, callback: (c: CssSelector, a: any) => void): boolean {
finalize(cssSelector: CssSelector, callback: ((c: CssSelector, a: any) => void)|null): boolean {
let result = true;
if (this.notSelectors.length > 0 && (!this.listContext || !this.listContext.alreadyMatched)) {
const notMatcher = SelectorMatcher.createNotMatcher(this.notSelectors);

View File

@ -240,7 +240,7 @@ export class ShadowCss {
private _extractUnscopedRulesFromCssText(cssText: string): string {
// Difference with webcomponents.js: does not handle comments
let r = '';
let m: RegExpExecArray;
let m: RegExpExecArray|null;
_cssContentUnscopedRuleRe.lastIndex = 0;
while ((m = _cssContentUnscopedRuleRe.exec(cssText)) !== null) {
const rule = m[0].replace(m[2], '').replace(m[1], m[4]);
@ -433,7 +433,7 @@ export class ShadowCss {
let scopedSelector = '';
let startIndex = 0;
let res: RegExpExecArray;
let res: RegExpExecArray|null;
const sep = /( |>|\+|~(?!=))\s*/g;
const scopeAfter = selector.indexOf(_polyfillHostNoCombinator);

View File

@ -44,15 +44,16 @@ export class StyleCompiler {
constructor(private _urlResolver: UrlResolver) {}
compileComponent(comp: CompileDirectiveMetadata): StylesCompileResult {
const template = comp.template !;
const externalStylesheets: CompiledStylesheet[] = [];
const componentStylesheet: CompiledStylesheet = this._compileStyles(
comp, new CompileStylesheetMetadata({
styles: comp.template.styles,
styleUrls: comp.template.styleUrls,
styles: template.styles,
styleUrls: template.styleUrls,
moduleUrl: identifierModuleUrl(comp.type)
}),
true);
comp.template.externalStylesheets.forEach((stylesheetMeta) => {
template.externalStylesheets.forEach((stylesheetMeta) => {
const compiledStylesheet = this._compileStyles(comp, stylesheetMeta, false);
externalStylesheets.push(compiledStylesheet);
});
@ -62,7 +63,7 @@ export class StyleCompiler {
private _compileStyles(
comp: CompileDirectiveMetadata, stylesheet: CompileStylesheetMetadata,
isComponentStylesheet: boolean): CompiledStylesheet {
const shim = comp.template.encapsulation === ViewEncapsulation.Emulated;
const shim = comp.template !.encapsulation === ViewEncapsulation.Emulated;
const styleExpressions =
stylesheet.styles.map(plainStyle => o.literal(this._shimIfNeeded(plainStyle, shim)));
const dependencies: StylesCompileDependency[] = [];
@ -87,7 +88,7 @@ export class StyleCompiler {
}
}
function getStylesVarName(component: CompileDirectiveMetadata): string {
function getStylesVarName(component: CompileDirectiveMetadata | null): string {
let result = `styles`;
if (component) {
result += `_${identifierName(component.type)}`;

View File

@ -17,8 +17,8 @@ export interface Summary<T> {
@CompilerInjectable()
export class SummaryResolver<T> {
isLibraryFile(fileName: string): boolean { return false; };
getLibraryFileName(fileName: string): string { return null; }
resolveSummary(reference: T): Summary<T> { return null; };
getLibraryFileName(fileName: string): string|null { return null; }
resolveSummary(reference: T): Summary<T>|null { return null; };
getSymbolsOf(filePath: string): T[] { return []; }
getImportAs(reference: T): T { return reference; }
}

View File

@ -64,7 +64,7 @@ export class BindingParser {
createDirectiveHostPropertyAsts(
dirMeta: CompileDirectiveSummary, elementSelector: string,
sourceSpan: ParseSourceSpan): BoundElementPropertyAst[] {
sourceSpan: ParseSourceSpan): BoundElementPropertyAst[]|null {
if (dirMeta.hostProperties) {
const boundProps: BoundProperty[] = [];
Object.keys(dirMeta.hostProperties).forEach(propName => {
@ -79,10 +79,11 @@ export class BindingParser {
});
return boundProps.map((prop) => this.createElementPropertyAst(elementSelector, prop));
}
return null;
}
createDirectiveHostEventAsts(dirMeta: CompileDirectiveSummary, sourceSpan: ParseSourceSpan):
BoundEventAst[] {
BoundEventAst[]|null {
if (dirMeta.hostListeners) {
const targetEventAsts: BoundEventAst[] = [];
Object.keys(dirMeta.hostListeners).forEach(propName => {
@ -97,13 +98,15 @@ export class BindingParser {
});
return targetEventAsts;
}
return null;
}
parseInterpolation(value: string, sourceSpan: ParseSourceSpan): ASTWithSource {
const sourceInfo = sourceSpan.start.toString();
try {
const ast = this._exprParser.parseInterpolation(value, sourceInfo, this._interpolationConfig);
const ast =
this._exprParser.parseInterpolation(value, sourceInfo, this._interpolationConfig) !;
if (ast) this._reportExpressionParserErrors(ast.errors, sourceSpan);
this._checkPipes(ast, sourceSpan);
return ast;
@ -153,8 +156,8 @@ export class BindingParser {
}
parseLiteralAttr(
name: string, value: string, sourceSpan: ParseSourceSpan, targetMatchableAttrs: string[][],
targetProps: BoundProperty[]) {
name: string, value: string|null, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetProps: BoundProperty[]) {
if (_isAnimationLabel(name)) {
name = name.substring(1);
if (value) {
@ -206,18 +209,18 @@ export class BindingParser {
private _parsePropertyAst(
name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetProps: BoundProperty[]) {
targetMatchableAttrs.push([name, ast.source]);
targetMatchableAttrs.push([name, ast.source !]);
targetProps.push(new BoundProperty(name, ast, BoundPropertyType.DEFAULT, sourceSpan));
}
private _parseAnimation(
name: string, expression: string, sourceSpan: ParseSourceSpan,
name: string, expression: string|null, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetProps: BoundProperty[]) {
// This will occur when a @trigger is not paired with an expression.
// For animations it is valid to not have an expression since */void
// states will be applied by angular when the element is attached/detached
const ast = this._parseBinding(expression || 'null', false, sourceSpan);
targetMatchableAttrs.push([name, ast.source]);
targetMatchableAttrs.push([name, ast.source !]);
targetProps.push(new BoundProperty(name, ast, BoundPropertyType.ANIMATION, sourceSpan));
}
@ -246,11 +249,11 @@ export class BindingParser {
null, boundProp.sourceSpan);
}
let unit: string = null;
let bindingType: PropertyBindingType;
let boundPropertyName: string = null;
let unit: string|null = null;
let bindingType: PropertyBindingType = undefined !;
let boundPropertyName: string|null = null;
const parts = boundProp.name.split(PROPERTY_PARTS_SEPARATOR);
let securityContexts: SecurityContext[];
let securityContexts: SecurityContext[] = undefined !;
// Check check for special cases (prefix style, attr, class)
if (parts.length > 1) {
@ -336,9 +339,9 @@ export class BindingParser {
name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
// long format: 'target: eventName'
const [target, eventName] = splitAtColon(name, [null, name]);
const [target, eventName] = splitAtColon(name, [null !, name]);
const ast = this._parseAction(expression, sourceSpan);
targetMatchableAttrs.push([name, ast.source]);
targetMatchableAttrs.push([name !, ast.source !]);
targetEvents.push(new BoundEventAst(eventName, target, null, ast, sourceSpan));
// Don't detect directives for event names for now,
// so don't add the event name to the matchableAttrs
@ -405,7 +408,7 @@ export class BindingParser {
const report = isAttr ? this._schemaRegistry.validateAttribute(propName) :
this._schemaRegistry.validateProperty(propName);
if (report.error) {
this._reportError(report.msg, sourceSpan, ParseErrorLevel.ERROR);
this._reportError(report.msg !, sourceSpan, ParseErrorLevel.ERROR);
}
}
}

View File

@ -19,7 +19,7 @@ export interface TemplateAst {
/**
* The source span from which this node was parsed.
*/
sourceSpan: ParseSourceSpan;
sourceSpan: ParseSourceSpan|null;
/**
* Visit this node and possibly transform it.
@ -62,7 +62,7 @@ export class AttrAst implements TemplateAst {
export class BoundElementPropertyAst implements TemplateAst {
constructor(
public name: string, public type: PropertyBindingType,
public securityContext: SecurityContext, public value: AST, public unit: string,
public securityContext: SecurityContext, public value: AST, public unit: string|null,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitElementProperty(this, context);
@ -75,7 +75,7 @@ export class BoundElementPropertyAst implements TemplateAst {
* `(@trigger.phase)="callback($event)"`).
*/
export class BoundEventAst implements TemplateAst {
static calcFullName(name: string, target: string, phase: string): string {
static calcFullName(name: string, target: string|null, phase: string|null): string {
if (target) {
return `${target}:${name}`;
} else if (phase) {
@ -86,8 +86,8 @@ export class BoundEventAst implements TemplateAst {
}
constructor(
public name: string, public target: string, public phase: string, public handler: AST,
public sourceSpan: ParseSourceSpan) {}
public name: string, public target: string|null, public phase: string|null,
public handler: AST, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitEvent(this, context);
}
@ -126,8 +126,8 @@ export class ElementAst implements TemplateAst {
public outputs: BoundEventAst[], public references: ReferenceAst[],
public directives: DirectiveAst[], public providers: ProviderAst[],
public hasViewContainer: boolean, public queryMatches: QueryMatch[],
public children: TemplateAst[], public ngContentIndex: number,
public sourceSpan: ParseSourceSpan, public endSourceSpan: ParseSourceSpan) {}
public children: TemplateAst[], public ngContentIndex: number|null,
public sourceSpan: ParseSourceSpan|null, public endSourceSpan: ParseSourceSpan|null) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitElement(this, context);
@ -275,7 +275,7 @@ export function templateVisitAll(
visitor: TemplateAstVisitor, asts: TemplateAst[], context: any = null): any[] {
const result: any[] = [];
const visit = visitor.visit ?
(ast: TemplateAst) => visitor.visit(ast, context) || ast.visit(visitor, context) :
(ast: TemplateAst) => visitor.visit !(ast, context) || ast.visit(visitor, context) :
(ast: TemplateAst) => ast.visit(visitor, context);
asts.forEach(ast => {
const astResult = visit(ast);

View File

@ -115,11 +115,11 @@ export class TemplateParser {
templateUrl: string): {template: TemplateAst[], pipes: CompilePipeSummary[]} {
const result = this.tryParse(component, template, directives, pipes, schemas, templateUrl);
const warnings =
result.errors.filter(error => error.level === ParseErrorLevel.WARNING).filter(warnOnlyOnce([
TEMPLATE_ATTR_DEPRECATION_WARNING, TEMPLATE_ELEMENT_DEPRECATION_WARNING
]));
result.errors !.filter(error => error.level === ParseErrorLevel.WARNING)
.filter(warnOnlyOnce(
[TEMPLATE_ATTR_DEPRECATION_WARNING, TEMPLATE_ELEMENT_DEPRECATION_WARNING]));
const errors = result.errors.filter(error => error.level === ParseErrorLevel.ERROR);
const errors = result.errors !.filter(error => error.level === ParseErrorLevel.ERROR);
if (warnings.length > 0) {
this._console.warn(`Template parse warnings:\n${warnings.join('\n')}`);
@ -130,7 +130,7 @@ export class TemplateParser {
throw syntaxError(`Template parse errors:\n${errorString}`);
}
return {template: result.templateAst, pipes: result.usedPipes};
return {template: result.templateAst !, pipes: result.usedPipes !};
}
tryParse(
@ -138,7 +138,7 @@ export class TemplateParser {
pipes: CompilePipeSummary[], schemas: SchemaMetadata[],
templateUrl: string): TemplateParseResult {
return this.tryParseHtml(
this.expandHtml(this._htmlParser.parse(
this.expandHtml(this._htmlParser !.parse(
template, templateUrl, true, this.getInterpolationConfig(component))),
component, template, directives, pipes, schemas, templateUrl);
}
@ -154,7 +154,7 @@ export class TemplateParser {
const uniqDirectives = removeSummaryDuplicates(directives);
const uniqPipes = removeSummaryDuplicates(pipes);
const providerViewContext = new ProviderViewContext(component);
let interpolationConfig: InterpolationConfig;
let interpolationConfig: InterpolationConfig = undefined !;
if (component.template && component.template.interpolation) {
interpolationConfig = {
start: component.template.interpolation[0],
@ -162,7 +162,7 @@ export class TemplateParser {
};
}
const bindingParser = new BindingParser(
this._exprParser, interpolationConfig, this._schemaRegistry, uniqPipes, errors);
this._exprParser, interpolationConfig !, this._schemaRegistry, uniqPipes, errors);
const parseVisitor = new TemplateParseVisitor(
this._config, providerViewContext, uniqDirectives, bindingParser, this._schemaRegistry,
schemas, errors);
@ -198,10 +198,11 @@ export class TemplateParser {
return htmlAstWithErrors;
}
getInterpolationConfig(component: CompileDirectiveMetadata): InterpolationConfig {
getInterpolationConfig(component: CompileDirectiveMetadata): InterpolationConfig|undefined {
if (component.template) {
return InterpolationConfig.fromArray(component.template.interpolation);
}
return undefined;
}
/** @internal */
@ -238,7 +239,7 @@ class TemplateParseVisitor implements html.Visitor {
// Note: queries start with id 1 so we can use the number in a Bloom filter!
this.contentQueryStartId = providerViewContext.component.viewQueries.length + 1;
directives.forEach((directive, index) => {
const selector = CssSelector.parse(directive.selector);
const selector = CssSelector.parse(directive.selector !);
this.selectorMatcher.addSelectables(selector, directive);
this.directivesIndex.set(directive, index);
});
@ -249,10 +250,10 @@ class TemplateParseVisitor implements html.Visitor {
visitExpansionCase(expansionCase: html.ExpansionCase, context: any): any { return null; }
visitText(text: html.Text, parent: ElementContext): any {
const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR);
const expr = this._bindingParser.parseInterpolation(text.value, text.sourceSpan);
return expr ? new BoundTextAst(expr, ngContentIndex, text.sourceSpan) :
new TextAst(text.value, ngContentIndex, text.sourceSpan);
const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR) !;
const expr = this._bindingParser.parseInterpolation(text.value, text.sourceSpan !);
return expr ? new BoundTextAst(expr, ngContentIndex, text.sourceSpan !) :
new TextAst(text.value, ngContentIndex, text.sourceSpan !);
}
visitAttribute(attribute: html.Attribute, context: any): any {
@ -322,7 +323,7 @@ class TemplateParseVisitor implements html.Visitor {
}
hasInlineTemplates = true;
this._bindingParser.parseInlineTemplateBinding(
prefixToken, templateBindingsSource, attr.sourceSpan, templateMatchableAttrs,
prefixToken !, templateBindingsSource !, attr.sourceSpan, templateMatchableAttrs,
templateElementOrDirectiveProps, templateElementVars);
}
@ -340,48 +341,49 @@ class TemplateParseVisitor implements html.Visitor {
const boundDirectivePropNames = new Set<string>();
const directiveAsts = this._createDirectiveAsts(
isTemplateElement, element.name, directiveMetas, elementOrDirectiveProps,
elementOrDirectiveRefs, element.sourceSpan, references, boundDirectivePropNames);
elementOrDirectiveRefs, element.sourceSpan !, references, boundDirectivePropNames);
const elementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts(
element.name, elementOrDirectiveProps, boundDirectivePropNames);
const isViewRoot = parent.isTemplateElement || hasInlineTemplates;
const providerContext = new ProviderElementContext(
this.providerViewContext, parent.providerContext, isViewRoot, directiveAsts, attrs,
references, isTemplateElement, queryStartIndex, element.sourceSpan);
this.providerViewContext, parent.providerContext !, isViewRoot, directiveAsts, attrs,
references, isTemplateElement, queryStartIndex, element.sourceSpan !);
const children: TemplateAst[] = html.visitAll(
preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children,
ElementContext.create(
isTemplateElement, directiveAsts,
isTemplateElement ? parent.providerContext : providerContext));
isTemplateElement ? parent.providerContext ! : providerContext));
providerContext.afterElement();
// Override the actual selector when the `ngProjectAs` attribute is provided
const projectionSelector = preparsedElement.projectAs != null ?
CssSelector.parse(preparsedElement.projectAs)[0] :
elementCssSelector;
const ngContentIndex = parent.findNgContentIndex(projectionSelector);
const ngContentIndex = parent.findNgContentIndex(projectionSelector) !;
let parsedElement: TemplateAst;
if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
if (element.children && !element.children.every(_isEmptyTextNode)) {
this._reportError(`<ng-content> element cannot have content.`, element.sourceSpan);
this._reportError(`<ng-content> element cannot have content.`, element.sourceSpan !);
}
parsedElement = new NgContentAst(
this.ngContentCount++, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
this.ngContentCount++, hasInlineTemplates ? null ! : ngContentIndex,
element.sourceSpan !);
} else if (isTemplateElement) {
this._assertAllEventsPublishedByDirectives(directiveAsts, events);
this._assertNoComponentsNorElementBindingsOnTemplate(
directiveAsts, elementProps, element.sourceSpan);
directiveAsts, elementProps, element.sourceSpan !);
parsedElement = new EmbeddedTemplateAst(
attrs, events, references, elementVars, providerContext.transformedDirectiveAsts,
providerContext.transformProviders, providerContext.transformedHasViewContainer,
providerContext.queryMatches, children, hasInlineTemplates ? null : ngContentIndex,
element.sourceSpan);
providerContext.queryMatches, children, hasInlineTemplates ? null ! : ngContentIndex,
element.sourceSpan !);
} else {
this._assertElementExists(matchElement, element);
this._assertOnlyOneComponent(directiveAsts, element.sourceSpan);
this._assertOnlyOneComponent(directiveAsts, element.sourceSpan !);
const ngContentIndex =
hasInlineTemplates ? null : parent.findNgContentIndex(projectionSelector);
@ -389,7 +391,8 @@ class TemplateParseVisitor implements html.Visitor {
nodeName, attrs, elementProps, events, references,
providerContext.transformedDirectiveAsts, providerContext.transformProviders,
providerContext.transformedHasViewContainer, providerContext.queryMatches, children,
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan, element.endSourceSpan);
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan || null,
element.endSourceSpan || null);
}
if (hasInlineTemplates) {
@ -400,21 +403,21 @@ class TemplateParseVisitor implements html.Visitor {
const templateBoundDirectivePropNames = new Set<string>();
const templateDirectiveAsts = this._createDirectiveAsts(
true, element.name, templateDirectiveMetas, templateElementOrDirectiveProps, [],
element.sourceSpan, [], templateBoundDirectivePropNames);
element.sourceSpan !, [], templateBoundDirectivePropNames);
const templateElementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts(
element.name, templateElementOrDirectiveProps, templateBoundDirectivePropNames);
this._assertNoComponentsNorElementBindingsOnTemplate(
templateDirectiveAsts, templateElementProps, element.sourceSpan);
templateDirectiveAsts, templateElementProps, element.sourceSpan !);
const templateProviderContext = new ProviderElementContext(
this.providerViewContext, parent.providerContext, parent.isTemplateElement,
templateDirectiveAsts, [], [], true, templateQueryStartIndex, element.sourceSpan);
this.providerViewContext, parent.providerContext !, parent.isTemplateElement,
templateDirectiveAsts, [], [], true, templateQueryStartIndex, element.sourceSpan !);
templateProviderContext.afterElement();
parsedElement = new EmbeddedTemplateAst(
[], [], [], templateElementVars, templateProviderContext.transformedDirectiveAsts,
templateProviderContext.transformProviders,
templateProviderContext.transformedHasViewContainer, templateProviderContext.queryMatches,
[parsedElement], ngContentIndex, element.sourceSpan);
[parsedElement], ngContentIndex, element.sourceSpan !);
}
return parsedElement;
@ -531,7 +534,7 @@ class TemplateParseVisitor implements html.Visitor {
let matchElement = false;
selectorMatcher.match(elementCssSelector, (selector, directive) => {
directives[this.directivesIndex.get(directive)] = directive;
directives[this.directivesIndex.get(directive) !] = directive;
matchElement = matchElement || selector.hasElementSelector();
});
@ -547,7 +550,7 @@ class TemplateParseVisitor implements html.Visitor {
elementSourceSpan: ParseSourceSpan, targetReferences: ReferenceAst[],
targetBoundDirectivePropNames: Set<string>): DirectiveAst[] {
const matchedReferences = new Set<string>();
let component: CompileDirectiveSummary = null;
let component: CompileDirectiveSummary = null !;
const directiveAsts = directives.map((directive) => {
const sourceSpan = new ParseSourceSpan(
@ -559,11 +562,11 @@ class TemplateParseVisitor implements html.Visitor {
}
const directiveProperties: BoundDirectivePropertyAst[] = [];
let hostProperties =
this._bindingParser.createDirectiveHostPropertyAsts(directive, elementName, sourceSpan);
this._bindingParser.createDirectiveHostPropertyAsts(directive, elementName, sourceSpan) !;
// Note: We need to check the host properties here as well,
// as we don't know the element name in the DirectiveWrapperCompiler yet.
hostProperties = this._checkPropertiesInSchema(elementName, hostProperties);
const hostEvents = this._bindingParser.createDirectiveHostEventAsts(directive, sourceSpan);
const hostEvents = this._bindingParser.createDirectiveHostEventAsts(directive, sourceSpan) !;
this._createDirectivePropertyAsts(
directive.inputs, props, directiveProperties, targetBoundDirectivePropNames);
elementOrDirectiveRefs.forEach((elOrDirRef) => {
@ -589,7 +592,7 @@ class TemplateParseVisitor implements html.Visitor {
elOrDirRef.sourceSpan);
}
} else if (!component) {
let refToken: CompileTokenMetadata = null;
let refToken: CompileTokenMetadata = null !;
if (isTemplateElement) {
refToken = createIdentifierToken(Identifiers.TemplateRef);
}
@ -648,7 +651,7 @@ class TemplateParseVisitor implements html.Visitor {
private _findComponentDirectiveNames(directives: DirectiveAst[]): string[] {
return this._findComponentDirectives(directives)
.map(directive => identifierName(directive.directive.type));
.map(directive => identifierName(directive.directive.type) !);
}
private _assertOnlyOneComponent(directives: DirectiveAst[], sourceSpan: ParseSourceSpan) {
@ -685,7 +688,7 @@ class TemplateParseVisitor implements html.Visitor {
errorMsg +=
`2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`;
}
this._reportError(errorMsg, element.sourceSpan);
this._reportError(errorMsg, element.sourceSpan !);
}
}
@ -757,7 +760,7 @@ class TemplateParseVisitor implements html.Visitor {
}
class NonBindableVisitor implements html.Visitor {
visitElement(ast: html.Element, parent: ElementContext): ElementAst {
visitElement(ast: html.Element, parent: ElementContext): ElementAst|null {
const preparsedElement = preparseElement(ast);
if (preparsedElement.type === PreparsedElementType.SCRIPT ||
preparsedElement.type === PreparsedElementType.STYLE ||
@ -783,8 +786,8 @@ class NonBindableVisitor implements html.Visitor {
}
visitText(text: html.Text, parent: ElementContext): TextAst {
const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR);
return new TextAst(text.value, ngContentIndex, text.sourceSpan);
const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR) !;
return new TextAst(text.value, ngContentIndex, text.sourceSpan !);
}
visitExpansion(expansion: html.Expansion, context: any): any { return expansion; }
@ -805,10 +808,10 @@ class ElementContext {
isTemplateElement: boolean, directives: DirectiveAst[],
providerContext: ProviderElementContext): ElementContext {
const matcher = new SelectorMatcher();
let wildcardNgContentIndex: number = null;
let wildcardNgContentIndex: number = null !;
const component = directives.find(directive => directive.directive.isComponent);
if (component) {
const ngContentSelectors = component.directive.template.ngContentSelectors;
const ngContentSelectors = component.directive.template !.ngContentSelectors;
for (let i = 0; i < ngContentSelectors.length; i++) {
const selector = ngContentSelectors[i];
if (selector === '*') {
@ -822,9 +825,10 @@ class ElementContext {
}
constructor(
public isTemplateElement: boolean, private _ngContentIndexMatcher: SelectorMatcher,
private _wildcardNgContentIndex: number, public providerContext: ProviderElementContext) {}
private _wildcardNgContentIndex: number|null,
public providerContext: ProviderElementContext|null) {}
findNgContentIndex(selector: CssSelector): number {
findNgContentIndex(selector: CssSelector): number|null {
const ngContentIndices: number[] = [];
this._ngContentIndexMatcher.match(
selector, (selector, ngContentIndex) => { ngContentIndices.push(ngContentIndex); });
@ -893,10 +897,9 @@ function isTemplate(
// `<template>` is HTML and case insensitive
if (tagNoNs.toLowerCase() === TEMPLATE_ELEMENT) {
if (enableLegacyTemplate && tagNoNs.toLowerCase() === TEMPLATE_ELEMENT) {
reportDeprecation(TEMPLATE_ELEMENT_DEPRECATION_WARNING, el.sourceSpan);
reportDeprecation(TEMPLATE_ELEMENT_DEPRECATION_WARNING, el.sourceSpan !);
return true;
}
return false;
}
return false;
}

View File

@ -21,11 +21,11 @@ const NG_NON_BINDABLE_ATTR = 'ngNonBindable';
const NG_PROJECT_AS = 'ngProjectAs';
export function preparseElement(ast: html.Element): PreparsedElement {
let selectAttr: string = null;
let hrefAttr: string = null;
let relAttr: string = null;
let selectAttr: string = null !;
let hrefAttr: string = null !;
let relAttr: string = null !;
let nonBindable = false;
let projectAs: string = null;
let projectAs: string = null !;
ast.attrs.forEach(attr => {
const lcAttrName = attr.name.toLowerCase();
if (lcAttrName == NG_CONTENT_SELECT_ATTR) {

View File

@ -49,7 +49,7 @@ export const DEFAULT_PACKAGE_URL_PROVIDER = {
*/
@CompilerInjectable()
export class UrlResolver {
constructor(@Inject(PACKAGE_ROOT_URL) private _packagePrefix: string = null) {}
constructor(@Inject(PACKAGE_ROOT_URL) private _packagePrefix: string|null = null) {}
/**
* Resolves the `url` given the `baseUrl`:
@ -254,7 +254,7 @@ enum _ComponentIndex {
* arbitrary strings may still look like path names.
*/
function _split(uri: string): Array<string|any> {
return uri.match(_splitRe);
return uri.match(_splitRe) !;
}
/**

View File

@ -50,6 +50,14 @@ export function visitValue(value: any, visitor: ValueVisitor, context: any): any
return visitor.visitOther(value, context);
}
export function isDefined(val: any): boolean {
return val !== null && val !== undefined;
}
export function noUndefined<T>(val: T | undefined): T {
return val === undefined ? null ! : val;
}
export interface ValueVisitor {
visitArray(arr: any[], context: any): any;
visitStringMap(map: {[key: string]: any}, context: any): any;
@ -71,7 +79,7 @@ export class ValueTransformer implements ValueVisitor {
}
export class SyncAsyncResult<T> {
constructor(public syncResult: T, public asyncResult: Promise<T> = null) {
constructor(public syncResult: T|null, public asyncResult: Promise<T>|null = null) {
if (!asyncResult) {
this.asyncResult = Promise.resolve(syncResult);
}

View File

@ -44,22 +44,22 @@ export class ViewCompiler {
const statements: o.Statement[] = [];
let renderComponentVarName: string;
let renderComponentVarName: string = undefined !;
if (!component.isHost) {
const template = component.template !;
const customRenderData: o.LiteralMapEntry[] = [];
if (component.template.animations && component.template.animations.length) {
customRenderData.push(new o.LiteralMapEntry(
'animation', convertValueToOutputAst(component.template.animations), true));
if (template.animations && template.animations.length) {
customRenderData.push(
new o.LiteralMapEntry('animation', convertValueToOutputAst(template.animations), true));
}
const renderComponentVar = o.variable(rendererTypeName(component.type.reference));
renderComponentVarName = renderComponentVar.name;
renderComponentVarName = renderComponentVar.name !;
statements.push(
renderComponentVar
.set(o.importExpr(createIdentifier(Identifiers.createRendererType2))
.callFn([new o.LiteralMapExpr([
new o.LiteralMapEntry(
'encapsulation', o.literal(component.template.encapsulation)),
new o.LiteralMapEntry('encapsulation', o.literal(template.encapsulation)),
new o.LiteralMapEntry('styles', styles),
new o.LiteralMapEntry('data', new o.LiteralMapExpr(customRenderData))
])]))
@ -68,7 +68,7 @@ export class ViewCompiler {
[o.StmtModifier.Final]));
}
const viewBuilderFactory = (parent: ViewBuilder): ViewBuilder => {
const viewBuilderFactory = (parent: ViewBuilder | null): ViewBuilder => {
const embeddedViewIndex = embeddedViewCount++;
return new ViewBuilder(
parent, component, embeddedViewIndex, usedPipes, staticQueryIds, viewBuilderFactory);
@ -105,7 +105,7 @@ const ALLOW_DEFAULT_VAR = o.variable(`ad`);
class ViewBuilder implements TemplateAstVisitor, LocalResolver {
private compType: o.Type;
private nodes: (() => {
sourceSpan: ParseSourceSpan,
sourceSpan: ParseSourceSpan | null,
nodeDef: o.Expression,
nodeFlags: NodeFlags, updateDirectives?: UpdateExpression[], updateRenderer?: UpdateExpression[]
})[] = [];
@ -116,14 +116,15 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
private children: ViewBuilder[] = [];
constructor(
private parent: ViewBuilder, private component: CompileDirectiveMetadata,
private parent: ViewBuilder|null, private component: CompileDirectiveMetadata,
private embeddedViewIndex: number, private usedPipes: CompilePipeSummary[],
private staticQueryIds: Map<TemplateAst, StaticAndDynamicQueryIds>,
private viewBuilderFactory: ViewBuilderFactory) {
// TODO(tbosch): The old view compiler used to use an `any` type
// for the context in any embedded view. We keep this behaivor for now
// to be able to introduce the new view compiler without too many errors.
this.compType = this.embeddedViewIndex > 0 ? o.DYNAMIC_TYPE : o.importType(this.component.type);
this.compType =
this.embeddedViewIndex > 0 ? o.DYNAMIC_TYPE : o.importType(this.component.type) !;
}
get viewName(): string {
@ -188,7 +189,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
viewFlags |= ViewFlags.OnPush;
}
const viewFactory = new o.DeclareFunctionStmt(
this.viewName, [new o.FnParam(LOG_VAR.name)],
this.viewName, [new o.FnParam(LOG_VAR.name !)],
[new o.ReturnStatement(o.importExpr(createIdentifier(Identifiers.viewDef)).callFn([
o.literal(viewFlags),
o.literalArr(nodeDefExprs),
@ -205,13 +206,13 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
let updateFn: o.Expression;
if (updateStmts.length > 0) {
const preStmts: o.Statement[] = [];
if (!this.component.isHost && o.findReadVarNames(updateStmts).has(COMP_VAR.name)) {
if (!this.component.isHost && o.findReadVarNames(updateStmts).has(COMP_VAR.name !)) {
preStmts.push(COMP_VAR.set(VIEW_VAR.prop('component')).toDeclStmt(this.compType));
}
updateFn = o.fn(
[
new o.FnParam(CHECK_VAR.name, o.INFERRED_TYPE),
new o.FnParam(VIEW_VAR.name, o.INFERRED_TYPE)
new o.FnParam(CHECK_VAR.name !, o.INFERRED_TYPE),
new o.FnParam(VIEW_VAR.name !, o.INFERRED_TYPE)
],
[...preStmts, ...updateStmts], o.INFERRED_TYPE);
} else {
@ -245,7 +246,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
visitBoundText(ast: BoundTextAst, context: any): any {
const nodeIndex = this.nodes.length;
// reserve the space in the nodeDefs array
this.nodes.push(null);
this.nodes.push(null !);
const astWithSource = <ASTWithSource>ast.value;
const inter = <Interpolation>astWithSource.ast;
@ -268,7 +269,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any {
const nodeIndex = this.nodes.length;
// reserve the space in the nodeDefs array
this.nodes.push(null);
this.nodes.push(null !);
const {flags, queryMatchesExpr, hostEvents} = this._visitElementOrTemplate(nodeIndex, ast);
@ -299,9 +300,9 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
visitElement(ast: ElementAst, context: any): any {
const nodeIndex = this.nodes.length;
// reserve the space in the nodeDefs array so we can add children
this.nodes.push(null);
this.nodes.push(null !);
let elName = ast.name;
let elName: string|null = ast.name;
if (ast.name === NG_CONTAINER_TAG) {
// Using a null element name creates an anchor.
elName = null;
@ -314,13 +315,13 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
let updateRendererExpressions: UpdateExpression[] = [];
let outputDefs: o.Expression[] = [];
if (elName) {
const hostBindings = ast.inputs
.map((inputAst) => ({
context: COMP_VAR as o.Expression,
inputAst,
dirAst: null,
}))
.concat(dirHostBindings);
const hostBindings: any[] = ast.inputs
.map((inputAst) => ({
context: COMP_VAR as o.Expression,
inputAst,
dirAst: null as any,
}))
.concat(dirHostBindings);
if (hostBindings.length) {
updateRendererExpressions =
hostBindings.map((hostBinding, bindingIndex) => this._preprocessUpdateExpression({
@ -386,7 +387,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
queryMatches: QueryMatch[]
}): {
flags: NodeFlags,
usedEvents: [string, string][],
usedEvents: [string | null, string][],
queryMatchesExpr: o.Expression,
hostBindings:
{context: o.Expression, inputAst: BoundElementPropertyAst, dirAst: DirectiveAst}[],
@ -396,7 +397,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
if (ast.hasViewContainer) {
flags |= NodeFlags.EmbeddedViews;
}
const usedEvents = new Map<string, [string, string]>();
const usedEvents = new Map<string, [string | null, string]>();
ast.outputs.forEach((event) => {
const {name, target} = elementEventNameAndTarget(event, null);
usedEvents.set(elementEventFullName(target, name), [target, name]);
@ -416,8 +417,8 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
}
ast.providers.forEach((providerAst, providerIndex) => {
let dirAst: DirectiveAst;
let dirIndex: number;
let dirAst: DirectiveAst = undefined !;
let dirIndex: number = undefined !;
ast.directives.forEach((localDirAst, i) => {
if (localDirAst.directive.type.reference === tokenReference(providerAst.token)) {
dirAst = localDirAst;
@ -427,7 +428,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
if (dirAst) {
const {hostBindings: dirHostBindings, hostEvents: dirHostEvents} = this._visitDirective(
providerAst, dirAst, dirIndex, nodeIndex, ast.references, ast.queryMatches, usedEvents,
this.staticQueryIds.get(<any>ast));
this.staticQueryIds.get(<any>ast) !);
hostBindings.push(...dirHostBindings);
hostEvents.push(...dirHostEvents);
} else {
@ -437,7 +438,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
let queryMatchExprs: o.Expression[] = [];
ast.queryMatches.forEach((match) => {
let valueType: QueryValueType;
let valueType: QueryValueType = undefined !;
if (tokenReference(match.value) === resolveIdentifier(Identifiers.ElementRef)) {
valueType = QueryValueType.ElementRef;
} else if (tokenReference(match.value) === resolveIdentifier(Identifiers.ViewContainerRef)) {
@ -450,7 +451,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
}
});
ast.references.forEach((ref) => {
let valueType: QueryValueType;
let valueType: QueryValueType = undefined !;
if (!ref.value) {
valueType = QueryValueType.RenderElement;
} else if (tokenReference(ref.value) === resolveIdentifier(Identifiers.TemplateRef)) {
@ -462,7 +463,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
}
});
ast.outputs.forEach((outputAst) => {
hostEvents.push({context: COMP_VAR, eventAst: outputAst, dirAst: null});
hostEvents.push({context: COMP_VAR, eventAst: outputAst, dirAst: null !});
});
return {
@ -470,7 +471,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
usedEvents: Array.from(usedEvents.values()),
queryMatchesExpr: queryMatchExprs.length ? o.literalArr(queryMatchExprs) : o.NULL_EXPR,
hostBindings,
hostEvents
hostEvents: hostEvents
};
}
@ -484,7 +485,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
} {
const nodeIndex = this.nodes.length;
// reserve the space in the nodeDefs array so we can add children
this.nodes.push(null);
this.nodes.push(null !);
dirAst.directive.queries.forEach((query, queryIndex) => {
const queryId = dirAst.contentQueryStartId + queryIndex;
@ -588,7 +589,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
private _visitProvider(providerAst: ProviderAst, queryMatches: QueryMatch[]): void {
const nodeIndex = this.nodes.length;
// reserve the space in the nodeDefs array so we can add children
this.nodes.push(null);
this.nodes.push(null !);
const {flags, queryMatchExprs, providerExpr, depsExpr} =
this._visitProviderOrDirective(providerAst, queryMatches);
@ -639,12 +640,12 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
return {flags: flags | providerType, queryMatchExprs, providerExpr, depsExpr};
}
getLocal(name: string): o.Expression {
getLocal(name: string): o.Expression|null {
if (name == EventHandlerVars.event.name) {
return EventHandlerVars.event;
}
let currViewExpr: o.Expression = VIEW_VAR;
for (let currBuilder: ViewBuilder = this; currBuilder; currBuilder = currBuilder.parent,
for (let currBuilder: ViewBuilder|null = this; currBuilder; currBuilder = currBuilder.parent,
currViewExpr = currViewExpr.prop('parent').cast(o.DYNAMIC_TYPE)) {
// check references
const refNodeIndex = currBuilder.refNodeIndices[name];
@ -701,7 +702,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
}
createPipeConverter(expression: UpdateExpression, name: string, argCount: number):
BuiltinConverter {
const pipe = this.usedPipes.find((pipeSummary) => pipeSummary.name === name);
const pipe = this.usedPipes.find((pipeSummary) => pipeSummary.name === name) !;
if (pipe.pure) {
const nodeIndex = this.nodes.length;
// function purePipeDef(argCount: number): NodeDef;
@ -740,7 +741,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
}
}
private _createPipe(sourceSpan: ParseSourceSpan, pipe: CompilePipeSummary): number {
private _createPipe(sourceSpan: ParseSourceSpan|null, pipe: CompilePipeSummary): number {
const nodeIndex = this.nodes.length;
let flags = NodeFlags.None;
pipe.type.lifecycleHooks.forEach((lifecycleHook) => {
@ -816,7 +817,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
return {updateRendererStmts, updateDirectivesStmts, nodeDefExprs};
function createUpdateStatements(
nodeIndex: number, sourceSpan: ParseSourceSpan, expressions: UpdateExpression[],
nodeIndex: number, sourceSpan: ParseSourceSpan | null, expressions: UpdateExpression[],
allowEmptyExprs: boolean): o.Statement[] {
const updateStmts: o.Statement[] = [];
const exprs = expressions.map(({sourceSpan, context, value}) => {
@ -824,8 +825,8 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
const nameResolver = context === COMP_VAR ? self : null;
const {stmts, currValExpr} =
convertPropertyBinding(nameResolver, context, value, bindingId);
updateStmts.push(
...stmts.map(stmt => o.applySourceSpanToStatementIfNeeded(stmt, sourceSpan)));
updateStmts.push(...stmts.map(
(stmt: o.Statement) => o.applySourceSpanToStatementIfNeeded(stmt, sourceSpan)));
return o.applySourceSpanToExpressionIfNeeded(currValExpr, sourceSpan);
});
if (expressions.length || allowEmptyExprs) {
@ -860,14 +861,14 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
if (handleEventStmts.length > 0) {
const preStmts: o.Statement[] =
[ALLOW_DEFAULT_VAR.set(o.literal(true)).toDeclStmt(o.BOOL_TYPE)];
if (!this.component.isHost && o.findReadVarNames(handleEventStmts).has(COMP_VAR.name)) {
if (!this.component.isHost && o.findReadVarNames(handleEventStmts).has(COMP_VAR.name !)) {
preStmts.push(COMP_VAR.set(VIEW_VAR.prop('component')).toDeclStmt(this.compType));
}
handleEventFn = o.fn(
[
new o.FnParam(VIEW_VAR.name, o.INFERRED_TYPE),
new o.FnParam(EVENT_NAME_VAR.name, o.INFERRED_TYPE),
new o.FnParam(EventHandlerVars.event.name, o.INFERRED_TYPE)
new o.FnParam(VIEW_VAR.name !, o.INFERRED_TYPE),
new o.FnParam(EVENT_NAME_VAR.name !, o.INFERRED_TYPE),
new o.FnParam(EventHandlerVars.event.name !, o.INFERRED_TYPE)
],
[...preStmts, ...handleEventStmts, new o.ReturnStatement(ALLOW_DEFAULT_VAR)],
o.INFERRED_TYPE);
@ -933,9 +934,9 @@ function singleProviderDef(providerType: ProviderAstType, providerMeta: CompileP
let flags: NodeFlags;
let deps: CompileDiDependencyMetadata[];
if (providerType === ProviderAstType.Directive || providerType === ProviderAstType.Component) {
providerExpr = o.importExpr(providerMeta.useClass);
providerExpr = o.importExpr(providerMeta.useClass !);
flags = NodeFlags.TypeDirective;
deps = providerMeta.deps || providerMeta.useClass.diDeps;
deps = providerMeta.deps || providerMeta.useClass !.diDeps;
} else {
if (providerMeta.useClass) {
providerExpr = o.importExpr(providerMeta.useClass);
@ -966,7 +967,7 @@ function tokenExpr(tokenMeta: CompileTokenMetadata): o.Expression {
function depDef(dep: CompileDiDependencyMetadata): o.Expression {
// Note: the following fields have already been normalized out by provider_analyzer:
// - isAttribute, isSelf, isHost
const expr = dep.isValue ? convertValueToOutputAst(dep.value) : tokenExpr(dep.token);
const expr = dep.isValue ? convertValueToOutputAst(dep.value) : tokenExpr(dep.token !);
let flags = DepFlags.None;
if (dep.isSkipSelf) {
flags |= DepFlags.SkipSelf;
@ -1110,11 +1111,11 @@ function findStaticQueryIds(
nodes.forEach((node) => {
const staticQueryIds = new Set<number>();
const dynamicQueryIds = new Set<number>();
let queryMatches: QueryMatch[];
let queryMatches: QueryMatch[] = undefined !;
if (node instanceof ElementAst) {
findStaticQueryIds(node.children, result);
node.children.forEach((child) => {
const childData = result.get(child);
const childData = result.get(child) !;
childData.staticQueryIds.forEach(queryId => staticQueryIds.add(queryId));
childData.dynamicQueryIds.forEach(queryId => dynamicQueryIds.add(queryId));
});
@ -1122,7 +1123,7 @@ function findStaticQueryIds(
} else if (node instanceof EmbeddedTemplateAst) {
findStaticQueryIds(node.children, result);
node.children.forEach((child) => {
const childData = result.get(child);
const childData = result.get(child) !;
childData.staticQueryIds.forEach(queryId => dynamicQueryIds.add(queryId));
childData.dynamicQueryIds.forEach(queryId => dynamicQueryIds.add(queryId));
});
@ -1149,7 +1150,7 @@ function staticViewQueryIds(nodeStaticQueryIds: Map<TemplateAst, StaticAndDynami
return {staticQueryIds, dynamicQueryIds};
}
function createComponentFactoryResolver(directives: DirectiveAst[]): ProviderAst {
function createComponentFactoryResolver(directives: DirectiveAst[]): ProviderAst|null {
const componentDirMeta = directives.find(dirAst => dirAst.directive.isComponent);
if (componentDirMeta && componentDirMeta.directive.entryComponents.length) {
const entryComponentFactories = componentDirMeta.directive.entryComponents.map(
@ -1174,7 +1175,7 @@ function createComponentFactoryResolver(directives: DirectiveAst[]): ProviderAst
}
function elementEventNameAndTarget(
eventAst: BoundEventAst, dirAst: DirectiveAst): {name: string, target: string} {
eventAst: BoundEventAst, dirAst: DirectiveAst | null): {name: string, target: string | null} {
if (eventAst.isAnimation) {
return {
name: `@${eventAst.name}.${eventAst.phase}`,

View File

@ -110,7 +110,8 @@ describe('compiler (unbundled Angular)', () => {
});
}
function findLineAndColumn(file: string, token: string): {line: number, column: number} {
function findLineAndColumn(
file: string, token: string): {line: number | null, column: number | null} {
const index = file.indexOf(token);
if (index === -1) {
return {line: null, column: null};
@ -178,7 +179,7 @@ describe('compiler (unbundled Angular)', () => {
appDir['app.component.ts'] = createComponentSource(templateDecorator(template));
compileApp().then((genFile) => {
const sourceMap = extractSourceMap(genFile.source);
const sourceMap = extractSourceMap(genFile.source) !;
expect(sourceMap.file).toEqual(genFile.genFileUrl);
// the generated file contains code that is not mapped to
@ -199,7 +200,7 @@ describe('compiler (unbundled Angular)', () => {
appDir['app.component.ts'] = createComponentSource(templateDecorator(template));
compileApp().then((genFile) => {
const sourceMap = extractSourceMap(genFile.source);
const sourceMap = extractSourceMap(genFile.source) !;
expect(originalPositionFor(sourceMap, findLineAndColumn(genFile.source, `'span'`)))
.toEqual({line: 2, column: 3, source: ngUrl});
});
@ -211,7 +212,7 @@ describe('compiler (unbundled Angular)', () => {
appDir['app.component.ts'] = createComponentSource(templateDecorator(template));
compileApp().then((genFile) => {
const sourceMap = extractSourceMap(genFile.source);
const sourceMap = extractSourceMap(genFile.source) !;
expect(
originalPositionFor(sourceMap, findLineAndColumn(genFile.source, `someMethod()`)))
.toEqual({line: 2, column: 9, source: ngUrl});
@ -224,7 +225,7 @@ describe('compiler (unbundled Angular)', () => {
appDir['app.component.ts'] = createComponentSource(templateDecorator(template));
compileApp().then((genFile) => {
const sourceMap = extractSourceMap(genFile.source);
const sourceMap = extractSourceMap(genFile.source) !;
expect(
originalPositionFor(sourceMap, findLineAndColumn(genFile.source, `someMethod()`)))
.toEqual({line: 2, column: 9, source: ngUrl});
@ -235,7 +236,7 @@ describe('compiler (unbundled Angular)', () => {
appDir['app.component.ts'] = createComponentSource(templateDecorator('Hello World!'));
compileApp().then((genFile) => {
const sourceMap = extractSourceMap(genFile.source);
const sourceMap = extractSourceMap(genFile.source) !;
expect(originalPositionFor(sourceMap, {line: 1, column: 0}))
.toEqual({line: 1, column: 0, source: ngComponentPath});
});
@ -328,7 +329,7 @@ describe('compiler (unbundled Angular)', () => {
compile(host, aotHost, expectNoDiagnostics).then((generatedFiles) => {
const genFile = generatedFiles.find(genFile => genFile.srcFileUrl === '/app/app.ts');
const createComponentFactoryCall =
/ɵccf\([^)]*\)/m.exec(genFile.source)[0].replace(/\s*/g, '');
/ɵccf\([^)]*\)/m.exec(genFile.source) ![0].replace(/\s*/g, '');
// selector
expect(createComponentFactoryCall).toContain('my-comp');
// inputs

View File

@ -360,7 +360,7 @@ describe('StaticReflector', () => {
it('should record data about the error in the exception', () => {
let threw = false;
try {
const metadata = host.getMetadataFor('/tmp/src/invalid-metadata.ts');
const metadata = host.getMetadataFor('/tmp/src/invalid-metadata.ts') !;
expect(metadata).toBeDefined();
const moduleMetadata: any = metadata[0]['metadata'];
expect(moduleMetadata).toBeDefined();

View File

@ -382,7 +382,7 @@ export class MockSummaryResolver implements SummaryResolver<StaticSymbol> {
}
getImportAs(symbol: StaticSymbol): StaticSymbol {
const entry = this.importAs.find(entry => entry.symbol === symbol);
return entry ? entry.importAs : undefined;
return entry ? entry.importAs : undefined !;
}
isLibraryFile(filePath: string): boolean { return filePath.endsWith('.d.ts'); }
@ -429,7 +429,7 @@ export class MockStaticSymbolResolverHost implements StaticSymbolResolverHost {
}
if (modulePath.indexOf('.') === 0) {
const baseName = pathTo(containingFile, modulePath);
const baseName = pathTo(containingFile !, modulePath);
const tsName = baseName + '.ts';
if (this._getMetadataFor(tsName)) {
return tsName;

View File

@ -95,7 +95,7 @@ export function main() {
members: {aMethod: {__symbolic: 'function'}},
statics: {aStatic: true}
});
expect(summaries[1].type.type.reference)
expect(summaries[1].type !.type.reference)
.toBe(symbolCache.get('/tmp/some_service.d.ts', 'SomeService'));
});
@ -203,7 +203,7 @@ export function main() {
expect(summaries[2].metadata).toEqual('b');
// SomService is a transitive dep, but should have been serialized as well.
expect(summaries[3].symbol).toBe(symbolCache.get('/tmp/external_svc.d.ts', 'SomeService'));
expect(summaries[3].type.type.reference)
expect(summaries[3].type !.type.reference)
.toBe(symbolCache.get('/tmp/external_svc.d.ts', 'SomeService'));
});

View File

@ -18,7 +18,7 @@ export type MockDirectory = {
[name: string]: MockData | undefined;
};
export function isDirectory(data: MockData): data is MockDirectory {
export function isDirectory(data: MockData | undefined): data is MockDirectory {
return typeof data !== 'string';
}
@ -146,6 +146,7 @@ export class EmittingCompilerHost implements ts.CompilerHost {
if (content) {
return ts.createSourceFile(fileName, content, languageVersion, /* setParentNodes */ true);
}
throw new Error(`File not found '${fileName}'.`);
}
getDefaultLibFileName(options: ts.CompilerOptions): string { return 'lib.d.ts'; }
@ -235,7 +236,7 @@ export class MockCompilerHost implements ts.CompilerHost {
let result = open(fileName, this.data) != null;
if (!result && fileName.startsWith(MOCK_NODEMODULES_PREFIX)) {
const libraryPath = fileName.substr(MOCK_NODEMODULES_PREFIX.length - 1);
for (const library of this.libraries) {
for (const library of this.libraries !) {
if (library.has(libraryPath)) {
return true;
}
@ -252,7 +253,7 @@ export class MockCompilerHost implements ts.CompilerHost {
}
}
readFile(fileName: string): string { return this.getFileContent(fileName); }
readFile(fileName: string): string { return this.getFileContent(fileName) !; }
trace(s: string): void { this.traces.push(s); }
@ -265,10 +266,8 @@ export class MockCompilerHost implements ts.CompilerHost {
if (isDirectory(data)) {
return Object.keys(data).filter(k => isDirectory(data[k]));
}
return [];
} else {
return undefined;
}
return [];
}
// ts.CompilerHost
@ -283,7 +282,7 @@ export class MockCompilerHost implements ts.CompilerHost {
this.sourceFiles.set(fileName, result);
}
}
return result;
return result !;
}
getDefaultLibFileName(options: ts.CompilerOptions): string { return 'lib.d.ts'; }
@ -318,7 +317,7 @@ export class MockCompilerHost implements ts.CompilerHost {
const result = open(fileName, this.data);
if (!result && fileName.startsWith(MOCK_NODEMODULES_PREFIX)) {
const libraryPath = fileName.substr(MOCK_NODEMODULES_PREFIX.length - 1);
for (const library of this.libraries) {
for (const library of this.libraries !) {
if (library.has(libraryPath)) return library.get(libraryPath);
}
}
@ -367,9 +366,9 @@ export class MockAotCompilerHost implements AotCompilerHost {
tsFilesOnly() { this.dtsAreSource = false; }
// StaticSymbolResolverHost
getMetadataFor(modulePath: string): {[key: string]: any}[] {
getMetadataFor(modulePath: string): {[key: string]: any}[]|null {
if (!this.tsHost.fileExists(modulePath)) {
return undefined;
return null;
}
if (DTS.test(modulePath)) {
if (this.metadataVisible) {
@ -384,6 +383,7 @@ export class MockAotCompilerHost implements AotCompilerHost {
const metadata = this.metadataCollector.getMetadata(sf);
return metadata ? [metadata] : [];
}
return null;
}
moduleNameToFileName(moduleName: string, containingFile: string): string|null {
@ -439,11 +439,11 @@ export class MockMetadataBundlerHost implements MetadataBundlerHost {
}
}
function find(fileName: string, data: MockData): MockData|undefined {
function find(fileName: string, data: MockData | undefined): MockData|undefined {
if (!data) return undefined;
let names = fileName.split('/');
if (names.length && !names[0].length) names.shift();
let current = data;
let current: MockData|undefined = data;
for (let name of names) {
if (typeof current === 'string')
return undefined;
@ -454,7 +454,7 @@ function find(fileName: string, data: MockData): MockData|undefined {
return current;
}
function open(fileName: string, data: MockData): string|undefined {
function open(fileName: string, data: MockData | undefined): string|undefined {
let result = find(fileName, data);
if (typeof result === 'string') {
return result;
@ -462,7 +462,7 @@ function open(fileName: string, data: MockData): string|undefined {
return undefined;
}
function directoryExists(dirname: string, data: MockData): boolean {
function directoryExists(dirname: string, data: MockData | undefined): boolean {
let result = find(dirname, data);
return result && typeof result !== 'string';
return !!result && typeof result !== 'string';
}

View File

@ -274,7 +274,7 @@ export function main() {
it('should throw an error if a selector is being parsed while in the wrong mode', () => {
const cssCode = '.class > tag';
let capturedMessage: string;
let capturedMessage: string = undefined !;
try {
tokenize(cssCode, false, CssLexerMode.STYLE_BLOCK);
} catch (e) {
@ -282,7 +282,7 @@ export function main() {
}
expect(capturedMessage).toMatch(/Unexpected character \[\>\] at column 0:7 in expression/g);
capturedMessage = null;
capturedMessage = null !;
try {
tokenize(cssCode, false, CssLexerMode.SELECTOR);

View File

@ -111,26 +111,26 @@ export function main() {
expect(ast.rules.length).toEqual(1);
const rule = <CssKeyframeRuleAst>ast.rules[0];
expect(rule.name.strValue).toEqual('rotateMe');
expect(rule.name !.strValue).toEqual('rotateMe');
const block = <CssBlockAst>rule.block;
const fromRule = <CssKeyframeDefinitionAst>block.entries[0];
expect(fromRule.name.strValue).toEqual('from');
expect(fromRule.name !.strValue).toEqual('from');
const fromStyle = <CssDefinitionAst>(<CssBlockAst>fromRule.block).entries[0];
expect(fromStyle.property.strValue).toEqual('transform');
assertTokens(fromStyle.value.tokens, ['rotate', '(', '-360', 'deg', ')']);
const midRule = <CssKeyframeDefinitionAst>block.entries[1];
expect(midRule.name.strValue).toEqual('50%');
expect(midRule.name !.strValue).toEqual('50%');
const midStyle = <CssDefinitionAst>(<CssBlockAst>midRule.block).entries[0];
expect(midStyle.property.strValue).toEqual('transform');
assertTokens(midStyle.value.tokens, ['rotate', '(', '0', 'deg', ')']);
const toRule = <CssKeyframeDefinitionAst>block.entries[2];
expect(toRule.name.strValue).toEqual('to');
expect(toRule.name !.strValue).toEqual('to');
const toStyle = <CssDefinitionAst>(<CssBlockAst>toRule.block).entries[0];
expect(toStyle.property.strValue).toEqual('transform');
assertTokens(toStyle.value.tokens, ['rotate', '(', '360', 'deg', ')']);
@ -695,7 +695,7 @@ export function main() {
const ast = output.ast;
assertMatchesOffsetAndChar(ast.location.start, 0, '#');
assertMatchesOffsetAndChar(ast.location.end, 22, undefined);
assertMatchesOffsetAndChar(ast.location.end, 22, undefined !);
});
});

View File

@ -257,7 +257,7 @@ export function main() {
expect(captures.length).toEqual(1);
const keyframe1 = <CssKeyframeRuleAst>_getCaptureAst(captures, 0);
expect(keyframe1.name.strValue).toEqual('rotate');
expect(keyframe1.name !.strValue).toEqual('rotate');
expect(keyframe1.block.entries.length).toEqual(2);
});

View File

@ -5,6 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {CompileAnimationEntryMetadata} from '@angular/compiler';
import {CompileDirectiveMetadata, CompileStylesheetMetadata, CompileTemplateMetadata, CompileTypeMetadata} from '@angular/compiler/src/compile_metadata';
import {CompilerConfig} from '@angular/compiler/src/config';
import {DirectiveNormalizer} from '@angular/compiler/src/directive_normalizer';
@ -15,11 +16,137 @@ import {ViewEncapsulation} from '@angular/core/src/metadata/view';
import {TestBed} from '@angular/core/testing';
import {AsyncTestCompleter, beforeEach, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
import {SyncAsyncResult, noUndefined} from '../src/util';
import {SpyResourceLoader} from './spies';
const SOME_MODULE_URL = 'package:some/module/a.js';
const SOME_HTTP_MODULE_URL = 'http://some/module/a.js';
function normalizeTemplate(normalizer: DirectiveNormalizer, o: {
ngModuleType?: any; componentType?: any; moduleUrl?: string; template?: string | null;
templateUrl?: string | null;
styles?: string[];
styleUrls?: string[];
interpolation?: [string, string] | null;
encapsulation?: ViewEncapsulation | null;
animations?: CompileAnimationEntryMetadata[];
}) {
return normalizer.normalizeTemplate({
ngModuleType: noUndefined(o.ngModuleType),
componentType: noUndefined(o.componentType),
moduleUrl: noUndefined(o.moduleUrl),
template: noUndefined(o.template),
templateUrl: noUndefined(o.templateUrl),
styles: noUndefined(o.styles),
styleUrls: noUndefined(o.styleUrls),
interpolation: noUndefined(o.interpolation),
encapsulation: noUndefined(o.encapsulation),
animations: noUndefined(o.animations)
});
}
function normalizeTemplateAsync(normalizer: DirectiveNormalizer, o: {
ngModuleType?: any; componentType?: any; moduleUrl?: string; template?: string | null;
templateUrl?: string | null;
styles?: string[];
styleUrls?: string[];
interpolation?: [string, string] | null;
encapsulation?: ViewEncapsulation | null;
animations?: CompileAnimationEntryMetadata[];
}) {
return normalizer.normalizeTemplateAsync({
ngModuleType: noUndefined(o.ngModuleType),
componentType: noUndefined(o.componentType),
moduleUrl: noUndefined(o.moduleUrl),
template: noUndefined(o.template),
templateUrl: noUndefined(o.templateUrl),
styles: noUndefined(o.styles),
styleUrls: noUndefined(o.styleUrls),
interpolation: noUndefined(o.interpolation),
encapsulation: noUndefined(o.encapsulation),
animations: noUndefined(o.animations)
});
}
function normalizeTemplateSync(normalizer: DirectiveNormalizer, o: {
ngModuleType?: any; componentType?: any; moduleUrl?: string; template?: string | null;
templateUrl?: string | null;
styles?: string[];
styleUrls?: string[];
interpolation?: [string, string] | null;
encapsulation?: ViewEncapsulation | null;
animations?: CompileAnimationEntryMetadata[];
}): CompileTemplateMetadata {
return normalizer.normalizeTemplateSync({
ngModuleType: noUndefined(o.ngModuleType),
componentType: noUndefined(o.componentType),
moduleUrl: noUndefined(o.moduleUrl),
template: noUndefined(o.template),
templateUrl: noUndefined(o.templateUrl),
styles: noUndefined(o.styles),
styleUrls: noUndefined(o.styleUrls),
interpolation: noUndefined(o.interpolation),
encapsulation: noUndefined(o.encapsulation),
animations: noUndefined(o.animations)
});
}
function compileTemplateMetadata({encapsulation, template, templateUrl, styles, styleUrls,
externalStylesheets, animations, ngContentSelectors,
interpolation, isInline}: {
encapsulation?: ViewEncapsulation | null,
template?: string | null,
templateUrl?: string | null,
styles?: string[],
styleUrls?: string[],
externalStylesheets?: CompileStylesheetMetadata[],
ngContentSelectors?: string[],
animations?: any[],
interpolation?: [string, string] | null,
isInline?: boolean
}): CompileTemplateMetadata {
return new CompileTemplateMetadata({
encapsulation: encapsulation || null,
template: template || null,
templateUrl: templateUrl || null,
styles: styles || [],
styleUrls: styleUrls || [],
externalStylesheets: externalStylesheets || [],
ngContentSelectors: ngContentSelectors || [],
animations: animations || [],
interpolation: interpolation || null,
isInline: !!isInline,
});
}
function normalizeLoadedTemplate(
normalizer: DirectiveNormalizer, o: {
ngModuleType?: any; componentType?: any; moduleUrl?: string; template?: string | null;
templateUrl?: string | null;
styles?: string[];
styleUrls?: string[];
interpolation?: [string, string] | null;
encapsulation?: ViewEncapsulation | null;
animations?: CompileAnimationEntryMetadata[];
},
template: string, templateAbsUrl: string) {
return normalizer.normalizeLoadedTemplate(
{
ngModuleType: o.ngModuleType || null,
componentType: o.componentType || null,
moduleUrl: o.moduleUrl || '',
template: o.template || null,
templateUrl: o.templateUrl || null,
styles: o.styles || [],
styleUrls: o.styleUrls || [],
interpolation: o.interpolation || null,
encapsulation: o.encapsulation || null,
animations: o.animations || null,
},
template, templateAbsUrl);
}
export function main() {
describe('DirectiveNormalizer', () => {
beforeEach(() => { TestBed.configureCompiler({providers: TEST_COMPILER_PROVIDERS}); });
@ -27,46 +154,50 @@ export function main() {
describe('normalizeDirective', () => {
it('should throw if no template was specified',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
expect(() => normalizer.normalizeTemplate({
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
})).toThrowError('No template specified for component SomeComp');
expect(() => normalizeTemplate(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
}))
.toThrowError('No template specified for component SomeComp');
}));
it('should throw if template is not a string',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
expect(() => normalizer.normalizeTemplate({
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
template: <any>{}
})).toThrowError('The template specified for component SomeComp is not a string');
expect(() => normalizeTemplate(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
template: <any>{}
}))
.toThrowError('The template specified for component SomeComp is not a string');
}));
it('should throw if templateUrl is not a string',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
expect(() => normalizer.normalizeTemplate({
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
templateUrl: <any>{}
})).toThrowError('The templateUrl specified for component SomeComp is not a string');
expect(() => normalizeTemplate(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
templateUrl: <any>{}
}))
.toThrowError('The templateUrl specified for component SomeComp is not a string');
}));
it('should throw if both template and templateUrl are defined',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
expect(() => normalizer.normalizeTemplate({
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
template: '',
templateUrl: '',
})).toThrowError(`'SomeComp' component cannot define both template and templateUrl`);
expect(() => normalizeTemplate(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
template: '',
templateUrl: '',
}))
.toThrowError(`'SomeComp' component cannot define both template and templateUrl`);
}));
});
describe('normalizeTemplateSync', () => {
it('should store the template',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeTemplateSync({
const template = normalizeTemplateSync(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -83,7 +214,7 @@ export function main() {
it('should resolve styles on the annotation against the moduleUrl',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeTemplateSync({
const template = normalizeTemplateSync(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -98,7 +229,7 @@ export function main() {
it('should resolve styles in the template against the moduleUrl',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeTemplateSync({
const template = normalizeTemplateSync(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -113,7 +244,7 @@ export function main() {
it('should use ViewEncapsulation.Emulated by default',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeTemplateSync({
const template = normalizeTemplateSync(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -131,13 +262,13 @@ export function main() {
[CompilerConfig, DirectiveNormalizer],
(config: CompilerConfig, normalizer: DirectiveNormalizer) => {
config.defaultEncapsulation = ViewEncapsulation.None;
const template = normalizer.normalizeTemplateSync({
const template = normalizeTemplateSync(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
encapsulation: null,
encapsulation: undefined,
template: '',
templateUrl: null,
templateUrl: undefined,
styles: [],
styleUrls: ['test.css']
});
@ -153,23 +284,21 @@ export function main() {
(async: AsyncTestCompleter, normalizer: DirectiveNormalizer,
resourceLoader: MockResourceLoader) => {
resourceLoader.expect('package:some/module/sometplurl.html', 'a');
normalizer
.normalizeTemplateAsync({
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
encapsulation: null,
template: null,
templateUrl: 'sometplurl.html',
styles: [],
styleUrls: ['test.css']
})
.then((template: CompileTemplateMetadata) => {
expect(template.template).toEqual('a');
expect(template.templateUrl).toEqual('package:some/module/sometplurl.html');
expect(template.isInline).toBe(false);
async.done();
});
normalizeTemplateAsync(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
encapsulation: null,
template: null,
templateUrl: 'sometplurl.html',
styles: [],
styleUrls: ['test.css']
}).then((template: CompileTemplateMetadata) => {
expect(template.template).toEqual('a');
expect(template.templateUrl).toEqual('package:some/module/sometplurl.html');
expect(template.isInline).toBe(false);
async.done();
});
resourceLoader.flush();
}));
@ -179,21 +308,19 @@ export function main() {
(async: AsyncTestCompleter, normalizer: DirectiveNormalizer,
resourceLoader: MockResourceLoader) => {
resourceLoader.expect('package:some/module/tpl/sometplurl.html', '');
normalizer
.normalizeTemplateAsync({
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
encapsulation: null,
template: null,
templateUrl: 'tpl/sometplurl.html',
styles: [],
styleUrls: ['test.css']
})
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
async.done();
});
normalizeTemplateAsync(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
encapsulation: null,
template: null,
templateUrl: 'tpl/sometplurl.html',
styles: [],
styleUrls: ['test.css']
}).then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/test.css']);
async.done();
});
resourceLoader.flush();
}));
@ -204,21 +331,19 @@ export function main() {
resourceLoader: MockResourceLoader) => {
resourceLoader.expect(
'package:some/module/tpl/sometplurl.html', '<style>@import test.css</style>');
normalizer
.normalizeTemplateAsync({
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
encapsulation: null,
template: null,
templateUrl: 'tpl/sometplurl.html',
styles: [],
styleUrls: []
})
.then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/tpl/test.css']);
async.done();
});
normalizeTemplateAsync(normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
encapsulation: null,
template: null,
templateUrl: 'tpl/sometplurl.html',
styles: [],
styleUrls: []
}).then((template: CompileTemplateMetadata) => {
expect(template.styleUrls).toEqual(['package:some/module/tpl/test.css']);
async.done();
});
resourceLoader.flush();
}));
@ -238,7 +363,7 @@ export function main() {
resourceLoader: SpyResourceLoader) => {
programResourceLoaderSpy(resourceLoader, {'package:some/module/test.css': 'a'});
normalizer
.normalizeExternalStylesheets(new CompileTemplateMetadata({
.normalizeExternalStylesheets(compileTemplateMetadata({
template: '',
templateUrl: '',
styleUrls: ['package:some/module/test.css']
@ -264,7 +389,7 @@ export function main() {
'package:some/module/test2.css': 'b'
});
normalizer
.normalizeExternalStylesheets(new CompileTemplateMetadata({
.normalizeExternalStylesheets(compileTemplateMetadata({
template: '',
templateUrl: '',
styleUrls: ['package:some/module/test.css']
@ -301,8 +426,8 @@ export function main() {
};
Promise
.all([
normalizer.normalizeTemplateAsync(prenormMeta),
normalizer.normalizeTemplateAsync(prenormMeta)
normalizeTemplateAsync(normalizer, prenormMeta),
normalizeTemplateAsync(normalizer, prenormMeta)
])
.then((templates: CompileTemplateMetadata[]) => {
expect(templates[0].template).toEqual('a');
@ -319,8 +444,8 @@ export function main() {
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const viewEncapsulation = ViewEncapsulation.Native;
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -334,8 +459,8 @@ export function main() {
it('should keep the template as html',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -349,8 +474,8 @@ export function main() {
it('should collect ngContent',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -364,8 +489,8 @@ export function main() {
it('should normalize ngContent wildcard selector',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -380,8 +505,8 @@ export function main() {
it('should collect top level styles in the template',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -395,8 +520,8 @@ export function main() {
it('should collect styles inside in elements',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -410,8 +535,8 @@ export function main() {
it('should collect styleUrls in the template',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -425,8 +550,8 @@ export function main() {
it('should collect styleUrls in elements',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -440,8 +565,8 @@ export function main() {
it('should ignore link elements with non stylesheet rel attribute',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -455,8 +580,8 @@ export function main() {
it('should ignore link elements with absolute urls but non package: scheme',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -470,8 +595,8 @@ export function main() {
it('should extract @import style urls into styleAbsUrl',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -486,8 +611,8 @@ export function main() {
it('should not resolve relative urls in inline styles',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -501,8 +626,8 @@ export function main() {
it('should resolve relative style urls in styleUrls',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -517,8 +642,8 @@ export function main() {
it('should resolve relative style urls in styleUrls with http directive url',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_HTTP_MODULE_URL,
@ -533,8 +658,8 @@ export function main() {
it('should normalize ViewEncapsulation.Emulated to ViewEncapsulation.None if there are no styles nor stylesheets',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -548,8 +673,8 @@ export function main() {
it('should ignore ng-content in elements with ngNonBindable',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,
@ -564,8 +689,8 @@ export function main() {
it('should still collect <style> in elements with ngNonBindable',
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
const template = normalizer.normalizeLoadedTemplate(
{
const template = normalizeLoadedTemplate(
normalizer, {
ngModuleType: null,
componentType: SomeComp,
moduleUrl: SOME_MODULE_URL,

View File

@ -28,18 +28,18 @@ export function main() {
function parseTemplateBindingsResult(
text: string, location: any = null, prefix?: string): TemplateBindingParseResult {
return createParser().parseTemplateBindings(prefix, text, location);
return createParser().parseTemplateBindings(prefix || null, text, location);
}
function parseTemplateBindings(
text: string, location: any = null, prefix?: string): TemplateBinding[] {
return parseTemplateBindingsResult(text, location, prefix).templateBindings;
}
function parseInterpolation(text: string, location: any = null): ASTWithSource {
function parseInterpolation(text: string, location: any = null): ASTWithSource|null {
return createParser().parseInterpolation(text, location);
}
function splitInterpolation(text: string, location: any = null): SplitInterpolation {
function splitInterpolation(text: string, location: any = null): SplitInterpolation|null {
return createParser().splitInterpolation(text, location);
}
@ -48,7 +48,7 @@ export function main() {
}
function checkInterpolation(exp: string, expected?: string) {
const ast = parseInterpolation(exp);
const ast = parseInterpolation(exp) !;
if (expected == null) expected = exp;
expect(unparse(ast)).toEqual(expected);
validate(ast);
@ -475,7 +475,7 @@ export function main() {
() => { expect(parseInterpolation('nothing')).toBe(null); });
it('should parse no prefix/suffix interpolation', () => {
const ast = parseInterpolation('{{a}}').ast as Interpolation;
const ast = parseInterpolation('{{a}}') !.ast as Interpolation;
expect(ast.strings).toEqual(['', '']);
expect(ast.expressions.length).toEqual(1);
expect(ast.expressions[0].name).toEqual('a');
@ -483,18 +483,18 @@ export function main() {
it('should parse prefix/suffix with multiple interpolation', () => {
const originalExp = 'before {{ a }} middle {{ b }} after';
const ast = parseInterpolation(originalExp).ast;
const ast = parseInterpolation(originalExp) !.ast;
expect(unparse(ast)).toEqual(originalExp);
validate(ast);
});
it('should report empty interpolation expressions', () => {
expectError(
parseInterpolation('{{}}'),
parseInterpolation('{{}}') !,
'Blank expressions are not allowed in interpolated strings');
expectError(
parseInterpolation('foo {{ }}'),
parseInterpolation('foo {{ }}') !,
'Parser Error: Blank expressions are not allowed in interpolated strings');
});
@ -507,7 +507,8 @@ export function main() {
it('should support custom interpolation', () => {
const parser = new Parser(new Lexer());
const ast = parser.parseInterpolation('{% a %}', null, {start: '{%', end: '%}'}).ast as any;
const ast =
parser.parseInterpolation('{% a %}', null, {start: '{%', end: '%}'}) !.ast as any;
expect(ast.strings).toEqual(['', '']);
expect(ast.expressions.length).toEqual(1);
expect(ast.expressions[0].name).toEqual('a');
@ -586,12 +587,12 @@ export function main() {
describe('offsets', () => {
it('should retain the offsets of an interpolation', () => {
const interpolations = splitInterpolation('{{a}} {{b}} {{c}}');
const interpolations = splitInterpolation('{{a}} {{b}} {{c}}') !;
expect(interpolations.offsets).toEqual([2, 9, 16]);
});
it('should retain the offsets into the expression AST of interpolations', () => {
const source = parseInterpolation('{{a}} {{b}} {{c}}');
const source = parseInterpolation('{{a}} {{b}} {{c}}') !;
const interpolation = source.ast as Interpolation;
expect(interpolation.expressions.map(e => e.span.start)).toEqual([2, 9, 16]);
});

View File

@ -67,7 +67,7 @@ class Unparser implements AstVisitor {
}
visitFunctionCall(ast: FunctionCall, context: any) {
this._visit(ast.target);
this._visit(ast.target !);
this._expression += '(';
let isFirst = true;
ast.args.forEach(arg => {

View File

@ -285,7 +285,7 @@ export function main() {
});
it('should allow nested implicit elements', () => {
let result: any[];
let result: any[] = undefined !;
expect(() => {
result = extract('<div>outer<div>inner</div></div>', ['div']);
@ -490,7 +490,7 @@ function fakeTranslate(
messages.forEach(message => {
const id = digest(message);
const text = serializeI18nNodes(message.nodes).join('').replace(/</g, '[');
i18nMsgMap[id] = [new i18n.Text(`**${text}**`, null)];
i18nMsgMap[id] = [new i18n.Text(`**${text}**`, null !)];
});
const translations = new TranslationBundle(i18nMsgMap, null, digest);

View File

@ -36,13 +36,13 @@ export function main(): void {
const visitor = new RecurseVisitor();
const container = new i18n.Container(
[
new i18n.Text('', null),
new i18n.Placeholder('', '', null),
new i18n.IcuPlaceholder(null, '', null),
new i18n.Text('', null !),
new i18n.Placeholder('', '', null !),
new i18n.IcuPlaceholder(null !, '', null !),
],
null);
const tag = new i18n.TagPlaceholder('', {}, '', '', [container], false, null);
const icu = new i18n.Icu('', '', {tag}, null);
null !);
const tag = new i18n.TagPlaceholder('', {}, '', '', [container], false, null !);
const icu = new i18n.Icu('', '', {tag}, null !);
icu.visit(visitor);
expect(visitor.textCount).toEqual(1);

View File

@ -117,7 +117,7 @@ export function main(): void {
</translationbundle>`;
// Invalid messages should not cause the parser to throw
let i18nNodesByMsgId: {[id: string]: i18n.Node[]};
let i18nNodesByMsgId: {[id: string]: i18n.Node[]} = undefined !;
expect(() => {
i18nNodesByMsgId = serializer.load(XTB, 'url').i18nNodesByMsgId;
}).not.toThrow();

View File

@ -18,11 +18,11 @@ export function main(): void {
describe('TranslationBundle', () => {
const file = new ParseSourceFile('content', 'url');
const location = new ParseLocation(file, 0, 0, 0);
const span = new ParseSourceSpan(location, null);
const span = new ParseSourceSpan(location, null !);
const srcNode = new i18n.Text('src', span);
it('should translate a plain message', () => {
const msgMap = {foo: [new i18n.Text('bar', null)]};
const msgMap = {foo: [new i18n.Text('bar', null !)]};
const tb = new TranslationBundle(msgMap, null, (_) => 'foo');
const msg = new i18n.Message([srcNode], {}, {}, 'm', 'd', 'i');
expect(serializeNodes(tb.get(msg))).toEqual(['bar']);
@ -31,8 +31,8 @@ export function main(): void {
it('should translate a message with placeholder', () => {
const msgMap = {
foo: [
new i18n.Text('bar', null),
new i18n.Placeholder('', 'ph1', null),
new i18n.Text('bar', null !),
new i18n.Placeholder('', 'ph1', null !),
]
};
const phMap = {
@ -46,12 +46,12 @@ export function main(): void {
it('should translate a message with placeholder referencing messages', () => {
const msgMap = {
foo: [
new i18n.Text('--', null),
new i18n.Placeholder('', 'ph1', null),
new i18n.Text('++', null),
new i18n.Text('--', null !),
new i18n.Placeholder('', 'ph1', null !),
new i18n.Text('++', null !),
],
ref: [
new i18n.Text('*refMsg*', null),
new i18n.Text('*refMsg*', null !),
],
};
const refMsg = new i18n.Message([srcNode], {}, {}, 'm', 'd', 'i');
@ -70,13 +70,13 @@ export function main(): void {
const digest = (_: any) => `no matching id`;
// Empty message map -> use source messages in Ignore mode
let tb = new TranslationBundle({}, null, digest, null, MissingTranslationStrategy.Ignore);
let tb = new TranslationBundle({}, null, digest, null !, MissingTranslationStrategy.Ignore);
expect(serializeNodes(tb.get(messages[0])).join('')).toEqual(src);
// Empty message map -> use source messages in Warning mode
tb = new TranslationBundle({}, null, digest, null, MissingTranslationStrategy.Warning);
tb = new TranslationBundle({}, null, digest, null !, MissingTranslationStrategy.Warning);
expect(serializeNodes(tb.get(messages[0])).join('')).toEqual(src);
// Empty message map -> throw in Error mode
tb = new TranslationBundle({}, null, digest, null, MissingTranslationStrategy.Error);
tb = new TranslationBundle({}, null, digest, null !, MissingTranslationStrategy.Error);
expect(() => serializeNodes(tb.get(messages[0])).join('')).toThrow();
});
@ -84,7 +84,7 @@ export function main(): void {
it('should report unknown placeholders', () => {
const msgMap = {
foo: [
new i18n.Text('bar', null),
new i18n.Text('bar', null !),
new i18n.Placeholder('', 'ph1', span),
]
};
@ -95,7 +95,7 @@ export function main(): void {
it('should report missing translation', () => {
const tb =
new TranslationBundle({}, null, (_) => 'foo', null, MissingTranslationStrategy.Error);
new TranslationBundle({}, null, (_) => 'foo', null !, MissingTranslationStrategy.Error);
const msg = new i18n.Message([srcNode], {}, {}, 'm', 'd', 'i');
expect(() => tb.get(msg)).toThrowError(/Missing translation for message "foo"/);
});
@ -108,7 +108,7 @@ export function main(): void {
};
const tb = new TranslationBundle(
{}, 'en', (_) => 'foo', null, MissingTranslationStrategy.Warning, console);
{}, 'en', (_) => 'foo', null !, MissingTranslationStrategy.Warning, console);
const msg = new i18n.Message([srcNode], {}, {}, 'm', 'd', 'i');
expect(() => tb.get(msg)).not.toThrowError();
@ -117,8 +117,8 @@ export function main(): void {
});
it('should not report missing translation with MissingTranslationStrategy.Ignore', () => {
const tb =
new TranslationBundle({}, null, (_) => 'foo', null, MissingTranslationStrategy.Ignore);
const tb = new TranslationBundle(
{}, null, (_) => 'foo', null !, MissingTranslationStrategy.Ignore);
const msg = new i18n.Message([srcNode], {}, {}, 'm', 'd', 'i');
expect(() => tb.get(msg)).not.toThrowError();
});
@ -132,15 +132,15 @@ export function main(): void {
let count = 0;
const digest = (_: any) => count++ ? 'ref' : 'foo';
const tb =
new TranslationBundle(msgMap, null, digest, null, MissingTranslationStrategy.Error);
new TranslationBundle(msgMap, null, digest, null !, MissingTranslationStrategy.Error);
expect(() => tb.get(msg)).toThrowError(/Missing translation for message "ref"/);
});
it('should report invalid translated html', () => {
const msgMap = {
foo: [
new i18n.Text('text', null),
new i18n.Placeholder('', 'ph1', null),
new i18n.Text('text', null !),
new i18n.Placeholder('', 'ph1', null !),
]
};
const phMap = {

View File

@ -16,7 +16,7 @@ export function main() {
let fixture: ComponentFixture<TestComponent>;
describe('directives', () => {
describe('directiv es', () => {
it('should support dotted selectors', async(() => {
@Directive({selector: '[dot.name]'})
class MyDir {

View File

@ -26,9 +26,9 @@ class SomeMetadata implements SomeMetadataType {
arrayProp: any[];
constructor(options: SomeMetadataType) {
this.plainProp = options.plainProp;
this._getterProp = options.getterProp;
this.arrayProp = options.arrayProp;
this.plainProp = options.plainProp !;
this._getterProp = options.getterProp !;
this.arrayProp = options.arrayProp !;
}
}
@ -42,7 +42,7 @@ class OtherMetadata extends SomeMetadata implements OtherMetadataType {
arrayProp: options.arrayProp
});
this.otherPlainProp = options.otherPlainProp;
this.otherPlainProp = options.otherPlainProp !;
}
}

View File

@ -215,7 +215,7 @@ export function main() {
it('should throw with descriptive error message when null is passed to declarations',
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
@NgModule({declarations: [null]})
@NgModule({declarations: [null !]})
class ModuleWithNullDeclared {
}
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithNullDeclared, true))
@ -225,7 +225,7 @@ export function main() {
it('should throw with descriptive error message when null is passed to imports',
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
@NgModule({imports: [null]})
@NgModule({imports: [null !]})
class ModuleWithNullImported {
}
expect(() => resolver.loadNgModuleDirectiveAndPipeMetadata(ModuleWithNullImported, true))
@ -246,7 +246,7 @@ export function main() {
it('should throw with descriptive error message when encounter invalid provider',
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
@NgModule({providers: [{provide: SimpleService, useClass: undefined}]})
@NgModule({providers: [{provide: SimpleService, useClass: undefined !}]})
class SomeModule {
}
@ -256,7 +256,7 @@ export function main() {
it('should throw with descriptive error message when provider is undefined',
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
@NgModule({providers: [undefined]})
@NgModule({providers: [undefined !]})
class SomeModule {
}
@ -288,10 +288,10 @@ export function main() {
it('should throw with descriptive error message when null or undefined is passed to module bootstrap',
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
@NgModule({bootstrap: [null]})
@NgModule({bootstrap: [null !]})
class ModuleWithNullBootstrap {
}
@NgModule({bootstrap: [undefined]})
@NgModule({bootstrap: [undefined !]})
class ModuleWithUndefinedBootstrap {
}
@ -410,7 +410,7 @@ export function main() {
class MyModule {
}
const modMeta = resolver.getNgModuleMetadata(MyModule);
const modMeta = resolver.getNgModuleMetadata(MyModule) !;
expect(modMeta.declaredDirectives.length).toBe(1);
expect(modMeta.declaredDirectives[0].reference).toBe(MyComp);
}));
@ -480,11 +480,12 @@ class MyBrokenComp2 {
class SimpleService {
}
@Component({selector: 'my-broken-comp', template: '', providers: [SimpleService, null, [null]]})
@Component({selector: 'my-broken-comp', template: '', providers: [SimpleService, null !, [null]]})
class MyBrokenComp3 {
}
@Component({selector: 'my-broken-comp', template: '', viewProviders: [null, SimpleService, [null]]})
@Component(
{selector: 'my-broken-comp', template: '', viewProviders: [null !, SimpleService, [null]]})
class MyBrokenComp4 {
}

View File

@ -78,7 +78,7 @@ class _Humanizer implements html.Visitor {
private _appendContext(ast: html.Node, input: any[]): any[] {
if (!this.includeSourceSpan) return input;
input.push(ast.sourceSpan.toString());
input.push(ast.sourceSpan !.toString());
return input;
}
}

View File

@ -395,11 +395,11 @@ export function main() {
it('should set the start and end source spans', () => {
const node = <html.Element>parser.parse('<div>a</div>', 'TestComp').rootNodes[0];
expect(node.startSourceSpan.start.offset).toEqual(0);
expect(node.startSourceSpan.end.offset).toEqual(5);
expect(node.startSourceSpan !.start.offset).toEqual(0);
expect(node.startSourceSpan !.end.offset).toEqual(5);
expect(node.endSourceSpan.start.offset).toEqual(6);
expect(node.endSourceSpan.end.offset).toEqual(12);
expect(node.endSourceSpan !.start.offset).toEqual(6);
expect(node.endSourceSpan !.end.offset).toEqual(12);
});
it('should support expansion form', () => {
@ -420,8 +420,8 @@ export function main() {
it('should report a value span for an attibute with a value', () => {
const ast = parser.parse('<div bar="12"></div>', 'TestComp');
const attr = (ast.rootNodes[0] as html.Element).attrs[0];
expect(attr.valueSpan.start.offset).toEqual(9);
expect(attr.valueSpan.end.offset).toEqual(13);
expect(attr.valueSpan !.start.offset).toEqual(9);
expect(attr.valueSpan !.end.offset).toEqual(13);
});
});

View File

@ -56,28 +56,28 @@ export function main() {
const nodes = expand(`{messages.length, plural,=0 {<b>bold</b>}}`).nodes;
const container: html.Element = <html.Element>nodes[0];
expect(container.sourceSpan.start.col).toEqual(0);
expect(container.sourceSpan.end.col).toEqual(42);
expect(container.startSourceSpan.start.col).toEqual(0);
expect(container.startSourceSpan.end.col).toEqual(42);
expect(container.endSourceSpan.start.col).toEqual(0);
expect(container.endSourceSpan.end.col).toEqual(42);
expect(container.sourceSpan !.start.col).toEqual(0);
expect(container.sourceSpan !.end.col).toEqual(42);
expect(container.startSourceSpan !.start.col).toEqual(0);
expect(container.startSourceSpan !.end.col).toEqual(42);
expect(container.endSourceSpan !.start.col).toEqual(0);
expect(container.endSourceSpan !.end.col).toEqual(42);
const switchExp = container.attrs[0];
expect(switchExp.sourceSpan.start.col).toEqual(1);
expect(switchExp.sourceSpan.end.col).toEqual(16);
const template: html.Element = <html.Element>container.children[0];
expect(template.sourceSpan.start.col).toEqual(25);
expect(template.sourceSpan.end.col).toEqual(41);
expect(template.sourceSpan !.start.col).toEqual(25);
expect(template.sourceSpan !.end.col).toEqual(41);
const switchCheck = template.attrs[0];
expect(switchCheck.sourceSpan.start.col).toEqual(25);
expect(switchCheck.sourceSpan.end.col).toEqual(28);
const b: html.Element = <html.Element>template.children[0];
expect(b.sourceSpan.start.col).toEqual(29);
expect(b.endSourceSpan.end.col).toEqual(40);
expect(b.sourceSpan !.start.col).toEqual(29);
expect(b.endSourceSpan !.end.col).toEqual(40);
});
it('should handle other special forms', () => {

View File

@ -443,7 +443,7 @@ export function main() {
});
it('should parse interpolation with custom markers', () => {
expect(tokenizeAndHumanizeParts('{% a %}', null, {start: '{%', end: '%}'})).toEqual([
expect(tokenizeAndHumanizeParts('{% a %}', null !, {start: '{%', end: '%}'})).toEqual([
[lex.TokenType.TEXT, '{% a %}'],
[lex.TokenType.EOF],
]);
@ -769,7 +769,7 @@ export function main() {
const file = new ParseSourceFile(src, 'file://');
const location = new ParseLocation(file, 12, 123, 456);
const span = new ParseSourceSpan(location, location);
const error = new lex.TokenError('**ERROR**', null, span);
const error = new lex.TokenError('**ERROR**', null !, span);
expect(error.toString())
.toEqual(`**ERROR** ("\n222\n333\n[ERROR ->]E\n444\n555\n"): file://@123:456`);
});

View File

@ -25,7 +25,7 @@ export function main() {
ctx.print(createSourceSpan(fileA, 1), 'o1');
ctx.print(createSourceSpan(fileB, 0), 'o2');
ctx.print(createSourceSpan(fileB, 1), 'o3');
const sm = ctx.toSourceMapGenerator('o.ts', 'o.js').toJSON();
const sm = ctx.toSourceMapGenerator('o.ts', 'o.js').toJSON() !;
expect(sm.sources).toEqual([fileA.url, fileB.url]);
expect(sm.sourcesContent).toEqual([fileA.content, fileB.content]);
});
@ -43,7 +43,7 @@ export function main() {
it('should be able to shift the content', () => {
ctx.print(createSourceSpan(fileA, 0), 'fileA-0');
const sm = ctx.toSourceMapGenerator('o.ts', 'o.js', 10).toJSON();
const sm = ctx.toSourceMapGenerator('o.ts', 'o.js', 10).toJSON() !;
expect(originalPositionFor(sm, {line: 11, column: 0})).toEqual({
line: 1,
column: 0,
@ -111,9 +111,9 @@ export function main() {
// All lines / columns indexes are 0-based
// Note: source-map line indexes are 1-based, column 0-based
function expectMap(
ctx: EmitterVisitorContext, genLine: number, genCol: number, source: string = null,
srcLine: number = null, srcCol: number = null) {
const sm = ctx.toSourceMapGenerator('o.ts', 'o.js').toJSON();
ctx: EmitterVisitorContext, genLine: number, genCol: number, source: string | null = null,
srcLine: number | null = null, srcCol: number | null = null) {
const sm = ctx.toSourceMapGenerator('o.ts', 'o.js').toJSON() !;
const genPosition = {line: genLine + 1, column: genCol};
const origPosition = originalPositionFor(sm, genPosition);
expect(origPosition.source).toEqual(source);
@ -123,7 +123,7 @@ function expectMap(
// returns the number of segments per line
function nbSegmentsPerLine(ctx: EmitterVisitorContext) {
const sm = ctx.toSourceMapGenerator('o.ts', 'o.js').toJSON();
const sm = ctx.toSourceMapGenerator('o.ts', 'o.js').toJSON() !;
const lines = sm.mappings.split(';');
return lines.map(l => {
const m = l.match(/,/g);

View File

@ -23,8 +23,8 @@ class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
return importedUrlStr;
}
getImportAs(symbol: StaticSymbol): StaticSymbol { return null; }
getTypeArity(symbol: StaticSymbol): number /*|null*/ { return null; }
getImportAs(symbol: StaticSymbol): StaticSymbol|null { return null; }
getTypeArity(symbol: StaticSymbol): number|null { return null; }
}
export function main() {
@ -39,12 +39,12 @@ export function main() {
});
function emitSourceMap(
stmt: o.Statement | o.Statement[], exportedVars: string[] = null,
stmt: o.Statement | o.Statement[], exportedVars: string[] | null = null,
preamble?: string): SourceMap {
const stmts = Array.isArray(stmt) ? stmt : [stmt];
const source = emitter.emitStatements(
someSourceFilePath, someGenFilePath, stmts, exportedVars || [], preamble);
return extractSourceMap(source);
return extractSourceMap(source) !;
}
describe('source maps', () => {

View File

@ -29,8 +29,8 @@ class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
return importedUrlStr;
}
getImportAs(symbol: StaticSymbol): StaticSymbol { return null; }
getTypeArity(symbol: StaticSymbol): number /*|null*/ { return null; }
getImportAs(symbol: StaticSymbol): StaticSymbol|null { return null; }
getTypeArity(symbol: StaticSymbol): number|null { return null; }
}
export function main() {
@ -49,7 +49,8 @@ export function main() {
someVar = o.variable('someVar');
});
function emitStmt(stmt: o.Statement, exportedVars: string[] = null, preamble?: string): string {
function emitStmt(
stmt: o.Statement, exportedVars: string[] | null = null, preamble?: string): string {
const source = emitter.emitStatements(
someSourceFilePath, someGenFilePath, [stmt], exportedVars || [], preamble);
return stripSourceMapAndNewLine(source);
@ -224,15 +225,15 @@ export function main() {
beforeEach(() => { callSomeMethod = o.THIS_EXPR.callMethod('someMethod', []).toStmt(); });
it('should support declaring classes', () => {
expect(emitStmt(new o.ClassStmt('SomeClass', null, [], [], null, [
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, [
]))).toEqual(['function SomeClass() {', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt('SomeClass', null, [], [], null, []), ['SomeClass']))
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, []), ['SomeClass']))
.toEqual([
'function SomeClass() {', '}',
`Object.defineProperty(exports, 'SomeClass', { get: function() { return SomeClass; }});`
].join('\n'));
expect(
emitStmt(new o.ClassStmt('SomeClass', o.variable('SomeSuperClass'), [], [], null, [])))
expect(emitStmt(
new o.ClassStmt('SomeClass', o.variable('SomeSuperClass'), [], [], null !, [])))
.toEqual([
'function SomeClass() {', '}',
'SomeClass.prototype = Object.create(SomeSuperClass.prototype);'
@ -241,23 +242,24 @@ export function main() {
it('should support declaring constructors', () => {
const superCall = o.SUPER_EXPR.callFn([o.variable('someParam')]).toStmt();
expect(emitStmt(
new o.ClassStmt('SomeClass', null, [], [], new o.ClassMethod(null, [], []), [])))
expect(emitStmt(new o.ClassStmt(
'SomeClass', null !, [], [], new o.ClassMethod(null !, [], []), [])))
.toEqual(['function SomeClass() {', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [],
new o.ClassMethod(null, [new o.FnParam('someParam')], []), [])))
'SomeClass', null !, [], [],
new o.ClassMethod(null !, [new o.FnParam('someParam')], []), [])))
.toEqual(['function SomeClass(someParam) {', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', o.variable('SomeSuperClass'), [], [],
new o.ClassMethod(null, [], [superCall]), [])))
new o.ClassMethod(null !, [], [superCall]), [])))
.toEqual([
'function SomeClass() {', ' var self = this;',
' SomeSuperClass.call(this, someParam);', '}',
'SomeClass.prototype = Object.create(SomeSuperClass.prototype);'
].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [], new o.ClassMethod(null, [], [callSomeMethod]), [])))
expect(
emitStmt(new o.ClassStmt(
'SomeClass', null !, [], [], new o.ClassMethod(null !, [], [callSomeMethod]), [])))
.toEqual([
'function SomeClass() {', ' var self = this;', ' self.someMethod();', '}'
].join('\n'));
@ -265,14 +267,14 @@ export function main() {
it('should support declaring getters', () => {
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [new o.ClassGetter('someGetter', [])], null, [])))
'SomeClass', null !, [], [new o.ClassGetter('someGetter', [])], null !, [])))
.toEqual([
'function SomeClass() {', '}',
`Object.defineProperty(SomeClass.prototype, 'someGetter', { get: function() {`, `}});`
].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [new o.ClassGetter('someGetter', [callSomeMethod])], null,
[])))
'SomeClass', null !, [], [new o.ClassGetter('someGetter', [callSomeMethod])],
null !, [])))
.toEqual([
'function SomeClass() {', '}',
`Object.defineProperty(SomeClass.prototype, 'someGetter', { get: function() {`,
@ -282,19 +284,19 @@ export function main() {
it('should support methods', () => {
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [], null, [new o.ClassMethod('someMethod', [], [])])))
'SomeClass', null !, [], [], null !, [new o.ClassMethod('someMethod', [], [])])))
.toEqual([
'function SomeClass() {', '}', 'SomeClass.prototype.someMethod = function() {', '};'
].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [], null,
'SomeClass', null !, [], [], null !,
[new o.ClassMethod('someMethod', [new o.FnParam('someParam')], [])])))
.toEqual([
'function SomeClass() {', '}',
'SomeClass.prototype.someMethod = function(someParam) {', '};'
].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [], null,
'SomeClass', null !, [], [], null !,
[new o.ClassMethod('someMethod', [], [callSomeMethod])])))
.toEqual([
'function SomeClass() {', '}', 'SomeClass.prototype.someMethod = function() {',

View File

@ -52,7 +52,7 @@ export function main() {
.addMapping(3, 'a.js', 5, 2);
// Generated with https://sokra.github.io/source-map-visualization using a TS source map
expect(map.toJSON().mappings)
expect(map.toJSON() !.mappings)
.toEqual(
'AAAA,IAAM,CAAC,GAAe,CAAC,CAAC;AACxB,IAAM,CAAC,GAAG,CAAC,CAAC;AAEZ,EAAE,CAAC,OAAO,CAAC,UAAA,CAAC;IACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC,CAAA');
});
@ -64,7 +64,7 @@ export function main() {
.addSource('url.ts', null)
.addLine()
.addMapping(0, 'inline.ts', 0, 0)
.toJSON();
.toJSON() !;
expect(map.file).toEqual('out.js');
expect(map.sources).toEqual(['inline.ts', 'url.ts']);
@ -113,7 +113,7 @@ export function main() {
it('should throw when adding segments without column', () => {
expect(() => {
new SourceMapGenerator('out.js').addSource('in.js').addLine().addMapping(null);
new SourceMapGenerator('out.js').addSource('in.js').addLine().addMapping(null !);
}).toThrowError('The column in the generated code must be provided');
});

View File

@ -17,7 +17,8 @@ export interface SourceLocation {
}
export function originalPositionFor(
sourceMap: SourceMap, genPosition: {line: number, column: number}): SourceLocation {
sourceMap: SourceMap,
genPosition: {line: number | null, column: number | null}): SourceLocation {
const smc = new SourceMapConsumer(sourceMap);
// Note: We don't return the original object as it also contains a `name` property
// which is always null and we don't want to include that in our assertions...
@ -25,7 +26,7 @@ export function originalPositionFor(
return {line, column, source};
}
export function extractSourceMap(source: string): SourceMap {
export function extractSourceMap(source: string): SourceMap|null {
let idx = source.lastIndexOf('\n//#');
if (idx == -1) return null;
const smComment = source.slice(idx).trim();

View File

@ -23,8 +23,8 @@ class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
return importedUrlStr;
}
getImportAs(symbol: StaticSymbol): StaticSymbol { return null; }
getTypeArity(symbol: StaticSymbol): number /*|null*/ { return null; }
getImportAs(symbol: StaticSymbol): StaticSymbol|null { return null; }
getTypeArity(symbol: StaticSymbol): number|null { return null; }
}
export function main() {
@ -44,12 +44,12 @@ export function main() {
});
function emitSourceMap(
stmt: o.Statement | o.Statement[], exportedVars: string[] = null,
stmt: o.Statement | o.Statement[], exportedVars: string[] | null = null,
preamble?: string): SourceMap {
const stmts = Array.isArray(stmt) ? stmt : [stmt];
const source = emitter.emitStatements(
someSourceFilePath, someGenFilePath, stmts, exportedVars || [], preamble);
return extractSourceMap(source);
return extractSourceMap(source) !;
}
describe('source maps', () => {

View File

@ -30,8 +30,8 @@ class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
return importedUrlStr;
}
getImportAs(symbol: StaticSymbol): StaticSymbol { return null; }
getTypeArity(symbol: StaticSymbol): number /*|null*/ { return null; }
getImportAs(symbol: StaticSymbol): StaticSymbol|null { return null; }
getTypeArity(symbol: StaticSymbol): number|null { return null; }
}
export function main() {
@ -47,11 +47,11 @@ export function main() {
beforeEach(() => {
importResolver = new SimpleJsImportGenerator();
emitter = new TypeScriptEmitter(importResolver);
someVar = o.variable('someVar');
someVar = o.variable('someVar', null, null);
});
function emitStmt(
stmt: o.Statement | o.Statement[], exportedVars: string[] = null,
stmt: o.Statement | o.Statement[], exportedVars: string[] | null = null,
preamble?: string): string {
const stmts = Array.isArray(stmt) ? stmt : [stmt];
const source = emitter.emitStatements(
@ -310,31 +310,32 @@ export function main() {
it('should support declaring classes', () => {
expect(emitStmt(new o.ClassStmt('SomeClass', null, [], [], null, [
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, [
]))).toEqual(['class SomeClass {', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt('SomeClass', null, [], [], null, []), ['SomeClass']))
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, []), ['SomeClass']))
.toEqual(['export class SomeClass {', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt('SomeClass', o.variable('SomeSuperClass'), [], [], null, [
expect(emitStmt(new o.ClassStmt('SomeClass', o.variable('SomeSuperClass'), [], [], null !, [
]))).toEqual(['class SomeClass extends SomeSuperClass {', '}'].join('\n'));
});
it('should support declaring constructors', () => {
const superCall = o.SUPER_EXPR.callFn([o.variable('someParam')]).toStmt();
expect(emitStmt(
new o.ClassStmt('SomeClass', null, [], [], new o.ClassMethod(null, [], []), [])))
expect(emitStmt(new o.ClassStmt(
'SomeClass', null !, [], [], new o.ClassMethod(null !, [], []), [])))
.toEqual(['class SomeClass {', ' constructor() {', ' }', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [],
new o.ClassMethod(null, [new o.FnParam('someParam', o.INT_TYPE)], []), [])))
'SomeClass', null !, [], [],
new o.ClassMethod(null !, [new o.FnParam('someParam', o.INT_TYPE)], []), [])))
.toEqual(
['class SomeClass {', ' constructor(someParam:number) {', ' }', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [], new o.ClassMethod(null, [], [superCall]), [])))
'SomeClass', null !, [], [], new o.ClassMethod(null !, [], [superCall]), [])))
.toEqual([
'class SomeClass {', ' constructor() {', ' super(someParam);', ' }', '}'
].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [], new o.ClassMethod(null, [], [callSomeMethod]), [])))
expect(
emitStmt(new o.ClassStmt(
'SomeClass', null !, [], [], new o.ClassMethod(null !, [], [callSomeMethod]), [])))
.toEqual([
'class SomeClass {', ' constructor() {', ' this.someMethod();', ' }', '}'
].join('\n'));
@ -342,56 +343,57 @@ export function main() {
it('should support declaring fields', () => {
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [new o.ClassField('someField')], [], null, [])))
'SomeClass', null !, [new o.ClassField('someField')], [], null !, [])))
.toEqual(['class SomeClass {', ' someField:any;', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [new o.ClassField('someField', o.INT_TYPE)], [], null, [])))
expect(
emitStmt(new o.ClassStmt(
'SomeClass', null !, [new o.ClassField('someField', o.INT_TYPE)], [], null !, [])))
.toEqual(['class SomeClass {', ' someField:number;', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null,
[new o.ClassField('someField', o.INT_TYPE, [o.StmtModifier.Private])], [], null,
[])))
'SomeClass', null !,
[new o.ClassField('someField', o.INT_TYPE, [o.StmtModifier.Private])], [],
null !, [])))
.toEqual(['class SomeClass {', ' /*private*/ someField:number;', '}'].join('\n'));
});
it('should support declaring getters', () => {
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [new o.ClassGetter('someGetter', [])], null, [])))
'SomeClass', null !, [], [new o.ClassGetter('someGetter', [])], null !, [])))
.toEqual(['class SomeClass {', ' get someGetter():any {', ' }', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [new o.ClassGetter('someGetter', [], o.INT_TYPE)], null,
[])))
'SomeClass', null !, [], [new o.ClassGetter('someGetter', [], o.INT_TYPE)],
null !, [])))
.toEqual(['class SomeClass {', ' get someGetter():number {', ' }', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [new o.ClassGetter('someGetter', [callSomeMethod])], null,
[])))
'SomeClass', null !, [], [new o.ClassGetter('someGetter', [callSomeMethod])],
null !, [])))
.toEqual([
'class SomeClass {', ' get someGetter():any {', ' this.someMethod();', ' }', '}'
].join('\n'));
expect(
emitStmt(new o.ClassStmt(
'SomeClass', null, [],
[new o.ClassGetter('someGetter', [], null, [o.StmtModifier.Private])], null, [])))
expect(emitStmt(new o.ClassStmt(
'SomeClass', null !, [],
[new o.ClassGetter('someGetter', [], null !, [o.StmtModifier.Private])], null !,
[])))
.toEqual(
['class SomeClass {', ' private get someGetter():any {', ' }', '}'].join('\n'));
});
it('should support methods', () => {
expect(emitStmt(new o.ClassStmt('SomeClass', null, [], [], null, [
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, [
new o.ClassMethod('someMethod', [], [])
]))).toEqual(['class SomeClass {', ' someMethod():void {', ' }', '}'].join('\n'));
expect(emitStmt(new o.ClassStmt('SomeClass', null, [], [], null, [
expect(emitStmt(new o.ClassStmt('SomeClass', null !, [], [], null !, [
new o.ClassMethod('someMethod', [], [], o.INT_TYPE)
]))).toEqual(['class SomeClass {', ' someMethod():number {', ' }', '}'].join('\n'));
expect(
emitStmt(new o.ClassStmt(
'SomeClass', null, [], [], null,
'SomeClass', null !, [], [], null !,
[new o.ClassMethod('someMethod', [new o.FnParam('someParam', o.INT_TYPE)], [])])))
.toEqual([
'class SomeClass {', ' someMethod(someParam:number):void {', ' }', '}'
].join('\n'));
expect(emitStmt(new o.ClassStmt(
'SomeClass', null, [], [], null,
'SomeClass', null !, [], [], null !,
[new o.ClassMethod('someMethod', [], [callSomeMethod])])))
.toEqual([
'class SomeClass {', ' someMethod():void {', ' this.someMethod();', ' }', '}'
@ -453,7 +455,7 @@ export function main() {
it('should support combined types', () => {
const writeVarExpr = o.variable('a').set(o.NULL_EXPR);
expect(emitStmt(writeVarExpr.toDeclStmt(new o.ArrayType(null))))
expect(emitStmt(writeVarExpr.toDeclStmt(new o.ArrayType(null !))))
.toEqual('var a:any[] = (null as any);');
expect(emitStmt(writeVarExpr.toDeclStmt(new o.ArrayType(o.INT_TYPE))))
.toEqual('var a:number[] = (null as any);');

Some files were not shown because too many files have changed in this diff Show More