Skip to content

Commit 2999a1e

Browse files
Merge remote-tracking branch 'origin/master' into numericPropertyAccess
2 parents 9a6d2ee + 5ab24ed commit 2999a1e

File tree

117 files changed

+1887
-404
lines changed

Some content is hidden

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

117 files changed

+1887
-404
lines changed

.github/ISSUE_TEMPLATE/Bug_report.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Please fill in the *entire* template below.
1616
-->
1717

1818
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
19-
**TypeScript Version:** 3.2.0-dev.201xxxxx
19+
**TypeScript Version:** 3.3.0-dev.201xxxxx
2020

2121
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
2222
**Search Terms:**

Gulpfile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ const generatedLCGFile = "built/local/enu/diagnosticMessages.generated.json.lcg"
117117
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
118118
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
119119
*/
120-
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]
120+
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"]
121+
.map(f => f.toLowerCase())
121122
.map(f => `built/local/${f}/diagnosticMessages.generated.json`)
122123
.concat(generatedLCGFile);
123124

Jakefile.js

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ else if (process.env.PATH !== undefined) {
2424

2525
const host = process.env.TYPESCRIPT_HOST || process.env.host || "node";
2626

27-
const locales = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"];
28-
2927
const defaultTestTimeout = 40000;
3028

3129
let useDebugMode = true;
@@ -709,19 +707,6 @@ const Travis = {
709707
}
710708
};
711709

712-
function buildLocalizedTargets() {
713-
/**
714-
* The localization target produces the two following transformations:
715-
* 1. 'src\loc\lcl\<locale>\diagnosticMessages.generated.json.lcl' => 'built\local\<locale>\diagnosticMessages.generated.json'
716-
* convert localized resources into a .json file the compiler can understand
717-
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
718-
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
719-
*/
720-
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"]
721-
.map(f => path.join(Paths.builtLocal,f))
722-
.concat(path.dirname(Paths.generatedLCGFile));
723-
}
724-
725710
function toNs(diff) {
726711
return diff[0] * 1e9 + diff[1];
727712
}

