Skip to content

Commit fd4ecce

Browse files
committed
Merge remote-tracking branch 'upstream/master' into diagnose-accidental-accessor-call
2 parents 6051fc1 + 64d6a1e commit fd4ecce

File tree

506 files changed

+9452
-2639
lines changed

Some content is hidden

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

506 files changed

+9452
-2639
lines changed

.github/ISSUE_TEMPLATE/config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ contact_links:
1414
name: "TypeScript FAQ"
1515
url: "https://github.com/microsoft/TypeScript/wiki/FAQ"
1616
-
17-
about: "Please raise issues about the site on it's own repo."
17+
about: "Please raise issues about the site on its own repo."
1818
name: Website
1919
url: "https://github.com/microsoft/TypeScript-Website/issues/new"

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "typescript",
33
"author": "Microsoft Corp.",
44
"homepage": "https://www.typescriptlang.org/",
5-
"version": "3.9.0",
5+
"version": "4.0.0",
66
"license": "Apache-2.0",
77
"description": "TypeScript is a language for application scale JavaScript development",
88
"keywords": [

src/compiler/binder.ts

+5-15
Original file line numberDiff line numberDiff line change
@@ -320,16 +320,6 @@ namespace ts {
320320
}
321321
}
322322

323-
function setValueDeclaration(symbol: Symbol, node: Declaration): void {
324-
const { valueDeclaration } = symbol;
325-
if (!valueDeclaration ||
326-
(isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) ||
327-
(valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) {
328-
// other kinds of value declarations take precedence over modules and assignment declarations
329-
symbol.valueDeclaration = node;
330-
}
331-
}
332-
333323
// Should not be called on a declaration with a computed property name,
334324
// unless it is a well known Symbol.
335325
function getDeclarationName(node: Declaration): __String | undefined {
@@ -659,7 +649,7 @@ namespace ts {
659649
}
660650
// We create a return control flow graph for IIFEs and constructors. For constructors
661651
// we use the return control flow graph in strict property initialization checks.
662-
currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined;
652+
currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor || (isInJSFile && (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression)) ? createBranchLabel() : undefined;
663653
currentExceptionTarget = undefined;
664654
currentBreakTarget = undefined;
665655
currentContinueTarget = undefined;
@@ -680,8 +670,8 @@ namespace ts {
680670
if (currentReturnTarget) {
681671
addAntecedent(currentReturnTarget, currentFlow);
682672
currentFlow = finishFlowLabel(currentReturnTarget);
683-
if (node.kind === SyntaxKind.Constructor) {
684-
(<ConstructorDeclaration>node).returnFlowNode = currentFlow;
673+
if (node.kind === SyntaxKind.Constructor || (isInJSFile && (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.FunctionExpression))) {
674+
(<FunctionLikeDeclaration>node).returnFlowNode = currentFlow;
685675
}
686676
}
687677
if (!isIIFE) {
@@ -2974,7 +2964,7 @@ namespace ts {
29742964

29752965
function bindSpecialPropertyAssignment(node: BindablePropertyAssignmentExpression) {
29762966
// Class declarations in Typescript do not allow property declarations
2977-
const parentSymbol = lookupSymbolForPropertyAccess(node.left.expression);
2967+
const parentSymbol = lookupSymbolForPropertyAccess(node.left.expression, container) || lookupSymbolForPropertyAccess(node.left.expression, blockScopeContainer) ;
29782968
if (!isInJSFile(node) && !isFunctionSymbol(parentSymbol)) {
29792969
return;
29802970
}
@@ -3083,7 +3073,7 @@ namespace ts {
30833073
}
30843074

30853075
function bindPropertyAssignment(name: BindableStaticNameExpression, propertyAccess: BindableStaticAccessExpression, isPrototypeProperty: boolean, containerIsClass: boolean) {
3086-
let namespaceSymbol = lookupSymbolForPropertyAccess(name);
3076+
let namespaceSymbol = lookupSymbolForPropertyAccess(name, container) || lookupSymbolForPropertyAccess(name, blockScopeContainer);
30873077
const isToplevel = isTopLevelNamespaceAssignment(propertyAccess);
30883078
namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty, containerIsClass);
30893079
bindPotentiallyNewExpandoMemberToNamespace(propertyAccess, namespaceSymbol, isPrototypeProperty);

src/compiler/checker.ts

+470-207
Large diffs are not rendered by default.

src/compiler/commandLineParser.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1721,7 +1721,7 @@ namespace ts {
17211721
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, Diagnostics.String_literal_with_double_quotes_expected));
17221722
}
17231723

1724-
const textOfKey = getTextOfPropertyName(element.name);
1724+
const textOfKey = isComputedNonLiteralName(element.name) ? undefined : getTextOfPropertyName(element.name);
17251725
const keyText = textOfKey && unescapeLeadingUnderscores(textOfKey);
17261726
const option = keyText && knownOptions ? knownOptions.get(keyText) : undefined;
17271727
if (keyText && extraKeyDiagnostics && !option) {

src/compiler/core.ts

+22
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,28 @@ namespace ts {
844844
return to;
845845
}
846846

847+
/**
848+
* Combines two arrays, values, or undefineds into the smallest container that can accommodate the resulting set:
849+
*
850+
* ```
851+
* undefined -> undefined -> undefined
852+
* T -> undefined -> T
853+
* T -> T -> T[]
854+
* T[] -> undefined -> T[] (no-op)
855+
* T[] -> T -> T[] (append)
856+
* T[] -> T[] -> T[] (concatenate)
857+
* ```
858+
*/
859+
export function combine<T>(xs: T | readonly T[] | undefined, ys: T | readonly T[] | undefined): T | readonly T[] | undefined;
860+
export function combine<T>(xs: T | T[] | undefined, ys: T | T[] | undefined): T | T[] | undefined;
861+
export function combine<T>(xs: T | T[] | undefined, ys: T | T[] | undefined) {
862+
if (xs === undefined) return ys;
863+
if (ys === undefined) return xs;
864+
if (isArray(xs)) return isArray(ys) ? concatenate(xs, ys) : append(xs, ys);
865+
if (isArray(ys)) return append(ys, xs);
866+
return [xs, ys];
867+
}
868+
847869
/**
848870
* Gets the actual offset into an array for a relative offset. Negative offsets indicate a
849871
* position offset from the end of the array.

src/compiler/corePublic.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
namespace ts {
22
// WARNING: The script `configurePrerelease.ts` uses a regexp to parse out these values.
33
// If changing the text in this section, be sure to test `configurePrerelease` too.
4-
export const versionMajorMinor = "3.9";
4+
export const versionMajorMinor = "4.0";
55
/** The version of the TypeScript compiler release */
66
export const version = `${versionMajorMinor}.0-dev`;
77

src/compiler/diagnosticMessages.json

+19-3
Original file line numberDiff line numberDiff line change
@@ -1477,11 +1477,11 @@
14771477
"category": "Error",
14781478
"code": 2371
14791479
},
1480-
"Parameter '{0}' cannot be referenced in its initializer.": {
1480+
"Parameter '{0}' cannot reference itself.": {
14811481
"category": "Error",
14821482
"code": 2372
14831483
},
1484-
"Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it.": {
1484+
"Parameter '{0}' cannot reference identifier '{1}' declared after it.": {
14851485
"category": "Error",
14861486
"code": 2373
14871487
},
@@ -2963,6 +2963,10 @@
29632963
"category": "Error",
29642964
"code": 2789
29652965
},
2966+
"The operand of a 'delete' operator must be optional.": {
2967+
"category": "Error",
2968+
"code": 2790
2969+
},
29662970

29672971
"Import declaration '{0}' is using private name '{1}'.": {
29682972
"category": "Error",
@@ -4384,9 +4388,17 @@
43844388
"category": "Error",
43854389
"code": 6231
43864390
},
4391+
"Declaration augments declaration in another file. This cannot be serialized.": {
4392+
"category": "Error",
4393+
"code": 6232
4394+
},
4395+
"This is the declaration being augmented. Consider moving the augmenting declaration into the same file.": {
4396+
"category": "Error",
4397+
"code": 6233
4398+
},
43874399
"This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?": {
43884400
"category": "Message",
4389-
"code": 6232
4401+
"code": 6234
43904402
},
43914403

43924404
"Projects to reference": {
@@ -5741,5 +5753,9 @@
57415753
"The intersection '{0}' was reduced to 'never' because property '{1}' exists in multiple constituents and is private in some.": {
57425754
"category": "Error",
57435755
"code": 18032
5756+
},
5757+
"Only numeric enums can have computed members, but this expression has type '{0}'. If you do not need exhaustiveness checks, consider using an object literal instead.": {
5758+
"category": "Error",
5759+
"code": 18033
57445760
}
57455761
}

src/compiler/emitter.ts

+25-10
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ namespace ts {
664664
getSymbolOfExternalModuleSpecifier: notImplemented,
665665
isBindingCapturedByNode: notImplemented,
666666
getDeclarationStatementsForSourceFile: notImplemented,
667+
isImportRequiredByAugmentation: notImplemented,
667668
};
668669

669670
/*@internal*/
@@ -2365,16 +2366,10 @@ namespace ts {
23652366

23662367
function emitParenthesizedExpression(node: ParenthesizedExpression) {
23672368
const openParenPos = emitTokenWithComment(SyntaxKind.OpenParenToken, node.pos, writePunctuation, node);
2368-
const leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(node, [node.expression], ListFormat.None);
2369-
if (leadingNewlines) {
2370-
writeLinesAndIndent(leadingNewlines, /*writeLinesIfNotIndenting*/ false);
2371-
}
2369+
const indented = writeLineSeparatorsAndIndentBefore(node.expression, node);
23722370
emitExpression(node.expression);
2373-
const trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(node, [node.expression], ListFormat.None);
2374-
if (trailingNewlines) {
2375-
writeLine(trailingNewlines);
2376-
}
2377-
decreaseIndentIf(leadingNewlines);
2371+
writeLineSeparatorsAfter(node.expression, node);
2372+
decreaseIndentIf(indented);
23782373
emitTokenWithComment(SyntaxKind.CloseParenToken, node.expression ? node.expression.end : openParenPos, writePunctuation, node);
23792374
}
23802375

@@ -3292,12 +3287,15 @@ namespace ts {
32923287
writePunctuation("<");
32933288

32943289
if (isJsxOpeningElement(node)) {
3290+
const indented = writeLineSeparatorsAndIndentBefore(node.tagName, node);
32953291
emitJsxTagName(node.tagName);
32963292
emitTypeArguments(node, node.typeArguments);
32973293
if (node.attributes.properties && node.attributes.properties.length > 0) {
32983294
writeSpace();
32993295
}
33003296
emit(node.attributes);
3297+
writeLineSeparatorsAfter(node.attributes, node);
3298+
decreaseIndentIf(indented);
33013299
}
33023300

33033301
writePunctuation(">");
@@ -4132,7 +4130,7 @@ namespace ts {
41324130
if (closingLineTerminatorCount) {
41334131
writeLine(closingLineTerminatorCount);
41344132
}
4135-
else if (format & ListFormat.SpaceBetweenBraces) {
4133+
else if (format & (ListFormat.SpaceAfterList | ListFormat.SpaceBetweenBraces)) {
41364134
writeSpace();
41374135
}
41384136
}
@@ -4301,6 +4299,7 @@ namespace ts {
43014299
return getEffectiveLines(
43024300
includeComments => getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(
43034301
firstChild.pos,
4302+
parentNode.pos,
43044303
currentSourceFile!,
43054304
includeComments));
43064305
}
@@ -4358,6 +4357,7 @@ namespace ts {
43584357
return getEffectiveLines(
43594358
includeComments => getLinesBetweenPositionAndNextNonWhitespaceCharacter(
43604359
lastChild.end,
4360+
parentNode.end,
43614361
currentSourceFile!,
43624362
includeComments));
43634363
}
@@ -4397,6 +4397,21 @@ namespace ts {
43974397
return lines;
43984398
}
43994399

4400+
function writeLineSeparatorsAndIndentBefore(node: Node, parent: Node): boolean {
4401+
const leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(parent, [node], ListFormat.None);
4402+
if (leadingNewlines) {
4403+
writeLinesAndIndent(leadingNewlines, /*writeLinesIfNotIndenting*/ false);
4404+
}
4405+
return !!leadingNewlines;
4406+
}
4407+
4408+
function writeLineSeparatorsAfter(node: Node, parent: Node) {
4409+
const trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(parent, [node], ListFormat.None);
4410+
if (trailingNewlines) {
4411+
writeLine(trailingNewlines);
4412+
}
4413+
}
4414+
44004415
function synthesizedNodeStartsOnNewLine(node: Node, format: ListFormat) {
44014416
if (nodeIsSynthesized(node)) {
44024417
const startsOnNewLine = getStartsOnNewLine(node);

src/compiler/factory.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ namespace ts {
44
enableEmitNotification: noop,
55
enableSubstitution: noop,
66
endLexicalEnvironment: returnUndefined,
7-
getCompilerOptions: notImplemented,
7+
getCompilerOptions: () => ({}),
88
getEmitHost: notImplemented,
99
getEmitResolver: notImplemented,
10+
setLexicalEnvironmentFlags: noop,
11+
getLexicalEnvironmentFlags: () => 0,
1012
hoistFunctionDeclaration: noop,
1113
hoistVariableDeclaration: noop,
14+
addInitializationStatement: noop,
1215
isEmitNotificationEnabled: notImplemented,
1316
isSubstitutionEnabled: notImplemented,
1417
onEmitNode: noop,
@@ -852,13 +855,13 @@ namespace ts {
852855
* This function needs to be called whenever we transform the statement
853856
* list of a source file, namespace, or function-like body.
854857
*/
855-
export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number, visitor?: (node: Node) => VisitResult<Node>): number;
856-
export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>): number | undefined;
857-
export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>): number | undefined {
858+
export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Node) => boolean): number;
859+
export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>, filter?: (node: Node) => boolean): number | undefined;
860+
export function addCustomPrologue(target: Statement[], source: readonly Statement[], statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>, filter: (node: Node) => boolean = returnTrue): number | undefined {
858861
const numStatements = source.length;
859862
while (statementOffset !== undefined && statementOffset < numStatements) {
860863
const statement = source[statementOffset];
861-
if (getEmitFlags(statement) & EmitFlags.CustomPrologue) {
864+
if (getEmitFlags(statement) & EmitFlags.CustomPrologue && filter(statement)) {
862865
append(target, visitor ? visitNode(statement, visitor, isStatement) : statement);
863866
}
864867
else {

0 commit comments

Comments
 (0)