Skip to content

Commit c725ee4

Browse files
committed
Merge branch 'master' into transforms
2 parents ed0a653 + 4a470bd commit c725ee4

38 files changed

+439
-108
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12937,6 +12937,14 @@ namespace ts {
1293712937
return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target);
1293812938
}
1293912939

12940+
function getBestChoiceType(type1: Type, type2: Type): Type {
12941+
const firstAssignableToSecond = isTypeAssignableTo(type1, type2);
12942+
const secondAssignableToFirst = isTypeAssignableTo(type2, type1);
12943+
return secondAssignableToFirst && !firstAssignableToSecond ? type1 :
12944+
firstAssignableToSecond && !secondAssignableToFirst ? type2 :
12945+
getUnionType([type1, type2], /*subtypeReduction*/ true);
12946+
}
12947+
1294012948
function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
1294112949
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node);
1294212950
}
@@ -13080,7 +13088,7 @@ namespace ts {
1308013088
leftType;
1308113089
case SyntaxKind.BarBarToken:
1308213090
return getTypeFacts(leftType) & TypeFacts.Falsy ?
13083-
getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], /*subtypeReduction*/ true) :
13091+
getBestChoiceType(removeDefinitelyFalsyTypes(leftType), rightType) :
1308413092
leftType;
1308513093
case SyntaxKind.EqualsToken:
1308613094
checkAssignmentOperator(rightType);
@@ -13207,7 +13215,7 @@ namespace ts {
1320713215
checkExpression(node.condition);
1320813216
const type1 = checkExpression(node.whenTrue, contextualMapper);
1320913217
const type2 = checkExpression(node.whenFalse, contextualMapper);
13210-
return getUnionType([type1, type2], /*subtypeReduction*/ true);
13218+
return getBestChoiceType(type1, type2);
1321113219
}
1321213220

1321313221
function typeContainsLiteralFromEnum(type: Type, enumType: EnumType) {

src/lib/es5.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,11 @@ interface Array<T> {
11081108
* Removes the last element from an array and returns it.
11091109
*/
11101110
pop(): T | undefined;
1111+
/**
1112+
* Combines two or more arrays.
1113+
* @param items Additional items to add to the end of array1.
1114+
*/
1115+
concat(...items: T[][]): T[];
11111116
/**
11121117
* Combines two or more arrays.
11131118
* @param items Additional items to add to the end of array1.

src/services/formatting/formatting.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,9 @@ namespace ts.formatting {
453453
case SyntaxKind.MethodDeclaration:
454454
if ((<MethodDeclaration>node).asteriskToken) {
455455
return SyntaxKind.AsteriskToken;
456-
}
457-
// fall-through
458-
456+
}/*
457+
fall-through
458+
*/
459459
case SyntaxKind.PropertyDeclaration:
460460
case SyntaxKind.Parameter:
461461
return (<Declaration>node).name.kind;
@@ -732,7 +732,7 @@ namespace ts.formatting {
732732
else {
733733
// indent token only if end line of previous range does not match start line of the token
734734
const prevEndLine = savePreviousRange && sourceFile.getLineAndCharacterOfPosition(savePreviousRange.end).line;
735-
indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine;
735+
indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine;
736736
}
737737
}
738738
}
@@ -892,7 +892,7 @@ namespace ts.formatting {
892892
}
893893

894894
function indentationIsDifferent(indentationString: string, startLinePosition: number): boolean {
895-
return indentationString !== sourceFile.text.substr(startLinePosition , indentationString.length);
895+
return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length);
896896
}
897897