scripts/generateLocalizedDiagnosticMessages.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function main(): void {
3636
console.error("Unexpected XML file structure. Expected to find result.LCX.$.TgtCul.");
3737
process.exit(1);
3838
}
39-
const outputDirectoryName = getPreferedLocaleName(result.LCX.$.TgtCul);
39+
const outputDirectoryName = getPreferedLocaleName(result.LCX.$.TgtCul).toLowerCase();
4040
if (!outputDirectoryName) {
4141
console.error(`Invalid output locale name for '${result.LCX.$.TgtCul}'.`);
4242
process.exit(1);

src/compiler/checker.ts

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,12 +1419,18 @@ namespace ts {
14191419
}
14201420
}
14211421
break;
1422+
case SyntaxKind.ArrowFunction:
1423+
// when targeting ES6 or higher there is no 'arguments' in an arrow function
1424+
// for lower compile targets the resolved symbol is used to emit an error
1425+
if (compilerOptions.target! >= ScriptTarget.ES2015) {
1426+
break;
1427+
}
1428+
// falls through
14221429
case SyntaxKind.MethodDeclaration:
14231430
case SyntaxKind.Constructor:
14241431
case SyntaxKind.GetAccessor:
14251432
case SyntaxKind.SetAccessor:
14261433
case SyntaxKind.FunctionDeclaration:
1427-
case SyntaxKind.ArrowFunction:
14281434
if (meaning & SymbolFlags.Variable && name === "arguments") {
14291435
result = argumentsSymbol;
14301436
break loop;
@@ -4709,6 +4715,10 @@ namespace ts {
47094715
return prop ? getTypeOfSymbol(prop) : undefined;
47104716
}
47114717

4718+
function getTypeOfPropertyOrIndexSignature(type: Type, name: __String): Type {
4719+
return getTypeOfPropertyOfType(type, name) || isNumericLiteralName(name) && getIndexTypeOfType(type, IndexKind.Number) || getIndexTypeOfType(type, IndexKind.String) || unknownType;
4720+
}
4721+
47124722
function isTypeAny(type: Type | undefined) {
47134723
return type && (type.flags & TypeFlags.Any) !== 0;
47144724
}
@@ -12168,10 +12178,6 @@ namespace ts {
1216812178
return result;
1216912179
}
1217012180

12171-
function getConstraintForRelation(type: Type) {
12172-
return relation === definitelyAssignableRelation ? undefined : getConstraintOfType(type);
12173-
}
12174-
1217512181
function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, isIntersectionConstituent: boolean): Ternary {
1217612182
const flags = source.flags & target.flags;
1217712183
if (relation === identityRelation && !(flags & TypeFlags.Object)) {
@@ -12304,23 +12310,25 @@ namespace ts {
1230412310
return result;
1230512311
}
1230612312
}
12307-
const constraint = getConstraintForRelation(<TypeParameter>source);
12308-
if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.AnyOrUnknown)) {
12309-
// A type variable with no constraint is not related to the non-primitive object type.
12310-
if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
12311-
errorInfo = saveErrorInfo;
12312-
return result;
12313+
if (relation !== definitelyAssignableRelation) {
12314+
const constraint = getConstraintOfType(<TypeParameter>source);
12315+
if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) {
12316+
// A type variable with no constraint is not related to the non-primitive object type.
12317+
if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
12318+
errorInfo = saveErrorInfo;
12319+
return result;
12320+
}
1231312321
}
12314-
}
12315-
// hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
12316-
else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) {
12322+
// hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
12323+
else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) {
12324+
errorInfo = saveErrorInfo;
12325+
return result;
12326+
}
12327+
// slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
12328+
else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) {
1231712329
errorInfo = saveErrorInfo;
1231812330
return result;
12319-
}
12320-
// slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
12321-
else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) {
12322-
errorInfo = saveErrorInfo;
12323-
return result;
12331+
}
1232412332
}
1232512333
}
1232612334
else if (source.flags & TypeFlags.Index) {
@@ -12473,10 +12481,10 @@ namespace ts {
1247312481
return propertiesIdenticalTo(source, target);
1247412482
}
1247512483
const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source) && !isTupleType(source);
12476-
const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
12484+
const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false);
1247712485
if (unmatchedProperty) {
1247812486
if (reportErrors) {
12479-
const props = arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties));
12487+
const props = arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false));
1248012488
if (!headMessage || (headMessage.code !== Diagnostics.Class_0_incorrectly_implements_interface_1.code &&
1248112489
headMessage.code !== Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) {
1248212490
suppressNextError = true; // Retain top-level error for interface implementing issues, otherwise omit it
@@ -13900,20 +13908,29 @@ namespace ts {
1390013908
return getTypeFromInference(inference);
1390113909
}
1390213910

13903-
function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean) {
13911+
function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean) {
1390413912
const properties = target.flags & TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(<IntersectionType>target) : getPropertiesOfObjectType(target);
1390513913
for (const targetProp of properties) {
1390613914
if (requireOptionalProperties || !(targetProp.flags & SymbolFlags.Optional)) {
1390713915
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
1390813916
if (!sourceProp) {
1390913917
yield targetProp;
1391013918
}
13919+
else if (matchDiscriminantProperties) {
13920+
const targetType = getTypeOfSymbol(targetProp);
13921+
if (targetType.flags & TypeFlags.Unit) {
13922+
const sourceType = getTypeOfSymbol(sourceProp);
13923+
if (!(sourceType.flags & TypeFlags.Any || getRegularTypeOfLiteralType(sourceType) === getRegularTypeOfLiteralType(targetType))) {
13924+
yield targetProp;
13925+
}
13926+
}
13927+
}
1391113928
}
1391213929
}
1391313930
}
1391413931

13915-
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean): Symbol | undefined {
13916-
return getUnmatchedProperties(source, target, requireOptionalProperties).next().value;
13932+
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean): Symbol | undefined {
13933+
return getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties).next().value;
1391713934
}
1391813935

