feat: add TypeScript 3 support (#25275)

PR Close #25275
This commit is contained in:
Alan Agius
2018-08-05 17:31:27 +02:00
committed by Matias Niemelä
parent c230173716
commit 5653fada32
30 changed files with 219 additions and 86 deletions
+2 -2
View File
@@ -19,8 +19,8 @@
"source-map": "^0.6.1"
},
"peerDependencies": {
"typescript": ">=2.7.2 <2.10",
"@angular/compiler": "0.0.0-PLACEHOLDER"
"@angular/compiler": "0.0.0-PLACEHOLDER",
"typescript": ">=3.0.1 <3.1"
},
"engines" : {
"node" : ">=8.0"
@@ -12,7 +12,8 @@ import {Evaluator, errorSymbol, recordMapEntry} from './evaluator';
import {ClassMetadata, ConstructorMetadata, FunctionMetadata, InterfaceMetadata, METADATA_VERSION, MemberMetadata, MetadataEntry, MetadataError, MetadataMap, MetadataSymbolicBinaryExpression, MetadataSymbolicCallExpression, MetadataSymbolicExpression, MetadataSymbolicIfExpression, MetadataSymbolicIndexExpression, MetadataSymbolicPrefixExpression, MetadataSymbolicReferenceExpression, MetadataSymbolicSelectExpression, MetadataSymbolicSpreadExpression, MetadataValue, MethodMetadata, ModuleExportMetadata, ModuleMetadata, isClassMetadata, isConstructorMetadata, isFunctionMetadata, isMetadataError, isMetadataGlobalReferenceExpression, isMetadataImportDefaultReference, isMetadataImportedSymbolReferenceExpression, isMetadataSymbolicExpression, isMetadataSymbolicReferenceExpression, isMetadataSymbolicSelectExpression, isMethodMetadata} from './schema';
import {Symbols} from './symbols';
const isStatic = (node: ts.Node) => ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Static;
const isStatic = (node: ts.Declaration) =>
ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Static;
/**
* A set of collector options to use when collecting metadata.
@@ -277,8 +278,8 @@ export class MetadataCollector {
}
});
const isExport = (node: ts.Node) =>
sourceFile.isDeclarationFile || ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export;
const isExport = (node: ts.Node) => sourceFile.isDeclarationFile ||
ts.getCombinedModifierFlags(node as ts.Declaration) & ts.ModifierFlags.Export;
const isExportedIdentifier = (identifier?: ts.Identifier) =>
identifier && exportMap.has(identifier.text);
const isExported =
@@ -224,7 +224,8 @@ function isEligibleForLowering(node: ts.Node | undefined): boolean {
return false;
case ts.SyntaxKind.VariableDeclaration:
// Avoid lowering expressions already in an exported variable declaration
return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) == 0;
return (ts.getCombinedModifierFlags(node as ts.VariableDeclaration) &
ts.ModifierFlags.Export) == 0;
}
return isEligibleForLowering(node.parent);
}
@@ -370,7 +371,7 @@ function createExportTableFor(sourceFile: ts.SourceFile): Set<string> {
case ts.SyntaxKind.ClassDeclaration:
case ts.SyntaxKind.FunctionDeclaration:
case ts.SyntaxKind.InterfaceDeclaration:
if ((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) != 0) {
if ((ts.getCombinedModifierFlags(node as ts.Declaration) & ts.ModifierFlags.Export) != 0) {
const classDeclaration =
node as(ts.ClassDeclaration | ts.FunctionDeclaration | ts.InterfaceDeclaration);
const name = classDeclaration.name;
@@ -385,7 +386,7 @@ function createExportTableFor(sourceFile: ts.SourceFile): Set<string> {
break;
case ts.SyntaxKind.VariableDeclaration:
const variableDeclaration = node as ts.VariableDeclaration;
if ((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) != 0 &&
if ((ts.getCombinedModifierFlags(variableDeclaration) & ts.ModifierFlags.Export) != 0 &&
variableDeclaration.name.kind == ts.SyntaxKind.Identifier) {
const name = variableDeclaration.name as ts.Identifier;
exportTable.add(name.text);
@@ -102,14 +102,14 @@ const defaultEmitCallback: TsEmitCallback =
* Minimum supported TypeScript version
* ∀ supported typescript version v, v >= MIN_TS_VERSION
*/
const MIN_TS_VERSION = '2.7.2';
const MIN_TS_VERSION = '3.0.1';
/**
* Supremum of supported TypeScript versions
* ∀ supported typescript version v, v < MAX_TS_VERSION
* MAX_TS_VERSION is not considered as a supported TypeScript version
*/
const MAX_TS_VERSION = '2.10.0';
const MAX_TS_VERSION = '3.1.0';
class AngularCompilerProgram implements Program {
private rootNames: string[];
@@ -29,13 +29,13 @@ describe('expression diagnostics', () => {
registry = ts.createDocumentRegistry(false, '/src');
host = new MockLanguageServiceHost(['app/app.component.ts'], FILES, '/src');
service = ts.createLanguageService(host, registry);
const program = service.getProgram();
const program = service.getProgram() !;
const checker = program.getTypeChecker();
const options: CompilerOptions = Object.create(host.getCompilationSettings());
options.genDir = '/dist';
options.basePath = '/src';
const symbolResolverHost = new ReflectorHost(() => program, host, options);
context = new DiagnosticContext(service, program, checker, symbolResolverHost);
const symbolResolverHost = new ReflectorHost(() => program !, host, options);
context = new DiagnosticContext(service, program !, checker, symbolResolverHost);
type = context.getStaticSymbol('app/app.component.ts', 'AppComponent');
});
@@ -39,7 +39,7 @@ describe('symbol query', () => {
const host = new MockLanguageServiceHost(
['/quickstart/app/app.component.ts'], QUICKSTART, '/quickstart');
const service = ts.createLanguageService(host, registry);
program = service.getProgram();
program = service.getProgram() !;
checker = program.getTypeChecker();
sourceFile = program.getSourceFile('/quickstart/app/app.component.ts') !;
const options: CompilerOptions = Object.create(host.getCompilationSettings());
@@ -40,7 +40,7 @@ describe('Collector', () => {
'interface-reference.ts'
]);
service = ts.createLanguageService(host, documentRegistry);
program = service.getProgram();
program = service.getProgram() !;
collector = new MetadataCollector({quotedNames: true});
});
@@ -1128,7 +1128,7 @@ describe('Collector', () => {
function override(fileName: string, content: string) {
host.overrideFile(fileName, content);
host.addFile(fileName);
program = service.getProgram();
program = service.getProgram() !;
}
function collectSource(content: string): ModuleMetadata {
@@ -29,7 +29,7 @@ describe('Evaluator', () => {
'newExpression.ts', 'errors.ts', 'declared.ts'
]);
service = ts.createLanguageService(host, documentRegistry);
program = service.getProgram();
program = service.getProgram() !;
typeChecker = program.getTypeChecker();
symbols = new Symbols(null as any as ts.SourceFile);
evaluator = new Evaluator(symbols, new Map());
@@ -42,7 +42,7 @@ describe('Symbols', () => {
beforeEach(() => {
host = new Host(FILES, ['consts.ts', 'expressions.ts', 'imports.ts']);
service = ts.createLanguageService(host);
program = service.getProgram();
program = service.getProgram() !;
expressions = program.getSourceFile('expressions.ts') !;
imports = program.getSourceFile('imports.ts') !;
});
@@ -7,6 +7,7 @@
*/
import * as fs from 'fs';
import * as path from 'path';
import * as ts from 'typescript';
export interface Directory { [name: string]: (Directory|string); }
@@ -54,8 +55,10 @@ export class Host implements ts.LanguageServiceHost {
if (this.overrides.has(fileName)) {
return this.overrides.get(fileName);
}
if (fileName.endsWith('lib.d.ts')) {
return fs.readFileSync(ts.getDefaultLibFilePath(this.getCompilationSettings()), 'utf8');
if (/lib(.*)\.d\.ts/.test(fileName)) {
const libDirPath = path.dirname(ts.getDefaultLibFilePath(this.getCompilationSettings()));
const libPath = path.join(libDirPath, fileName);
return fs.readFileSync(libPath, 'utf8');
}
const current = open(this.directory, fileName);
if (typeof current === 'string') return current;
@@ -76,6 +79,9 @@ export function open(directory: Directory, fileName: string): Directory|string|u
}
export class MockNode implements ts.Node {
decorators?: ts.NodeArray<ts.Decorator>;
modifiers?: ts.NodeArray<ts.Modifier>;
parent !: ts.Node;
constructor(
public kind: ts.SyntaxKind = ts.SyntaxKind.Identifier, public flags: ts.NodeFlags = 0,
public pos: number = 0, public end: number = 0) {}
@@ -101,6 +107,11 @@ export class MockNode implements ts.Node {
}
export class MockIdentifier extends MockNode implements ts.Identifier {
originalKeywordKind?: ts.SyntaxKind;
isInJSDocNamespace?: boolean;
decorators?: ts.NodeArray<ts.Decorator>;
modifiers?: ts.NodeArray<ts.Modifier>;
parent !: ts.Node;
public text: string;
// TODO(issue/24571): remove '!'.
public escapedText !: ts.__String;
@@ -124,6 +135,12 @@ export class MockIdentifier extends MockNode implements ts.Identifier {
}
export class MockVariableDeclaration extends MockNode implements ts.VariableDeclaration {
parent !: ts.VariableDeclarationList | ts.CatchClause;
exclamationToken?: ts.Token<ts.SyntaxKind.ExclamationToken>;
type?: ts.TypeNode;
initializer?: ts.Expression;
decorators?: ts.NodeArray<ts.Decorator>;
modifiers?: ts.NodeArray<ts.Modifier>;
// tslint:disable-next-line
public _declarationBrand: any;
@@ -140,6 +157,11 @@ export class MockVariableDeclaration extends MockNode implements ts.VariableDecl
}
export class MockSymbol implements ts.Symbol {
declarations !: ts.Declaration[];
valueDeclaration !: ts.Declaration;
members?: ts.UnderscoreEscapedMap<ts.Symbol>;
exports?: ts.UnderscoreEscapedMap<ts.Symbol>;
globalExports?: ts.UnderscoreEscapedMap<ts.Symbol>;
// TODO(issue/24571): remove '!'.
public escapedName !: ts.__String;
constructor(
+1 -1
View File
@@ -83,7 +83,7 @@ function createTestSupportFor(basePath: string) {
'lib': [
path.resolve(basePath, 'node_modules/typescript/lib/lib.es6.d.ts'),
],
...overrideOptions,
'paths': {'@angular/*': ['./node_modules/@angular/*']}, ...overrideOptions,
};
}