Skip to content

Commit 6a81d4c

Browse files
committed
Merge branch 'master' into fixInfiniteConstraints
2 parents a15fecd + 103f894 commit 6a81d4c

File tree

104 files changed

+546
-6963
lines changed

Some content is hidden

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

104 files changed

+546
-6963
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,5 @@ tests/cases/user/*/**/*.d.ts
7575
!tests/cases/user/discord.js/
7676
tests/baselines/reference/dt
7777
.failed-tests
78-
TEST-results.xml
78+
TEST-results.xml
79+
package-lock.json

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

package-lock.json

Lines changed: 0 additions & 6280 deletions
This file was deleted.

src/compiler/checker.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3553,15 +3553,10 @@ namespace ts {
35533553
anyType : getTypeOfSymbol(propertySymbol);
35543554
const saveEnclosingDeclaration = context.enclosingDeclaration;
35553555
context.enclosingDeclaration = undefined;
3556-
if (getCheckFlags(propertySymbol) & CheckFlags.Late) {
3556+
if (context.tracker.trackSymbol && getCheckFlags(propertySymbol) & CheckFlags.Late) {
35573557
const decl = first(propertySymbol.declarations);
3558-
if (context.tracker.trackSymbol && hasLateBindableName(decl)) {
3559-
// get symbol of the first identifier of the entityName
3560-
const firstIdentifier = getFirstIdentifier(decl.name.expression);
3561-
const name = resolveName(firstIdentifier, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
3562-
if (name) {
3563-
context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value);
3564-
}
3558+
if (hasLateBindableName(decl)) {
3559+
trackComputedName(decl.name, saveEnclosingDeclaration, context);
35653560
}
35663561
}
35673562
const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true);
@@ -3771,6 +3766,9 @@ namespace ts {
37713766
function cloneBindingName(node: BindingName): BindingName {
37723767
return <BindingName>elideInitializerAndSetEmitFlags(node);
37733768
function elideInitializerAndSetEmitFlags(node: Node): Node {
3769+
if (context.tracker.trackSymbol && isComputedPropertyName(node) && isLateBindableName(node)) {
3770+
trackComputedName(node, context.enclosingDeclaration, context);
3771+
}
37743772
const visited = visitEachChild(node, elideInitializerAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!;
37753773
const clone = nodeIsSynthesized(visited) ? visited : getSynthesizedClone(visited);
37763774
if (clone.kind === SyntaxKind.BindingElement) {
@@ -3781,6 +3779,16 @@ namespace ts {
37813779
}
37823780
}
37833781

3782+
function trackComputedName(node: LateBoundName, enclosingDeclaration: Node | undefined, context: NodeBuilderContext) {
3783+
if (!context.tracker.trackSymbol) return;
3784+
// get symbol of the first identifier of the entityName
3785+
const firstIdentifier = getFirstIdentifier(node.expression);
3786+
const name = resolveName(firstIdentifier, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
3787+
if (name) {
3788+
context.tracker.trackSymbol(name, enclosingDeclaration, SymbolFlags.Value);
3789+
}
3790+
}
3791+
37843792
function lookupSymbolChain(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, yieldModuleSymbol?: boolean) {
37853793
context.tracker.trackSymbol!(symbol, context.enclosingDeclaration, meaning); // TODO: GH#18217
37863794
// Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
@@ -13909,6 +13917,18 @@ namespace ts {
1390913917
return flow.id;
1391013918
}
1391113919

13920+
function typeMaybeAssignableTo(source: Type, target: Type) {
13921+
if (!(source.flags & TypeFlags.Union)) {
13922+
return isTypeAssignableTo(source, target);
13923+
}
13924+
for (const t of (<UnionType>source).types) {
13925+
if (isTypeAssignableTo(t, target)) {
13926+
return true;
13927+
}
13928+
}
13929+
return false;
13930+
}
13931+
1391213932
// Remove those constituent types of declaredType to which no constituent type of assignedType is assignable.
1391313933
// For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
1391413934
// we remove type string.
@@ -13917,8 +13937,12 @@ namespace ts {
1391713937
if (assignedType.flags & TypeFlags.Never) {
1391813938
return assignedType;
1391913939
}
13920-
const reducedType = filterType(declaredType, t => isTypeComparableTo(assignedType, t));
13921-
if (!(reducedType.flags & TypeFlags.Never)) {
13940+
const reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t));
13941+
// Our crude heuristic produces an invalid result in some cases: see GH#26130.
13942+
// For now, when that happens, we give up and don't narrow at all. (This also
13943+
// means we'll never narrow for erroneous assignments where the assigned type
13944+
// is not assignable to the declared type.)
13945+
if (isTypeAssignableTo(assignedType, reducedType)) {
1392213946
return reducedType;
1392313947
}
1392413948
}

src/compiler/tsbuild.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Currently we do not want to expose API for build, we should work out the API, and then expose it just like we did for builder/watch
2+
/*@internal*/
13
namespace ts {
24
const minimumDate = new Date(-8640000000000000);
35
const maximumDate = new Date(8640000000000000);

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4714,6 +4714,7 @@ namespace ts {
47144714
verticalTab = 0x0B, // \v
47154715
}
47164716

4717+
/*@internal*/
47174718
export interface UpToDateHost {
47184719
fileExists(fileName: string): boolean;
47194720
getModifiedTime(fileName: string): Date | undefined;

src/harness/harness.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ namespace Harness {
14881488
!errors || (errors.length === 0) ? null : getErrorBaseline(inputFiles, errors, pretty));
14891489
}
14901490

1491-
export function doTypeAndSymbolBaseline(baselinePath: string, program: ts.Program, allFiles: {unitName: string, content: string}[], opts?: Baseline.BaselineOptions, multifile?: boolean, skipTypeBaselines?: boolean, skipSymbolBaselines?: boolean) {
1491+
export function doTypeAndSymbolBaseline(baselinePath: string, program: ts.Program, allFiles: {unitName: string, content: string}[], opts?: Baseline.BaselineOptions, multifile?: boolean, skipTypeBaselines?: boolean, skipSymbolBaselines?: boolean, hasErrorBaseline?: boolean) {
14921492
// The full walker simulates the types that you would get from doing a full
14931493
// compile. The pull walker simulates the types you get when you just do
14941494
// a type query for a random node (like how the LS would do it). Most of the
@@ -1504,7 +1504,7 @@ namespace Harness {
15041504
// These types are equivalent, but depend on what order the compiler observed
15051505
// certain parts of the program.
15061506

1507-
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);
1507+
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true, !!hasErrorBaseline);
15081508

15091509
// Produce baselines. The first gives the types for all expressions.
15101510
// The second gives symbols for all identifiers.

src/harness/typeWriter.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class TypeWriterWalker {
2525

2626
private checker: ts.TypeChecker;
2727

28-
constructor(private program: ts.Program, fullTypeCheck: boolean) {
28+
constructor(private program: ts.Program, fullTypeCheck: boolean, private hadErrorBaseline: boolean) {
2929
// Consider getting both the diagnostics checker and the non-diagnostics checker to verify
3030
// they are consistent.
3131
this.checker = fullTypeCheck
@@ -69,6 +69,26 @@ class TypeWriterWalker {
6969
}
7070
}
7171

72+
private isImportStatementName(node: ts.Node) {
73+
if (ts.isImportSpecifier(node.parent) && (node.parent.name === node || node.parent.propertyName === node)) return true;
74+
if (ts.isImportClause(node.parent) && node.parent.name === node) return true;
75+
if (ts.isImportEqualsDeclaration(node.parent) && node.parent.name === node) return true;
76+
return false;
77+
}
78+
79+
private isExportStatementName(node: ts.Node) {
80+
if (ts.isExportAssignment(node.parent) && node.parent.expression === node) return true;
81+
if (ts.isExportSpecifier(node.parent) && (node.parent.name === node || node.parent.propertyName === node)) return true;
82+
return false;
83+
}
84+
85+
private isIntrinsicJsxTag(node: ts.Node) {
86+
const p = node.parent;
87+
if (!(ts.isJsxOpeningElement(p) || ts.isJsxClosingElement(p) || ts.isJsxSelfClosingElement(p))) return false;
88+
if (p.tagName !== node) return false;
89+
return ts.isIntrinsicJsxName(node.getText());
90+
}
91+
7292
private writeTypeOrSymbol(node: ts.Node, isSymbolWalk: boolean): TypeWriterResult | undefined {
7393
const actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
7494
const lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
@@ -85,7 +105,31 @@ class TypeWriterWalker {
85105
// let type = this.checker.getTypeAtLocation(node);
86106
let type = ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) ? this.checker.getTypeAtLocation(node.parent) : undefined;
87107
if (!type || type.flags & ts.TypeFlags.Any) type = this.checker.getTypeAtLocation(node);
88-
const typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType);
108+
const typeString =
109+
// Distinguish `errorType`s from `any`s; but only if the file has no errors.
110+
// Additionally,
111+
// * the LHS of a qualified name
112+
// * a binding pattern name
113+
// * labels
114+
// * the "global" in "declare global"
115+
// * the "target" in "new.target"
116+
// * names in import statements
117+
// * type-only names in export statements
118+
// * and intrinsic jsx tag names
119+
// return `error`s via `getTypeAtLocation`
120+
// But this is generally expected, so we don't call those out, either
121+
(!this.hadErrorBaseline &&
122+
type.flags & ts.TypeFlags.Any &&
123+
!ts.isBindingElement(node.parent) &&
124+
!ts.isPropertyAccessOrQualifiedName(node.parent) &&
125+
!ts.isLabelName(node) &&
126+
!(ts.isModuleDeclaration(node.parent) && ts.isGlobalScopeAugmentation(node.parent)) &&
127+
!ts.isMetaProperty(node.parent) &&
128+
!this.isImportStatementName(node) &&
129+
!this.isExportStatementName(node) &&
130+
!this.isIntrinsicJsxTag(node)) ?
131+
(type as ts.IntrinsicType).intrinsicName :
132+
this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType);
89133
return {
90134
line: lineAndCharacter.line,
91135
syntaxKind: node.kind,

src/testRunner/compilerRunner.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,13 @@ class CompilerTest {
253253
Harness.Compiler.doTypeAndSymbolBaseline(
254254
this.justName,
255255
this.result.program!,
256-
this.toBeCompiled.concat(this.otherFiles).filter(file => !!this.result.program!.getSourceFile(file.unitName)));
256+
this.toBeCompiled.concat(this.otherFiles).filter(file => !!this.result.program!.getSourceFile(file.unitName)),
257+
/*opts*/ undefined,
258+
/*multifile*/ undefined,
259+
/*skipTypeBaselines*/ undefined,
260+
/*skipSymbolBaselines*/ undefined,
261+
!!ts.length(this.result.diagnostics)
262+
);
257263
}
258264

259265
private makeUnitName(name: string, root: string) {

src/testRunner/unittests/convertToAsyncFunction.ts

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -319,38 +319,6 @@ interface String { charAt: any; }
319319
interface Array<T> {}`
320320
};
321321

322-
const newLineCharacter = "\n";
323-
const formatOptions: FormatCodeSettings = {
324-
indentSize: 4,
325-
tabSize: 4,
326-
newLineCharacter,
327-
convertTabsToSpaces: true,
328-
indentStyle: IndentStyle.Smart,
329-
insertSpaceAfterConstructor: false,
330-
insertSpaceAfterCommaDelimiter: true,
331-
insertSpaceAfterSemicolonInForStatements: true,
332-
insertSpaceBeforeAndAfterBinaryOperators: true,
333-
insertSpaceAfterKeywordsInControlFlowStatements: true,
334-
insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
335-
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
336-
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
337-
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
338-
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
339-
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
340-
insertSpaceBeforeFunctionParenthesis: false,
341-
placeOpenBraceOnNewLineForFunctions: false,
342-
placeOpenBraceOnNewLineForControlBlocks: false,
343-
};
344-
345-
const notImplementedHost: LanguageServiceHost = {
346-
getCompilationSettings: notImplemented,
347-
getScriptFileNames: notImplemented,
348-
getScriptVersion: notImplemented,
349-
getScriptSnapshot: notImplemented,
350-
getDefaultLibFileName: notImplemented,
351-
getCurrentDirectory: notImplemented,
352-
};
353-
354322
function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage, includeLib?: boolean) {
355323
const t = getTest(text);
356324
const selectionRange = t.ranges.get("selection")!;
@@ -389,7 +357,7 @@ interface Array<T> {}`
389357
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
390358
preferences: emptyOptions,
391359
host: notImplementedHost,
392-
formatContext: formatting.getFormatContext(formatOptions)
360+
formatContext: formatting.getFormatContext(testFormatOptions)
393361
};
394362

395363
const diagnostics = languageService.getSuggestionDiagnostics(f.path);

src/testRunner/unittests/extractTestHelpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ namespace ts {
8686
placeOpenBraceOnNewLineForControlBlocks: false,
8787
};
8888

89-
const notImplementedHost: LanguageServiceHost = {
89+
export const notImplementedHost: LanguageServiceHost = {
9090
getCompilationSettings: notImplemented,
9191
getScriptFileNames: notImplemented,
9292
getScriptVersion: notImplemented,

tests/baselines/reference/acceptableAlias1.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module M {
66
}
77
export import X = N;
88
>X : any
9-
>N : any
9+
>N : error
1010
}
1111

1212
import r = M.X;

tests/baselines/reference/aliasInaccessibleModule.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ module M {
66
}
77
export import X = N;
88
>X : any
9-
>N : any
9+
>N : error
1010
}

0 commit comments

Comments
 (0)