898898
function indentMultilineComment(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean) {
@@ -936,7 +936,7 @@ namespace ts.formatting {
936936

937937
// shift all parts on the delta size
938938
const delta = indentation - nonWhitespaceColumnInFirstPart.column;
939-
for (let i = startIndex, len = parts.length; i < len; i++, startLine++) {
939+
for (let i = startIndex, len = parts.length; i < len; i++ , startLine++) {
940940
const startLinePos = getStartPositionOfLine(startLine, sourceFile);
941941
const nonWhitespaceCharacterAndColumn =
942942
i === 0

src/services/formatting/rules.ts

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,13 @@ namespace ts.formatting {
231231
public NoSpaceBeforeCloseBraceInJsxExpression: Rule;
232232
public SpaceBeforeCloseBraceInJsxExpression: Rule;
233233

234+
// JSX opening elements
235+
public SpaceBeforeJsxAttribute: Rule;
236+
public SpaceBeforeSlashInJsxOpeningElement: Rule;
237+
public NoSpaceBeforeGreaterThanTokenInJsxOpeningElement: Rule;
238+
public NoSpaceBeforeEqualInJsxAttribute: Rule;
239+
public NoSpaceAfterEqualInJsxAttribute: Rule;
240+
234241
constructor() {
235242
///
236243
/// Common Rules
@@ -322,7 +329,7 @@ namespace ts.formatting {
322329

323330
// Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
324331
// So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
325-
this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space));
332+
this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space));
326333

327334
// This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
328335
this.SpaceAfterTryFinally = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword]), SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
@@ -386,6 +393,13 @@ namespace ts.formatting {
386393
// template string
387394
this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
388395

396+
// jsx opening element
397+
this.SpaceBeforeJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsNextTokenParentJsxAttribute, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
398+
this.SpaceBeforeSlashInJsxOpeningElement = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.SlashToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
399+
this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement = new Rule(RuleDescriptor.create1(SyntaxKind.SlashToken, SyntaxKind.GreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
400+
this.NoSpaceBeforeEqualInJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.EqualsToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
401+
this.NoSpaceAfterEqualInJsxAttribute = new Rule(RuleDescriptor.create3(SyntaxKind.EqualsToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
402+
389403
// These rules are higher in priority than user-configurable rules.
390404
this.HighPriorityCommonRules = [
391405
this.IgnoreBeforeComment, this.IgnoreAfterLineComment,
@@ -413,6 +427,8 @@ namespace ts.formatting {
413427
this.SpaceAfterVoidOperator,
414428
this.SpaceBetweenAsyncAndOpenParen, this.SpaceBetweenAsyncAndFunctionKeyword,
415429
this.NoSpaceBetweenTagAndTemplateString,
430+
this.SpaceBeforeJsxAttribute, this.SpaceBeforeSlashInJsxOpeningElement, this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement,
431+
this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute,
416432

417433
// TypeScript-specific rules
418434
this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport,
@@ -450,8 +466,8 @@ namespace ts.formatting {
450466
///
451467

452468
// Insert space after comma delimiter
453-
this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space));
454-
this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext), RuleAction.Delete));
469+
this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space));
470+
this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext), RuleAction.Delete));
455471

456472
// Insert space before and after binary operators
457473
this.SpaceBeforeBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
@@ -498,10 +514,10 @@ namespace ts.formatting {
498514
this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
499515

500516
// No space after { and before } in JSX expression
501-
this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
502-
this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space));
503-
this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
504-
this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space));
517+
this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete));
518+
this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space));
519+
this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete));
520+
this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space));
505521

506522
// Insert space after function keyword for anonymous functions
507523
this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
@@ -741,14 +757,26 @@ namespace ts.formatting {
741757
return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText;
742758
}
743759

