Skip to content

Commit 197040d

Browse files
committed
Merge branch 'master' into allow-string-enum-in-element-access
2 parents d7d69a1 + e54828f commit 197040d

File tree

131 files changed

+1656
-547
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+1656
-547
lines changed

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"@types/run-sequence": "latest",
5050
"@types/through2": "latest",
5151
"browserify": "latest",
52+
"browser-resolve": "^1.11.2",
5253
"chai": "latest",
5354
"convert-source-map": "latest",
5455
"del": "latest",
@@ -93,8 +94,5 @@
9394
"fs": false,
9495
"os": false,
9596
"path": false
96-
},
97-
"dependencies": {
98-
"browser-resolve": "^1.11.2"
9997
}
10098
}

src/compiler/checker.ts

Lines changed: 90 additions & 51 deletions
Large diffs are not rendered by default.

src/compiler/comments.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace ts {
2121
let declarationListContainerEnd = -1;
2222
let currentSourceFile: SourceFile;
2323
let currentText: string;
24-
let currentLineMap: number[];
24+
let currentLineMap: ReadonlyArray<number>;
2525
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[];
2626
let hasWrittenComment = false;
2727
let disabled: boolean = printerOptions.removeComments;

src/compiler/core.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ namespace ts {
715715
return result;
716716
}
717717

718-
export function sum<T extends Record<K, number>, K extends string>(array: T[], prop: K): number {
718+
export function sum<T extends Record<K, number>, K extends string>(array: ReadonlyArray<T>, prop: K): number {
719719
let result = 0;
720720
for (const v of array) {
721721
// Note: we need the following type assertion because of GH #17069
@@ -2626,4 +2626,8 @@ namespace ts {
26262626
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
26272627
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
26282628
}
2629+
2630+
export function and<T>(f: (arg: T) => boolean, g: (arg: T) => boolean) {
2631+
return (arg: T) => f(arg) && g(arg);
2632+
}
26292633
}

src/compiler/declarationEmitter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ namespace ts {
6060
let enclosingDeclaration: Node;
6161
let resultHasExternalModuleIndicator: boolean;
6262
let currentText: string;
63-
let currentLineMap: number[];
63+
let currentLineMap: ReadonlyArray<number>;
6464
let currentIdentifiers: Map<string>;
6565
let isCurrentFileExternalModule: boolean;
6666
let reportedDeclarationError = false;

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3696,7 +3696,7 @@
36963696
"code": 95003
36973697
},
36983698

3699-
"Extract function into '{0}'": {
3699+
"Extract function into {0}": {
37003700
"category": "Message",
37013701
"code": 95004
37023702
}

src/compiler/factory.ts

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,13 +2339,13 @@ namespace ts {
23392339
: node;
23402340
}
23412341

2342-
export function createBundle(sourceFiles: SourceFile[]) {
2342+
export function createBundle(sourceFiles: ReadonlyArray<SourceFile>) {
23432343
const node = <Bundle>createNode(SyntaxKind.Bundle);
23442344
node.sourceFiles = sourceFiles;
23452345
return node;
23462346
}
23472347

2348-
export function updateBundle(node: Bundle, sourceFiles: SourceFile[]) {
2348+
export function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>) {
23492349
if (node.sourceFiles !== sourceFiles) {
23502350
return createBundle(sourceFiles);
23512351
}
@@ -2372,6 +2372,24 @@ namespace ts {
23722372
);
23732373
}
23742374

2375+
export function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression;
2376+
export function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
2377+
export function createImmediatelyInvokedArrowFunction(statements: Statement[], param?: ParameterDeclaration, paramValue?: Expression) {
2378+
return createCall(
2379+
createArrowFunction(
2380+
/*modifiers*/ undefined,
2381+
/*typeParameters*/ undefined,
2382+
/*parameters*/ param ? [param] : [],
2383+
/*type*/ undefined,
2384+
/*equalsGreaterThanToken*/ undefined,
2385+
createBlock(statements, /*multiLine*/ true)
2386+
),
2387+
/*typeArguments*/ undefined,
2388+
/*argumentsArray*/ paramValue ? [paramValue] : []
2389+
);
2390+
}
2391+
2392+
23752393
export function createComma(left: Expression, right: Expression) {
23762394
return <Expression>createBinary(left, SyntaxKind.CommaToken, right);
23772395
}
@@ -4036,8 +4054,31 @@ namespace ts {
40364054
}
40374055
}
40384056

4057+
/**
4058+
* Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions.
4059+
*
4060+
* A parenthesized expression can be ignored when all of the following are true:
4061+
*
4062+
* - It's `pos` and `end` are not -1
4063+
* - It does not have a custom source map range
4064+
* - It does not have a custom comment range
4065+
* - It does not have synthetic leading or trailing comments
4066+
*
4067+
* If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around
4068+
* the expression to maintain precedence, a new parenthesized expression should be created automatically when
4069+
* the containing expression is created/updated.
4070+
*/
4071+
function isIgnorableParen(node: Expression) {
4072+
return node.kind === SyntaxKind.ParenthesizedExpression
4073+
&& nodeIsSynthesized(node)
4074+
&& nodeIsSynthesized(getSourceMapRange(node))
4075+
&& nodeIsSynthesized(getCommentRange(node))
4076+
&& !some(getSyntheticLeadingComments(node))
4077+
&& !some(getSyntheticTrailingComments(node));
4078+
}
4079+
40394080
export function recreateOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression {
4040-
if (outerExpression && isOuterExpression(outerExpression, kinds)) {
4081+
if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
40414082
return updateOuterExpression(
40424083
outerExpression,
40434084
recreateOuterExpressions(outerExpression.expression, innerExpression)

src/compiler/program.ts

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,15 @@ namespace ts {
205205
}
206206

207207
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
208-
let diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
209-
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
210-
program.getGlobalDiagnostics(cancellationToken),
211-
program.getSemanticDiagnostics(sourceFile, cancellationToken));
208+
const diagnostics = [
209+
...program.getOptionsDiagnostics(cancellationToken),
210+
...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
211+
...program.getGlobalDiagnostics(cancellationToken),
212+
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
213+
];
212214

213215
if (program.getCompilerOptions().declaration) {
214-
diagnostics = diagnostics.concat(program.getDeclarationDiagnostics(sourceFile, cancellationToken));
216+
addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
215217
}
216218

217219
return sortAndDeduplicateDiagnostics(diagnostics);
@@ -223,7 +225,7 @@ namespace ts {
223225
getNewLine(): string;
224226
}
225227

226-
export function formatDiagnostics(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string {
228+
export function formatDiagnostics(diagnostics: ReadonlyArray<Diagnostic>, host: FormatDiagnosticsHost): string {
227229
let output = "";
228230

229231
for (const diagnostic of diagnostics) {
@@ -399,7 +401,7 @@ namespace ts {
399401
* @param oldProgram - Reuses an old program structure.
400402
* @returns A 'Program' object.
401403
*/
402-
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
404+
export function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
403405
let program: Program;
404406
let files: SourceFile[] = [];
405407
let commonSourceDirectory: string;
@@ -888,7 +890,7 @@ namespace ts {
888890
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
889891
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
890892
if (resolveModuleNamesWorker) {
891-
const moduleNames = map(concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral);
893+
const moduleNames = getModuleNames(newSourceFile);
892894
const oldProgramState = { program: oldProgram, file: oldSourceFile, modifiedFilePaths };
893895
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, oldProgramState);
894896
// ensure that module resolution results are still correct
@@ -996,7 +998,7 @@ namespace ts {
996998
}
997999

9981000
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
999-
let declarationDiagnostics: Diagnostic[] = [];
1001+
let declarationDiagnostics: ReadonlyArray<Diagnostic> = [];
10001002

10011003
if (options.noEmit) {
10021004
return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
@@ -1006,10 +1008,12 @@ namespace ts {
10061008
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
10071009
// get any preEmit diagnostics, not just the ones
10081010
if (options.noEmitOnError) {
1009-
const diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
1010-
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
1011-
program.getGlobalDiagnostics(cancellationToken),
1012-
program.getSemanticDiagnostics(sourceFile, cancellationToken));
1011+
const diagnostics = [
1012+
...program.getOptionsDiagnostics(cancellationToken),
1013+
...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
1014+
...program.getGlobalDiagnostics(cancellationToken),
1015+
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
1016+
];
10131017

10141018
if (diagnostics.length === 0 && program.getCompilerOptions().declaration) {
10151019
declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
@@ -1060,8 +1064,8 @@ namespace ts {
10601064

10611065
function getDiagnosticsHelper(
10621066
sourceFile: SourceFile,
1063-
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[],
1064-
cancellationToken: CancellationToken): Diagnostic[] {
1067+
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => ReadonlyArray<Diagnostic>,
1068+
cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
10651069
if (sourceFile) {
10661070
return getDiagnostics(sourceFile, cancellationToken);
10671071
}
@@ -1073,15 +1077,15 @@ namespace ts {
10731077
}));
10741078
}
10751079

1076-
function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
1080+
function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
10771081
return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
10781082
}
10791083

1080-
function getSemanticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
1084+
function getSemanticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
10811085
return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
10821086
}
10831087

1084-
function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
1088+
function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
10851089
const options = program.getCompilerOptions();
10861090
// collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
10871091
if (!sourceFile || options.out || options.outFile) {
@@ -1092,7 +1096,7 @@ namespace ts {
10921096
}
10931097
}
10941098

1095-
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
1099+
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): ReadonlyArray<Diagnostic> {
10961100
// For JavaScript files, we report semantic errors for using TypeScript-only
10971101
// constructs from within a JavaScript file as syntactic errors.
10981102
if (isSourceFileJavaScript(sourceFile)) {
@@ -1430,12 +1434,10 @@ namespace ts {
14301434
return a.fileName === b.fileName;
14311435
}
14321436

1433-
function moduleNameIsEqualTo(a: LiteralExpression, b: LiteralExpression): boolean {
1434-
return a.text === b.text;
1435-
}
1436-
1437-
function getTextOfLiteral(literal: LiteralExpression): string {
1438-
return literal.text;
1437+
function moduleNameIsEqualTo(a: StringLiteral | Identifier, b: StringLiteral | Identifier): boolean {
1438+
return a.kind === SyntaxKind.StringLiteral
1439+
? b.kind === SyntaxKind.StringLiteral && a.text === b.text
1440+
: b.kind === SyntaxKind.Identifier && a.escapedText === b.escapedText;
14391441
}
14401442

14411443
function collectExternalModuleReferences(file: SourceFile): void {
@@ -1448,7 +1450,7 @@ namespace ts {
14481450

14491451
// file.imports may not be undefined if there exists dynamic import
14501452
let imports: StringLiteral[];
1451-
let moduleAugmentations: StringLiteral[];
1453+
let moduleAugmentations: Array<StringLiteral | Identifier>;
14521454
let ambientModules: string[];
14531455

14541456
// If we are importing helpers, we need to add a synthetic reference to resolve the
@@ -1477,7 +1479,7 @@ namespace ts {
14771479

14781480
return;
14791481

1480-
function collectModuleReferences(node: Node, inAmbientModule: boolean): void {
1482+
function collectModuleReferences(node: Statement, inAmbientModule: boolean): void {
14811483
switch (node.kind) {
14821484
case SyntaxKind.ImportDeclaration:
14831485
case SyntaxKind.ImportEqualsDeclaration:
@@ -1499,8 +1501,8 @@ namespace ts {
14991501
break;
15001502
case SyntaxKind.ModuleDeclaration:
15011503
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || hasModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) {
1502-
const moduleName = <StringLiteral>(<ModuleDeclaration>node).name; // TODO: GH#17347
1503-
const nameText = ts.getTextOfIdentifierOrLiteral(moduleName);
1504+
const moduleName = (<ModuleDeclaration>node).name;
1505+
const nameText = getTextOfIdentifierOrLiteral(moduleName);
15041506
// Ambient module declarations can be interpreted as augmentations for some existing external modules.
15051507
// This will happen in two cases:
15061508
// - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
@@ -1817,8 +1819,7 @@ namespace ts {
18171819
collectExternalModuleReferences(file);
18181820
if (file.imports.length || file.moduleAugmentations.length) {
18191821
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
1820-
const nonGlobalAugmentation = filter(file.moduleAugmentations, (moduleAugmentation) => moduleAugmentation.kind === SyntaxKind.StringLiteral);
1821-
const moduleNames = map(concatenate(file.imports, nonGlobalAugmentation), getTextOfLiteral);
1822+
const moduleNames = getModuleNames(file);
18221823
const oldProgramState = { program: oldProgram, file, modifiedFilePaths };
18231824
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState);
18241825
Debug.assert(resolutions.length === moduleNames.length);
@@ -2229,4 +2230,15 @@ namespace ts {
22292230
Debug.assert(names.every(name => name !== undefined), "A name is undefined.", () => JSON.stringify(names));
22302231
return names;
22312232
}
2233+
2234+
function getModuleNames({ imports, moduleAugmentations }: SourceFile): string[] {
2235+
const res = imports.map(i => i.text);
2236+
for (const aug of moduleAugmentations) {
2237+
if (aug.kind === SyntaxKind.StringLiteral) {
2238+
res.push(aug.text);
2239+
}
2240+
// Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
2241+
}
2242+
return res;
2243+
}
22322244
}

src/compiler/scanner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ namespace ts {
343343
}
344344

345345
/* @internal */
346-
export function getLineStarts(sourceFile: SourceFileLike): number[] {
346+
export function getLineStarts(sourceFile: SourceFileLike): ReadonlyArray<number> {
347347
return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text));
348348
}
349349

src/compiler/transformer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ namespace ts {
9292
* @param transforms An array of `TransformerFactory` callbacks.
9393
* @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
9494
*/
95-
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: T[], transformers: TransformerFactory<T>[], allowDtsFiles: boolean): TransformationResult<T> {
95+
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: ReadonlyArray<T>, transformers: ReadonlyArray<TransformerFactory<T>>, allowDtsFiles: boolean): TransformationResult<T> {
9696
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
9797
let lexicalEnvironmentVariableDeclarations: VariableDeclaration[];
9898
let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[];

src/compiler/transformers/destructuring.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ namespace ts {
409409
*/
410410
function createDestructuringPropertyAccess(flattenContext: FlattenContext, value: Expression, propertyName: PropertyName): LeftHandSideExpression {
411411
if (isComputedPropertyName(propertyName)) {
412-
const argumentExpression = ensureIdentifier(flattenContext, propertyName.expression, /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
412+
const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
413413
return createElementAccess(value, argumentExpression);
414414
}
415415
else if (isStringOrNumericLiteral(propertyName)) {

0 commit comments

Comments
 (0)