1391913936
function tupleTypesDefinitelyUnrelated(source: TupleTypeReference, target: TupleTypeReference) {
@@ -13925,7 +13942,8 @@ namespace ts {
1392513942
// Two tuple types with incompatible arities are definitely unrelated.
1392613943
// Two object types that each have a property that is unmatched in the other are definitely unrelated.
1392713944
return isTupleType(source) && isTupleType(target) && tupleTypesDefinitelyUnrelated(source, target) ||
13928-
!!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false) && !!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false);
13945+
!!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true) &&
13946+
!!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true);
1392913947
}
1393013948

1393113949
function getTypeFromInference(inference: InferenceInfo) {
@@ -15643,7 +15661,7 @@ namespace ts {
1564315661
}
1564415662
const propType = getTypeOfPropertyOfType(type, propName);
1564515663
const narrowedPropType = propType && narrowType(propType);
15646-
return propType === narrowedPropType ? type : filterType(type, t => isTypeComparableTo(getTypeOfPropertyOfType(t, propName)!, narrowedPropType!));
15664+
return propType === narrowedPropType ? type : filterType(type, t => isTypeComparableTo(getTypeOfPropertyOrIndexSignature(t, propName), narrowedPropType!));
1564715665
}
1564815666

1564915667
function narrowTypeByTruthiness(type: Type, expr: Expression, assumeTrue: boolean): Type {
@@ -19872,14 +19890,31 @@ namespace ts {
1987219890
}
1987319891

1987419892
function getTypeArgumentArityError(node: Node, signatures: ReadonlyArray<Signature>, typeArguments: NodeArray<TypeNode>) {
19875-
let min = Infinity;
19876-
let max = -Infinity;
19893+
const argCount = typeArguments.length;
19894+
// No overloads exist
19895+
if (signatures.length === 1) {
19896+
const sig = signatures[0];
19897+
const min = getMinTypeArgumentCount(sig.typeParameters);
19898+
const max = length(sig.typeParameters);
19899+
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, min < max ? min + "-" + max : min , argCount);
19900+
}
19901+
// Overloads exist
19902+
let belowArgCount = -Infinity;
19903+
let aboveArgCount = Infinity;
1987719904
for (const sig of signatures) {
19878-
min = Math.min(min, getMinTypeArgumentCount(sig.typeParameters));
19879-
max = Math.max(max, length(sig.typeParameters));
19905+
const min = getMinTypeArgumentCount(sig.typeParameters);
19906+
const max = length(sig.typeParameters);
19907+
if (min > argCount) {
19908+
aboveArgCount = Math.min(aboveArgCount, min);
19909+
}
19910+
else if (max < argCount) {
19911+
belowArgCount = Math.max(belowArgCount, max);
19912+
}
19913+
}
19914+
if (belowArgCount !== -Infinity && aboveArgCount !== Infinity) {
19915+
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments, argCount, belowArgCount, aboveArgCount);
1988019916
}
19881-
const paramCount = min === max ? min : min + "-" + max;
19882-
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length);
19917+
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
1988319918
}
1988419919

1988519920
function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean, fallbackError?: DiagnosticMessage): Signature {
@@ -23633,7 +23668,6 @@ namespace ts {
2363323668
break;
2363423669
}
2363523670
}
23636-
checkGrammarForDisallowedTrailingComma(node.elementTypes);
2363723671
forEach(node.elementTypes, checkSourceElement);
2363823672
}
2363923673

src/compiler/core.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,10 @@ namespace ts {
21652165
}
21662166