744-
static isNonJsxElementContext(context: FormattingContext): boolean {
760+
static IsNonJsxElementContext(context: FormattingContext): boolean {
745761
return context.contextNode.kind !== SyntaxKind.JsxElement;
746762
}
747763

748-
static isJsxExpressionContext(context: FormattingContext): boolean {
764+
static IsJsxExpressionContext(context: FormattingContext): boolean {
749765
return context.contextNode.kind === SyntaxKind.JsxExpression;
750766
}
751767

768+
static IsNextTokenParentJsxAttribute(context: FormattingContext): boolean {
769+
return context.nextTokenParent.kind === SyntaxKind.JsxAttribute;
770+
}
771+
772+
static IsJsxAttributeContext(context: FormattingContext): boolean {
773+
return context.contextNode.kind === SyntaxKind.JsxAttribute;
774+
}
775+
776+
static IsJsxSelfClosingElementContext(context: FormattingContext): boolean {
777+
return context.contextNode.kind === SyntaxKind.JsxSelfClosingElement;
778+
}
779+
752780
static IsNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean {
753781
return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context);
754782
}

src/services/services.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3095,14 +3095,16 @@ namespace ts {
30953095

30963096
const oldSettings = program && program.getCompilerOptions();
30973097
const newSettings = hostCache.compilationSettings();
3098-
const changesInCompilationSettingsAffectSyntax = oldSettings &&
3098+
const shouldCreateNewSourceFiles = oldSettings &&
30993099
(oldSettings.target !== newSettings.target ||
31003100
oldSettings.module !== newSettings.module ||
31013101
oldSettings.moduleResolution !== newSettings.moduleResolution ||
31023102
oldSettings.noResolve !== newSettings.noResolve ||
31033103
oldSettings.jsx !== newSettings.jsx ||
31043104
oldSettings.allowJs !== newSettings.allowJs ||
3105-
oldSettings.disableSizeLimit !== oldSettings.disableSizeLimit);
3105+
oldSettings.disableSizeLimit !== oldSettings.disableSizeLimit ||
3106+
oldSettings.baseUrl !== newSettings.baseUrl ||
3107+
!mapIsEqualTo(oldSettings.paths, newSettings.paths));
31063108

31073109
// Now create a new compiler
31083110
const compilerHost: CompilerHost = {
@@ -3154,7 +3156,7 @@ namespace ts {
31543156
const oldSourceFiles = program.getSourceFiles();
31553157
const oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldSettings);
31563158
for (const oldSourceFile of oldSourceFiles) {
3157-
if (!newProgram.getSourceFile(oldSourceFile.fileName) || changesInCompilationSettingsAffectSyntax) {
3159+
if (!newProgram.getSourceFile(oldSourceFile.fileName) || shouldCreateNewSourceFiles) {
31583160
documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey);
31593161
}
31603162
}
@@ -3188,7 +3190,7 @@ namespace ts {
31883190
// Check if the language version has changed since we last created a program; if they are the same,
31893191
// it is safe to reuse the sourceFiles; if not, then the shape of the AST can change, and the oldSourceFile
31903192
// can not be reused. we have to dump all syntax trees and create new ones.
3191-
if (!changesInCompilationSettingsAffectSyntax) {
3193+
if (!shouldCreateNewSourceFiles) {
31923194
// Check if the old program had this file already
31933195
const oldSourceFile = program && program.getSourceFileByPath(path);
31943196
if (oldSourceFile) {

tests/baselines/reference/arrayConcat2.symbols

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@ var a: string[] = [];
33
>a : Symbol(a, Decl(arrayConcat2.ts, 0, 3))
44

55
a.concat("hello", 'world');
6-
>a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --))
6+
>a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
77
>a : Symbol(a, Decl(arrayConcat2.ts, 0, 3))
8-
>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --))
8+
>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
99

1010
a.concat('Hello');
11-
>a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --))
11+
>a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
1212
>a : Symbol(a, Decl(arrayConcat2.ts, 0, 3))
13-
>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --))
13+
>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
1414

1515
var b = new Array<string>();
1616
>b : Symbol(b, Decl(arrayConcat2.ts, 5, 3))
1717
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
1818

1919
b.concat('hello');
20-
>b.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --))
20+
>b.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
2121
>b : Symbol(b, Decl(arrayConcat2.ts, 5, 3))
22-
>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --))
22+
>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
2323

tests/baselines/reference/arrayConcat2.types

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ var a: string[] = [];
55

66
a.concat("hello", 'world');
77
>a.concat("hello", 'world') : string[]
8-
>a.concat : (...items: (string | string[])[]) => string[]
8+
>a.concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; }
99
>a : string[]
10-
>concat : (...items: (string | string[])[]) => string[]
10+
>concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; }
1111
>"hello" : string
1212
>'world' : string
1313

1414
a.concat('Hello');
1515
>a.concat('Hello') : string[]
16-
>a.concat : (...items: (string | string[])[]) => string[]
16+
>a.concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; }
1717
>a : string[]
18-
>concat : (...items: (string | string[])[]) => string[]
18+
>concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; }
1919
>'Hello' : string
2020

2121
var b = new Array<string>();
@@ -25,8 +25,8 @@ var b = new Array<string>();
2525

2626
b.concat('hello');
2727
>b.concat('hello') : string[]
28-
>b.concat : (...items: (string | string[])[]) => string[]
28+
>b.concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; }
2929
>b : string[]
30-
>concat : (...items: (string | string[])[]) => string[]
30+
>concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; }
3131
>'hello' : string
3232

0 commit comments

Comments
 (0)