refactor(tsc-wrapped): update tsc-wrapped to pass strictNullCheck (#18160)
PR Close #18160
This commit is contained in:

committed by
Miško Hevery

parent
619e625ee2
commit
abee785821
@ -70,7 +70,9 @@ export interface BundledModule {
|
||||
privates: BundlePrivateEntry[];
|
||||
}
|
||||
|
||||
export interface MetadataBundlerHost { getMetadataFor(moduleName: string): ModuleMetadata; }
|
||||
export interface MetadataBundlerHost {
|
||||
getMetadataFor(moduleName: string): ModuleMetadata|undefined;
|
||||
}
|
||||
|
||||
type StaticsMetadata = {
|
||||
[name: string]: MetadataValue | FunctionMetadata;
|
||||
@ -78,7 +80,7 @@ type StaticsMetadata = {
|
||||
|
||||
export class MetadataBundler {
|
||||
private symbolMap = new Map<string, Symbol>();
|
||||
private metadataCache = new Map<string, ModuleMetadata>();
|
||||
private metadataCache = new Map<string, ModuleMetadata|undefined>();
|
||||
private exports = new Map<string, Symbol[]>();
|
||||
private rootModule: string;
|
||||
private exported: Set<Symbol>;
|
||||
@ -98,14 +100,14 @@ export class MetadataBundler {
|
||||
const privates = Array.from(this.symbolMap.values())
|
||||
.filter(s => s.referenced && s.isPrivate)
|
||||
.map(s => ({
|
||||
privateName: s.privateName,
|
||||
name: s.declaration.name,
|
||||
module: s.declaration.module
|
||||
privateName: s.privateName !,
|
||||
name: s.declaration !.name,
|
||||
module: s.declaration !.module
|
||||
}));
|
||||
const origins = Array.from(this.symbolMap.values())
|
||||
.filter(s => s.referenced && !s.reexport)
|
||||
.reduce<{[name: string]: string}>((p, s) => {
|
||||
p[s.isPrivate ? s.privateName : s.name] = s.declaration.module;
|
||||
p[s.isPrivate ? s.privateName ! : s.name] = s.declaration !.module;
|
||||
return p;
|
||||
}, {});
|
||||
const exports = this.getReExports(exportedSymbols);
|
||||
@ -114,7 +116,7 @@ export class MetadataBundler {
|
||||
__symbolic: 'module',
|
||||
version: VERSION,
|
||||
exports: exports.length ? exports : undefined, metadata, origins,
|
||||
importAs: this.importAs
|
||||
importAs: this.importAs !
|
||||
},
|
||||
privates
|
||||
};
|
||||
@ -124,7 +126,7 @@ export class MetadataBundler {
|
||||
return resolveModule(importName, from);
|
||||
}
|
||||
|
||||
private getMetadata(moduleName: string): ModuleMetadata {
|
||||
private getMetadata(moduleName: string): ModuleMetadata|undefined {
|
||||
let result = this.metadataCache.get(moduleName);
|
||||
if (!result) {
|
||||
if (moduleName.startsWith('.')) {
|
||||
@ -138,7 +140,7 @@ export class MetadataBundler {
|
||||
|
||||
private exportAll(moduleName: string): Symbol[] {
|
||||
const module = this.getMetadata(moduleName);
|
||||
let result: Symbol[] = this.exports.get(moduleName);
|
||||
let result = this.exports.get(moduleName);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
@ -148,7 +150,7 @@ export class MetadataBundler {
|
||||
|
||||
const exportSymbol = (exportedSymbol: Symbol, exportAs: string) => {
|
||||
const symbol = this.symbolOf(moduleName, exportAs);
|
||||
result.push(symbol);
|
||||
result !.push(symbol);
|
||||
exportedSymbol.reexportedAs = symbol;
|
||||
symbol.exports = exportedSymbol;
|
||||
};
|
||||
@ -266,7 +268,7 @@ export class MetadataBundler {
|
||||
name = newPrivateName();
|
||||
symbol.privateName = name;
|
||||
}
|
||||
result[name] = symbol.value;
|
||||
result[name] = symbol.value !;
|
||||
}
|
||||
});
|
||||
|
||||
@ -279,9 +281,10 @@ export class MetadataBundler {
|
||||
const exportAlls = new Set<string>();
|
||||
for (const symbol of exportedSymbols) {
|
||||
if (symbol.reexport) {
|
||||
const declaration = symbol.declaration;
|
||||
// symbol.declaration is guarenteed to be defined during the phase this method is called.
|
||||
const declaration = symbol.declaration !;
|
||||
const module = declaration.module;
|
||||
if (declaration.name == '*') {
|
||||
if (declaration !.name == '*') {
|
||||
// Reexport all the symbols.
|
||||
exportAlls.add(declaration.module);
|
||||
} else {
|
||||
@ -304,11 +307,13 @@ export class MetadataBundler {
|
||||
}
|
||||
|
||||
private convertSymbol(symbol: Symbol) {
|
||||
const canonicalSymbol = symbol.canonicalSymbol;
|
||||
// canonicalSymbol is ensured to be defined before this is called.
|
||||
const canonicalSymbol = symbol.canonicalSymbol !;
|
||||
|
||||
if (!canonicalSymbol.referenced) {
|
||||
canonicalSymbol.referenced = true;
|
||||
const declaration = canonicalSymbol.declaration;
|
||||
// declaration is ensured to be definded before this method is called.
|
||||
const declaration = canonicalSymbol.declaration !;
|
||||
const module = this.getMetadata(declaration.module);
|
||||
if (module) {
|
||||
const value = module.metadata[declaration.name];
|
||||
@ -336,10 +341,10 @@ export class MetadataBundler {
|
||||
return {
|
||||
__symbolic: 'class',
|
||||
arity: value.arity,
|
||||
extends: this.convertExpression(moduleName, value.extends),
|
||||
extends: this.convertExpression(moduleName, value.extends) !,
|
||||
decorators:
|
||||
value.decorators && value.decorators.map(d => this.convertExpression(moduleName, d)),
|
||||
members: this.convertMembers(moduleName, value.members),
|
||||
value.decorators && value.decorators.map(d => this.convertExpression(moduleName, d) !),
|
||||
members: this.convertMembers(moduleName, value.members !),
|
||||
statics: value.statics && this.convertStatics(moduleName, value.statics)
|
||||
};
|
||||
}
|
||||
@ -356,11 +361,11 @@ export class MetadataBundler {
|
||||
private convertMember(moduleName: string, member: MemberMetadata) {
|
||||
const result: MemberMetadata = {__symbolic: member.__symbolic};
|
||||
result.decorators =
|
||||
member.decorators && member.decorators.map(d => this.convertExpression(moduleName, d));
|
||||
member.decorators && member.decorators.map(d => this.convertExpression(moduleName, d) !);
|
||||
if (isMethodMetadata(member)) {
|
||||
(result as MethodMetadata).parameterDecorators = member.parameterDecorators &&
|
||||
member.parameterDecorators.map(
|
||||
d => d && d.map(p => this.convertExpression(moduleName, p)));
|
||||
d => d && d.map(p => this.convertExpression(moduleName, p) !));
|
||||
if (isConstructorMetadata(member)) {
|
||||
if (member.parameters) {
|
||||
(result as ConstructorMetadata).parameters =
|
||||
@ -397,7 +402,7 @@ export class MetadataBundler {
|
||||
return this.convertError(moduleName, value);
|
||||
}
|
||||
if (isMetadataSymbolicExpression(value)) {
|
||||
return this.convertExpression(moduleName, value);
|
||||
return this.convertExpression(moduleName, value) !;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(v => this.convertValue(moduleName, v));
|
||||
@ -413,8 +418,8 @@ export class MetadataBundler {
|
||||
}
|
||||
|
||||
private convertExpression(
|
||||
moduleName: string, value: MetadataSymbolicExpression|MetadataError|
|
||||
undefined): MetadataSymbolicExpression|MetadataError|undefined {
|
||||
moduleName: string, value: MetadataSymbolicExpression|MetadataError|null|
|
||||
undefined): MetadataSymbolicExpression|MetadataError|undefined|null {
|
||||
if (value) {
|
||||
switch (value.__symbolic) {
|
||||
case 'error':
|
||||
@ -439,9 +444,9 @@ export class MetadataBundler {
|
||||
}
|
||||
|
||||
private convertReference(moduleName: string, value: MetadataSymbolicReferenceExpression):
|
||||
MetadataSymbolicReferenceExpression|MetadataError {
|
||||
MetadataSymbolicReferenceExpression|MetadataError|undefined {
|
||||
const createReference = (symbol: Symbol): MetadataSymbolicReferenceExpression => {
|
||||
const declaration = symbol.declaration;
|
||||
const declaration = symbol.declaration !;
|
||||
if (declaration.module.startsWith('.')) {
|
||||
// Reference to a symbol defined in the module. Ensure it is converted then return a
|
||||
// references to the final symbol.
|
||||
@ -450,11 +455,11 @@ export class MetadataBundler {
|
||||
__symbolic: 'reference',
|
||||
get name() {
|
||||
// Resolved lazily because private names are assigned late.
|
||||
const canonicalSymbol = symbol.canonicalSymbol;
|
||||
const canonicalSymbol = symbol.canonicalSymbol !;
|
||||
if (canonicalSymbol.isPrivate == null) {
|
||||
throw Error('Invalid state: isPrivate was not initialized');
|
||||
}
|
||||
return canonicalSymbol.isPrivate ? canonicalSymbol.privateName : canonicalSymbol.name;
|
||||
return canonicalSymbol.isPrivate ? canonicalSymbol.privateName ! : canonicalSymbol.name;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
@ -564,7 +569,7 @@ export class CompilerHostAdapter implements MetadataBundlerHost {
|
||||
|
||||
constructor(private host: ts.CompilerHost) {}
|
||||
|
||||
getMetadataFor(fileName: string): ModuleMetadata {
|
||||
getMetadataFor(fileName: string): ModuleMetadata|undefined {
|
||||
const sourceFile = this.host.getSourceFile(fileName + '.ts', ts.ScriptTarget.Latest);
|
||||
return this.collector.getMetadata(sourceFile);
|
||||
}
|
||||
|
@ -6,8 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
export class CliOptions {
|
||||
public basePath: string;
|
||||
constructor({basePath = null}: {basePath?: string}) { this.basePath = basePath; }
|
||||
public basePath: string|null;
|
||||
constructor({basePath = null}: {basePath?: string | null}) { this.basePath = basePath; }
|
||||
}
|
||||
|
||||
export class I18nExtractionCliOptions extends CliOptions {
|
||||
@ -28,18 +28,18 @@ export class I18nExtractionCliOptions extends CliOptions {
|
||||
}
|
||||
|
||||
export class NgcCliOptions extends CliOptions {
|
||||
public i18nFormat: string;
|
||||
public i18nFile: string;
|
||||
public locale: string;
|
||||
public missingTranslation: string;
|
||||
public i18nFormat: string|null;
|
||||
public i18nFile: string|null;
|
||||
public locale: string|null;
|
||||
public missingTranslation: string|null;
|
||||
|
||||
constructor({i18nFormat = null, i18nFile = null, locale = null, missingTranslation = null,
|
||||
basePath = null}: {
|
||||
i18nFormat?: string,
|
||||
i18nFile?: string,
|
||||
locale?: string,
|
||||
missingTranslation?: string,
|
||||
basePath?: string
|
||||
i18nFormat?: string | null,
|
||||
i18nFile?: string|null,
|
||||
locale?: string|null,
|
||||
missingTranslation?: string|null,
|
||||
basePath?: string|null
|
||||
}) {
|
||||
super({basePath: basePath});
|
||||
this.i18nFormat = i18nFormat;
|
||||
|
@ -54,13 +54,13 @@ export class MetadataCollector {
|
||||
* Returns a JSON.stringify friendly form describing the decorators of the exported classes from
|
||||
* the source file that is expected to correspond to a module.
|
||||
*/
|
||||
public getMetadata(sourceFile: ts.SourceFile, strict: boolean = false): ModuleMetadata {
|
||||
public getMetadata(sourceFile: ts.SourceFile, strict: boolean = false): ModuleMetadata|undefined {
|
||||
const locals = new Symbols(sourceFile);
|
||||
const nodeMap =
|
||||
new Map<MetadataValue|ClassMetadata|InterfaceMetadata|FunctionMetadata, ts.Node>();
|
||||
const evaluator = new Evaluator(locals, nodeMap, this.options);
|
||||
let metadata: {[name: string]: MetadataValue | ClassMetadata | FunctionMetadata}|undefined;
|
||||
let exports: ModuleExportMetadata[];
|
||||
let exports: ModuleExportMetadata[]|undefined = undefined;
|
||||
|
||||
function objFromDecorator(decoratorNode: ts.Decorator): MetadataSymbolicExpression {
|
||||
return <MetadataSymbolicExpression>evaluator.evaluateNode(decoratorNode.expression);
|
||||
@ -79,7 +79,7 @@ export class MetadataCollector {
|
||||
function maybeGetSimpleFunction(
|
||||
functionDeclaration: ts.FunctionDeclaration |
|
||||
ts.MethodDeclaration): {func: FunctionMetadata, name: string}|undefined {
|
||||
if (functionDeclaration.name.kind == ts.SyntaxKind.Identifier) {
|
||||
if (functionDeclaration.name && functionDeclaration.name.kind == ts.SyntaxKind.Identifier) {
|
||||
const nameNode = <ts.Identifier>functionDeclaration.name;
|
||||
const functionName = nameNode.text;
|
||||
const functionBody = functionDeclaration.body;
|
||||
@ -107,7 +107,8 @@ export class MetadataCollector {
|
||||
function classMetadataOf(classDeclaration: ts.ClassDeclaration): ClassMetadata {
|
||||
const result: ClassMetadata = {__symbolic: 'class'};
|
||||
|
||||
function getDecorators(decorators: ts.Decorator[]): MetadataSymbolicExpression[] {
|
||||
function getDecorators(decorators: ts.Decorator[] | undefined): MetadataSymbolicExpression[]|
|
||||
undefined {
|
||||
if (decorators && decorators.length)
|
||||
return decorators.map(decorator => objFromDecorator(decorator));
|
||||
return undefined;
|
||||
@ -145,7 +146,7 @@ export class MetadataCollector {
|
||||
}
|
||||
|
||||
// member decorators
|
||||
let members: MetadataMap = null;
|
||||
let members: MetadataMap|null = null;
|
||||
function recordMember(name: string, metadata: MemberMetadata) {
|
||||
if (!members) members = {};
|
||||
const data = members.hasOwnProperty(name) ? members[name] : [];
|
||||
@ -154,7 +155,7 @@ export class MetadataCollector {
|
||||
}
|
||||
|
||||
// static member
|
||||
let statics: {[name: string]: MetadataValue | FunctionMetadata} = null;
|
||||
let statics: {[name: string]: MetadataValue | FunctionMetadata}|null = null;
|
||||
function recordStaticMember(name: string, value: MetadataValue | FunctionMetadata) {
|
||||
if (!statics) statics = {};
|
||||
statics[name] = value;
|
||||
@ -176,7 +177,8 @@ export class MetadataCollector {
|
||||
}
|
||||
const methodDecorators = getDecorators(method.decorators);
|
||||
const parameters = method.parameters;
|
||||
const parameterDecoratorData: (MetadataSymbolicExpression | MetadataError)[][] = [];
|
||||
const parameterDecoratorData:
|
||||
((MetadataSymbolicExpression | MetadataError)[] | undefined)[] = [];
|
||||
const parametersData:
|
||||
(MetadataSymbolicReferenceExpression | MetadataError |
|
||||
MetadataSymbolicSelectExpression | null)[] = [];
|
||||
@ -254,7 +256,8 @@ export class MetadataCollector {
|
||||
const {moduleSpecifier, exportClause} = exportDeclaration;
|
||||
|
||||
if (!moduleSpecifier) {
|
||||
exportClause.elements.forEach(spec => {
|
||||
// If there is a module specifier there is also an exportClause
|
||||
exportClause !.elements.forEach(spec => {
|
||||
const exportedAs = spec.name.text;
|
||||
const name = (spec.propertyName || spec.name).text;
|
||||
exportMap.set(name, exportedAs);
|
||||
@ -263,12 +266,13 @@ export class MetadataCollector {
|
||||
}
|
||||
});
|
||||
|
||||
const isExportedIdentifier = (identifier: ts.Identifier) => exportMap.has(identifier.text);
|
||||
const isExportedIdentifier = (identifier?: ts.Identifier) =>
|
||||
identifier && exportMap.has(identifier.text);
|
||||
const isExported =
|
||||
(node: ts.FunctionDeclaration | ts.ClassDeclaration | ts.InterfaceDeclaration |
|
||||
ts.EnumDeclaration) => isExport(node) || isExportedIdentifier(node.name);
|
||||
const exportedIdentifierName = (identifier: ts.Identifier) =>
|
||||
exportMap.get(identifier.text) || identifier.text;
|
||||
const exportedIdentifierName = (identifier?: ts.Identifier) =>
|
||||
identifier && (exportMap.get(identifier.text) || identifier.text);
|
||||
const exportedName =
|
||||
(node: ts.FunctionDeclaration | ts.ClassDeclaration | ts.InterfaceDeclaration |
|
||||
ts.EnumDeclaration) => exportedIdentifierName(node.name);
|
||||
@ -358,8 +362,11 @@ export class MetadataCollector {
|
||||
const classDeclaration = <ts.ClassDeclaration>node;
|
||||
if (classDeclaration.name) {
|
||||
if (isExported(classDeclaration)) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[exportedName(classDeclaration)] = classMetadataOf(classDeclaration);
|
||||
const name = exportedName(classDeclaration);
|
||||
if (name) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[name] = classMetadataOf(classDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Otherwise don't record metadata for the class.
|
||||
@ -368,8 +375,11 @@ export class MetadataCollector {
|
||||
case ts.SyntaxKind.InterfaceDeclaration:
|
||||
const interfaceDeclaration = <ts.InterfaceDeclaration>node;
|
||||
if (interfaceDeclaration.name && isExported(interfaceDeclaration)) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[exportedName(interfaceDeclaration)] = {__symbolic: 'interface'};
|
||||
const name = exportedName(interfaceDeclaration);
|
||||
if (name) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[name] = {__symbolic: 'interface'};
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -378,11 +388,13 @@ export class MetadataCollector {
|
||||
// names substitution will be performed by the StaticReflector.
|
||||
const functionDeclaration = <ts.FunctionDeclaration>node;
|
||||
if (isExported(functionDeclaration) && functionDeclaration.name) {
|
||||
if (!metadata) metadata = {};
|
||||
const name = exportedName(functionDeclaration);
|
||||
const maybeFunc = maybeGetSimpleFunction(functionDeclaration);
|
||||
metadata[name] =
|
||||
maybeFunc ? recordEntry(maybeFunc.func, node) : {__symbolic: 'function'};
|
||||
if (name) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[name] =
|
||||
maybeFunc ? recordEntry(maybeFunc.func, node) : {__symbolic: 'function'};
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -400,7 +412,7 @@ export class MetadataCollector {
|
||||
} else {
|
||||
enumValue = evaluator.evaluateNode(member.initializer);
|
||||
}
|
||||
let name: string = undefined;
|
||||
let name: string|undefined = undefined;
|
||||
if (member.name.kind == ts.SyntaxKind.Identifier) {
|
||||
const identifier = <ts.Identifier>member.name;
|
||||
name = identifier.text;
|
||||
@ -424,8 +436,10 @@ export class MetadataCollector {
|
||||
}
|
||||
}
|
||||
if (writtenMembers) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[enumName] = recordEntry(enumValueHolder, node);
|
||||
if (enumName) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[enumName] = recordEntry(enumValueHolder, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -444,8 +458,11 @@ export class MetadataCollector {
|
||||
let exported = false;
|
||||
if (isExport(variableStatement) || isExport(variableDeclaration) ||
|
||||
isExportedIdentifier(nameNode)) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[exportedIdentifierName(nameNode)] = recordEntry(varValue, node);
|
||||
const name = exportedIdentifierName(nameNode);
|
||||
if (name) {
|
||||
if (!metadata) metadata = {};
|
||||
metadata[name] = recordEntry(varValue, node);
|
||||
}
|
||||
exported = true;
|
||||
}
|
||||
if (typeof varValue == 'string' || typeof varValue == 'number' ||
|
||||
@ -601,11 +618,11 @@ function validateMetadata(
|
||||
}
|
||||
if (classData.members) {
|
||||
Object.getOwnPropertyNames(classData.members)
|
||||
.forEach(name => classData.members[name].forEach((m) => validateMember(classData, m)));
|
||||
.forEach(name => classData.members ![name].forEach((m) => validateMember(classData, m)));
|
||||
}
|
||||
if (classData.statics) {
|
||||
Object.getOwnPropertyNames(classData.statics).forEach(name => {
|
||||
const staticMember = classData.statics[name];
|
||||
const staticMember = classData.statics ![name];
|
||||
if (isFunctionMetadata(staticMember)) {
|
||||
validateExpression(staticMember.value);
|
||||
} else {
|
||||
@ -628,7 +645,7 @@ function validateMetadata(
|
||||
}
|
||||
}
|
||||
|
||||
function shouldReportNode(node: ts.Node) {
|
||||
function shouldReportNode(node: ts.Node | undefined) {
|
||||
if (node) {
|
||||
const nodeStart = node.getStart();
|
||||
return !(
|
||||
|
@ -33,10 +33,10 @@ export abstract class DelegatingHost implements ts.CompilerHost {
|
||||
(fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void) =>
|
||||
this.delegate.getSourceFile(fileName, languageVersion, onError);
|
||||
|
||||
getCancellationToken = () => this.delegate.getCancellationToken();
|
||||
getCancellationToken = () => this.delegate.getCancellationToken !();
|
||||
getDefaultLibFileName = (options: ts.CompilerOptions) =>
|
||||
this.delegate.getDefaultLibFileName(options);
|
||||
getDefaultLibLocation = () => this.delegate.getDefaultLibLocation();
|
||||
getDefaultLibLocation = () => this.delegate.getDefaultLibLocation !();
|
||||
writeFile: ts.WriteFileCallback = this.delegate.writeFile;
|
||||
getCurrentDirectory = () => this.delegate.getCurrentDirectory();
|
||||
getDirectories = (path: string): string[] =>
|
||||
@ -46,8 +46,8 @@ export abstract class DelegatingHost implements ts.CompilerHost {
|
||||
getNewLine = () => this.delegate.getNewLine();
|
||||
fileExists = (fileName: string) => this.delegate.fileExists(fileName);
|
||||
readFile = (fileName: string) => this.delegate.readFile(fileName);
|
||||
trace = (s: string) => this.delegate.trace(s);
|
||||
directoryExists = (directoryName: string) => this.delegate.directoryExists(directoryName);
|
||||
trace = (s: string) => this.delegate.trace !(s);
|
||||
directoryExists = (directoryName: string) => this.delegate.directoryExists !(directoryName);
|
||||
}
|
||||
|
||||
const IGNORED_FILES = /\.ngfactory\.js$|\.ngstyle\.js$/;
|
||||
@ -79,7 +79,8 @@ export class MetadataWriterHost extends DelegatingHost {
|
||||
const metadata =
|
||||
this.metadataCollector.getMetadata(collectableFile, !!this.ngOptions.strictMetadataEmit);
|
||||
const metadata1 = this.metadataCollector1.getMetadata(collectableFile, false);
|
||||
const metadatas: ModuleMetadata[] = [metadata, metadata1].filter(e => !!e);
|
||||
const metadatas: ModuleMetadata[] =
|
||||
[metadata, metadata1].filter(e => !!e) as ModuleMetadata[];
|
||||
if (metadatas.length) {
|
||||
const metadataText = JSON.stringify(metadatas);
|
||||
writeFileSync(path, metadataText, {encoding: 'utf-8'});
|
||||
@ -163,7 +164,7 @@ export class SyntheticIndexHost extends DelegatingHost {
|
||||
normalize(sourceFiles[0].fileName) == this.normalSyntheticIndexName) {
|
||||
// If we are writing the synthetic index, write the metadata along side.
|
||||
const metadataName = fileName.replace(DTS, '.metadata.json');
|
||||
writeFileSync(metadataName, this.indexMetadata, 'utf8');
|
||||
writeFileSync(metadataName, this.indexMetadata, {encoding: 'utf8'});
|
||||
}
|
||||
}
|
||||
}
|
@ -68,7 +68,7 @@ export interface ImportMetadata {
|
||||
}
|
||||
|
||||
|
||||
function getSourceFileOfNode(node: ts.Node): ts.SourceFile {
|
||||
function getSourceFileOfNode(node: ts.Node | undefined): ts.SourceFile {
|
||||
while (node && node.kind != ts.SyntaxKind.SourceFile) {
|
||||
node = node.parent;
|
||||
}
|
||||
@ -79,7 +79,7 @@ function getSourceFileOfNode(node: ts.Node): ts.SourceFile {
|
||||
export function errorSymbol(
|
||||
message: string, node?: ts.Node, context?: {[name: string]: string},
|
||||
sourceFile?: ts.SourceFile): MetadataError {
|
||||
let result: MetadataError;
|
||||
let result: MetadataError|undefined = undefined;
|
||||
if (node) {
|
||||
sourceFile = sourceFile || getSourceFileOfNode(node);
|
||||
if (sourceFile) {
|
||||
@ -106,15 +106,16 @@ export class Evaluator {
|
||||
private symbols: Symbols, private nodeMap: Map<MetadataEntry, ts.Node>,
|
||||
private options: CollectorOptions = {}) {}
|
||||
|
||||
nameOf(node: ts.Node): string|MetadataError {
|
||||
if (node.kind == ts.SyntaxKind.Identifier) {
|
||||
nameOf(node: ts.Node|undefined): string|MetadataError {
|
||||
if (node && node.kind == ts.SyntaxKind.Identifier) {
|
||||
return (<ts.Identifier>node).text;
|
||||
}
|
||||
const result = this.evaluateNode(node);
|
||||
const result = node && this.evaluateNode(node);
|
||||
if (isMetadataError(result) || typeof result === 'string') {
|
||||
return result;
|
||||
} else {
|
||||
return errorSymbol('Name expected', node, {received: node.getText()});
|
||||
return errorSymbol(
|
||||
'Name expected', node, {received: (node && node.getText()) || '<missing>'});
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +139,7 @@ export class Evaluator {
|
||||
return this.isFoldableWorker(node, new Map<ts.Node, boolean>());
|
||||
}
|
||||
|
||||
private isFoldableWorker(node: ts.Node, folding: Map<ts.Node, boolean>): boolean {
|
||||
private isFoldableWorker(node: ts.Node|undefined, folding: Map<ts.Node, boolean>): boolean {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.ObjectLiteralExpression:
|
||||
@ -518,11 +519,11 @@ export class Evaluator {
|
||||
if (isDefined(operand) && isPrimitive(operand)) {
|
||||
switch (prefixUnaryExpression.operator) {
|
||||
case ts.SyntaxKind.PlusToken:
|
||||
return +operand;
|
||||
return +(operand as any);
|
||||
case ts.SyntaxKind.MinusToken:
|
||||
return -operand;
|
||||
return -(operand as any);
|
||||
case ts.SyntaxKind.TildeToken:
|
||||
return ~operand;
|
||||
return ~(operand as any);
|
||||
case ts.SyntaxKind.ExclamationToken:
|
||||
return !operand;
|
||||
}
|
||||
@ -661,8 +662,8 @@ function isPropertyAssignment(node: ts.Node): node is ts.PropertyAssignment {
|
||||
return node.kind == ts.SyntaxKind.PropertyAssignment;
|
||||
}
|
||||
|
||||
const empty = [] as ts.NodeArray<any>;
|
||||
const empty = ts.createNodeArray<any>();
|
||||
|
||||
function arrayOrEmpty<T extends ts.Node>(v: ts.NodeArray<T>): ts.NodeArray<T> {
|
||||
function arrayOrEmpty<T extends ts.Node>(v: ts.NodeArray<T>| undefined): ts.NodeArray<T> {
|
||||
return v || empty;
|
||||
}
|
@ -41,9 +41,9 @@ export function createBundleIndexHost(
|
||||
return {
|
||||
host,
|
||||
errors: [{
|
||||
file: null,
|
||||
start: null,
|
||||
length: null,
|
||||
file: null as any as ts.SourceFile,
|
||||
start: null as any as number,
|
||||
length: null as any as number,
|
||||
messageText:
|
||||
'Angular compiler option "flatModuleIndex" requires one and only one .ts file in the "files" field.',
|
||||
category: ts.DiagnosticCategory.Error,
|
||||
@ -58,7 +58,7 @@ export function createBundleIndexHost(
|
||||
const metadataBundle = bundler.getMetadataBundle();
|
||||
const metadata = JSON.stringify(metadataBundle.metadata);
|
||||
const name =
|
||||
path.join(path.dirname(indexModule), ngOptions.flatModuleOutFile.replace(JS_EXT, '.ts'));
|
||||
path.join(path.dirname(indexModule), ngOptions.flatModuleOutFile !.replace(JS_EXT, '.ts'));
|
||||
const libraryIndex = `./${path.basename(indexModule)}`;
|
||||
const content = privateEntriesToIndex(libraryIndex, metadataBundle.privates);
|
||||
host = new SyntheticIndexHost(host, {name, content, metadata});
|
||||
@ -201,7 +201,7 @@ if (require.main === module) {
|
||||
const project = options.project || '.';
|
||||
// TODO(alexeagle): command line should be TSC-compatible, remove "CliOptions" here
|
||||
const cliOptions = new CliOptions(require('minimist')(args));
|
||||
main(project, cliOptions, null, options)
|
||||
main(project, cliOptions, undefined, options)
|
||||
.then((exitCode: any) => process.exit(exitCode))
|
||||
.catch((e: any) => {
|
||||
console.error(e.stack);
|
||||
|
@ -73,7 +73,7 @@ export function isMemberMetadata(value: any): value is MemberMetadata {
|
||||
|
||||
export interface MethodMetadata extends MemberMetadata {
|
||||
__symbolic: 'constructor'|'method';
|
||||
parameterDecorators?: (MetadataSymbolicExpression|MetadataError)[][];
|
||||
parameterDecorators?: ((MetadataSymbolicExpression | MetadataError)[]|undefined)[];
|
||||
}
|
||||
export function isMethodMetadata(value: any): value is MethodMetadata {
|
||||
return value && (value.__symbolic === 'constructor' || value.__symbolic === 'method');
|
||||
@ -81,7 +81,7 @@ export function isMethodMetadata(value: any): value is MethodMetadata {
|
||||
|
||||
export interface ConstructorMetadata extends MethodMetadata {
|
||||
__symbolic: 'constructor';
|
||||
parameters?: (MetadataSymbolicExpression|MetadataError|null)[];
|
||||
parameters?: (MetadataSymbolicExpression|MetadataError|null|undefined)[];
|
||||
}
|
||||
export function isConstructorMetadata(value: any): value is ConstructorMetadata {
|
||||
return value && value.__symbolic === 'constructor';
|
||||
@ -97,8 +97,8 @@ export function isFunctionMetadata(value: any): value is FunctionMetadata {
|
||||
return value && value.__symbolic === 'function';
|
||||
}
|
||||
|
||||
export type MetadataValue = string | number | boolean | MetadataObject | MetadataArray |
|
||||
MetadataSymbolicExpression | MetadataError;
|
||||
export type MetadataValue = string | number | boolean | undefined | null | MetadataObject |
|
||||
MetadataArray | MetadataSymbolicExpression | MetadataError;
|
||||
|
||||
export interface MetadataObject { [name: string]: MetadataValue; }
|
||||
|
||||
|
@ -49,23 +49,26 @@ export class Symbols {
|
||||
ts.SyntaxKind.ExternalModuleReference) {
|
||||
const externalReference =
|
||||
<ts.ExternalModuleReference>importEqualsDeclaration.moduleReference;
|
||||
// An `import <identifier> = require(<module-specifier>);
|
||||
if (!externalReference.expression.parent) {
|
||||
// The `parent` field of a node is set by the TypeScript binder (run as
|
||||
// part of the type checker). Setting it here allows us to call `getText()`
|
||||
// even if the `SourceFile` was not type checked (which looks for `SourceFile`
|
||||
// in the parent chain). This doesn't damage the node as the binder unconditionally
|
||||
// sets the parent.
|
||||
externalReference.expression.parent = externalReference;
|
||||
externalReference.parent = this.sourceFile as any;
|
||||
if (externalReference.expression) {
|
||||
// An `import <identifier> = require(<module-specifier>);
|
||||
if (!externalReference.expression.parent) {
|
||||
// The `parent` field of a node is set by the TypeScript binder (run as
|
||||
// part of the type checker). Setting it here allows us to call `getText()`
|
||||
// even if the `SourceFile` was not type checked (which looks for `SourceFile`
|
||||
// in the parent chain). This doesn't damage the node as the binder unconditionally
|
||||
// sets the parent.
|
||||
externalReference.expression.parent = externalReference;
|
||||
externalReference.parent = this.sourceFile as any;
|
||||
}
|
||||
const from = stripQuotes(externalReference.expression.getText());
|
||||
symbols.set(
|
||||
importEqualsDeclaration.name.text, {__symbolic: 'reference', module: from});
|
||||
break;
|
||||
}
|
||||
const from = stripQuotes(externalReference.expression.getText());
|
||||
symbols.set(importEqualsDeclaration.name.text, {__symbolic: 'reference', module: from});
|
||||
} else {
|
||||
symbols.set(
|
||||
importEqualsDeclaration.name.text,
|
||||
{__symbolic: 'error', message: `Unsupported import syntax`});
|
||||
}
|
||||
symbols.set(
|
||||
importEqualsDeclaration.name.text,
|
||||
{__symbolic: 'error', message: `Unsupported import syntax`});
|
||||
break;
|
||||
case ts.SyntaxKind.ImportDeclaration:
|
||||
const importDecl = <ts.ImportDeclaration>node;
|
||||
|
@ -33,7 +33,7 @@ export class UserError extends Error {
|
||||
super(message);
|
||||
// Required for TS 2.1, see
|
||||
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
||||
Object.setPrototypeOf(this, UserError.prototype);
|
||||
(Object as any).setPrototypeOf(this, UserError.prototype);
|
||||
|
||||
const nativeError = new Error(message) as any as Error;
|
||||
this._nativeError = nativeError;
|
||||
@ -76,13 +76,14 @@ export function formatDiagnostics(diags: ts.Diagnostic[]): string {
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
export function check(diags: ts.Diagnostic[]) {
|
||||
export function check(diags: ts.Diagnostic[] | undefined) {
|
||||
if (diags && diags.length && diags[0]) {
|
||||
throw new UserError(formatDiagnostics(diags));
|
||||
}
|
||||
}
|
||||
|
||||
export function validateAngularCompilerOptions(options: AngularCompilerOptions): ts.Diagnostic[] {
|
||||
export function validateAngularCompilerOptions(options: AngularCompilerOptions): ts.Diagnostic[]|
|
||||
undefined {
|
||||
if (options.annotationsAs) {
|
||||
switch (options.annotationsAs) {
|
||||
case 'decorators':
|
||||
@ -90,9 +91,9 @@ export function validateAngularCompilerOptions(options: AngularCompilerOptions):
|
||||
break;
|
||||
default:
|
||||
return [{
|
||||
file: null,
|
||||
start: null,
|
||||
length: null,
|
||||
file: null as any as ts.SourceFile,
|
||||
start: null as any as number,
|
||||
length: null as any as number,
|
||||
messageText:
|
||||
'Angular compiler options "annotationsAs" only supports "static fields" and "decorators"',
|
||||
category: ts.DiagnosticCategory.Error,
|
||||
@ -136,7 +137,7 @@ export class Tsc implements CompilerInterface {
|
||||
return ts.readConfigFile(project, this.readFile);
|
||||
}
|
||||
})();
|
||||
check([error]);
|
||||
check([error !]);
|
||||
|
||||
const parsed =
|
||||
ts.parseJsonConfigFileContent(config, this.parseConfigHost, basePath, existingOptions);
|
||||
|
Reference in New Issue
Block a user