21672167
export function fill<T>(length: number, cb: (index: number) => T): T[] {
2168-
return new Array(length).fill(0).map((_, i) => cb(i));
2168+
const result = Array<T>(length);
2169+
for (let i = 0; i < length; i++) {
2170+
result[i] = cb(i);
2171+
}
2172+
return result;
21692173
}
21702174
}

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,10 @@
10111011
"category": "Message",
10121012
"code": 1350
10131013
},
1014+
"An identifier or keyword cannot immediately follow a numeric literal.": {
1015+
"category": "Error",
1016+
"code": 1351
1017+
},
10141018

10151019
"Duplicate identifier '{0}'.": {
10161020
"category": "Error",
@@ -2529,6 +2533,10 @@
25292533
"category": "Error",
25302534
"code": 2742
25312535
},
2536+
"No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments.": {
2537+
"category": "Error",
2538+
"code": 2743
2539+
},
25322540

25332541
"Import declaration '{0}' is using private name '{1}'.": {
25342542
"category": "Error",

src/compiler/inspectValue.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,18 @@ namespace ts {
4040

4141
type Recurser = <T>(obj: unknown, name: string, cbOk: () => T, cbFail: (isCircularReference: boolean, keyStack: ReadonlyArray<string>) => T) => T;
4242
function getRecurser(): Recurser {
43-
const seen = new Set<unknown>();
43+
const seen: unknown[] = [];
4444
const nameStack: string[] = [];
4545
return (obj, name, cbOk, cbFail) => {
46-
if (seen.has(obj) || nameStack.length > 4) {
47-
return cbFail(seen.has(obj), nameStack);
46+
if (seen.indexOf(obj) !== -1 || nameStack.length > 4) {
47+
return cbFail(seen.indexOf(obj) !== -1, nameStack);
4848
}
4949

50-
seen.add(obj);
50+
seen.push(obj);
5151
nameStack.push(name);
5252
const res = cbOk();
5353
nameStack.pop();
54-
seen.delete(obj);
54+
seen.pop();
5555
return res;
5656
};
5757
}
@@ -104,8 +104,8 @@ namespace ts {
104104
key === "constructor" ? undefined : getValueInfo(key, value, recurser));
105105
}
106106

107-
const ignoredProperties: ReadonlySet<string> = new Set(["arguments", "caller", "constructor", "eval", "super_"]);
108-
const reservedFunctionProperties: ReadonlySet<string> = new Set(Object.getOwnPropertyNames(noop));
107+
const ignoredProperties: ReadonlyArray<string> = ["arguments", "caller", "constructor", "eval", "super_"];
108+
const reservedFunctionProperties: ReadonlyArray<string> = Object.getOwnPropertyNames(noop);
109109
interface ObjectEntry { readonly key: string; readonly value: unknown; }
110110
function getEntriesOfObject(obj: object): ReadonlyArray<ObjectEntry> {
111111
const seen = createMap<true>();
@@ -114,8 +114,8 @@ namespace ts {
114114
while (!isNullOrUndefined(chain) && chain !== Object.prototype && chain !== Function.prototype) {
115115
for (const key of Object.getOwnPropertyNames(chain)) {
116116
if (!isJsPrivate(key) &&
117-
!ignoredProperties.has(key) &&
118-
(typeof obj !== "function" || !reservedFunctionProperties.has(key)) &&
117+
ignoredProperties.indexOf(key) === -1 &&
118+
(typeof obj !== "function" || reservedFunctionProperties.indexOf(key) === -1) &&
119119
// Don't add property from a higher prototype if it already exists in a lower one
120120
addToSeen(seen, key)) {
121121
const value = safeGetPropertyOfObject(chain, key);
@@ -148,7 +148,7 @@ namespace ts {
148148
}
149149

150150
export function isJsPrivate(name: string): boolean {
151-
return name.startsWith("_");
151+
return startsWith(name, "_");
152152
}
153153

154154
function tryRequire(fileNameToRequire: string): unknown {

0 commit comments

Comments
 (0)