Skip to content

Commit 3f4e5a4

Browse files
committed
Merge branch 'master' into javaScriptModules
# Conflicts: # tests/webTestServer.ts
2 parents d880d4f + ece96ac commit 3f4e5a4

39 files changed

Lines changed: 561 additions & 215 deletions

CONTRIBUTING.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
## Contributing bug fixes
2+
23
TypeScript is currently accepting contributions in the form of bug fixes. A bug must have an issue tracking it in the issue tracker that has been approved ("Milestone == Community") by the TypeScript team. Your pull request should include a link to the bug that you are fixing. If you've submitted a PR for a bug, please post a comment in the bug to avoid duplication of effort.
34

45
## Contributing features
6+
57
Features (things that add new or improved functionality to TypeScript) may be accepted, but will need to first be approved (marked as "Milestone == Community" by a TypeScript coordinator with the message "Approved") in the suggestion issue. Features with language design impact, or that are adequately satisfied with external tools, will not be accepted.
68

79
Design changes will not be accepted at this time. If you have a design change proposal, please log a suggestion issue.
810

911
## Legal
12+
1013
You will need to complete a Contributor License Agreement (CLA). Briefly, this agreement testifies that you are granting us permission to use the submitted change according to the terms of the project's license, and that the work being submitted is under appropriate copyright.
1114

1215
Please submit a Contributor License Agreement (CLA) before submitting a pull request. You may visit https://cla.microsoft.com to sign digitally. Alternatively, download the agreement ([Microsoft Contribution License Agreement.docx](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=822190) or [Microsoft Contribution License Agreement.pdf](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=921298)), sign, scan, and email it back to <cla@microsoft.com>. Be sure to include your github user name along with the agreement. Once we have received the signed CLA, we'll review the request.
1316

1417
## Housekeeping
18+
1519
Your pull request should:
1620

1721
* Include a description of what your change intends to do
@@ -29,7 +33,8 @@ Your pull request should:
2933
* To avoid line ending issues, set `autocrlf = input` and `whitespace = cr-at-eol` in your git configuration
3034

3135
## Running the Tests
32-
To run all tests, invoke the runtests target using jake:
36+
37+
To run all tests, invoke the `runtests` target using jake:
3338

3439
```Shell
3540
jake runtests
@@ -55,7 +60,7 @@ jake runtests tests=2dArrays
5560

5661
## Debugging the tests
5762

58-
To debug the tests, invoke the runtests-browser using jake.
63+
To debug the tests, invoke the `runtests-browser` task from jake.
5964
You will probably only want to debug one test at a time:
6065

6166
```Shell
@@ -75,16 +80,14 @@ jake runtests tests=2dArrays debug=true
7580
```
7681

7782
## Adding a Test
78-
To add a new testcase, simply place a `.ts` file in `tests\cases\compiler` containing code that exemplifies the bugfix or change you are making.
7983

80-
These files support metadata tags in the format `// @metaDataName: value`. The supported names and values are:
84+
To add a new test case, simply place a `.ts` file in `tests\cases\compiler` containing code that exemplifies the bugfix or change you are making.
8185

82-
* `comments`, `sourcemap`, `noimplicitany`, `declaration`: true or false (corresponds to the compiler command-line options of the same name)
83-
* `target`: ES3 or ES5 (same as compiler)
84-
* `out`, outDir: path (same as compiler)
85-
* `module`: local, commonjs, or amd (local corresponds to not passing any compiler --module flag)
86-
* `fileName`: path
87-
* These tags delimit sections of a file to be used as separate compilation units. They are useful for tests relating to modules. See below for examples.
86+
These files support metadata tags in the format `// @metaDataName: value`.
87+
The supported names and values are the same as those supported in the compiler itself, with the addition of the `fileName` flag.
88+
`fileName` tags delimit sections of a file to be used as separate compilation units.
89+
They are useful for tests relating to modules.
90+
See below for examples.
8891

8992
**Note** that if you have a test corresponding to a specific spec compliance item, you can place it in `tests\cases\conformance` in an appropriately-named subfolder.
9093
**Note** that filenames here must be distinct from all other compiler testcase names, so you may have to work a bit to find a unique name if it's something common.
@@ -107,6 +110,7 @@ var x = g();
107110
One can also write a project test, but it is slightly more involved.
108111

109112
## Managing the Baselines
113+
110114
Compiler testcases generate baselines that track the emitted `.js`, the errors produced by the compiler, and the type of each expression in the file. Additionally, some testcases opt in to baselining the source map output.
111115

112116
When a change in the baselines is detected, the test will fail. To inspect changes vs the expected baselines, use
@@ -123,4 +127,4 @@ jake baseline-accept
123127

124128
to establish the new baselines as the desired behavior. This will change the files in `tests\baselines\reference`, which should be included as part of your commit. It's important to carefully validate changes in the baselines.
125129

126-
**Note** that baseline-accept should only be run after a full test run! Accepting baselines after running a subset of tests will delete baseline files for the tests that didn't run.
130+
**Note** that `baseline-accept` should only be run after a full test run! Accepting baselines after running a subset of tests will delete baseline files for the tests that didn't run.

src/compiler/checker.ts

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4922,7 +4922,7 @@ namespace ts {
49224922
if (apparentType.flags & (TypeFlags.ObjectType | TypeFlags.Intersection) && target.flags & TypeFlags.ObjectType) {
49234923
// Report structural errors only if we haven't reported any errors yet
49244924
let reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo;
4925-
if (result = objectTypeRelatedTo(apparentType, <ObjectType>target, reportStructuralErrors)) {
4925+
if (result = objectTypeRelatedTo(apparentType, source, target, reportStructuralErrors)) {
49264926
errorInfo = saveErrorInfo;
49274927
return result;
49284928
}
@@ -4944,7 +4944,7 @@ namespace ts {
49444944
return result;
49454945
}
49464946
}
4947-
return objectTypeRelatedTo(<ObjectType>source, <ObjectType>target, /*reportErrors*/ false);
4947+
return objectTypeRelatedTo(source, source, target, /*reportErrors*/ false);
49484948
}
49494949
if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) {
49504950
return typeParameterIdenticalTo(<TypeParameter>source, <TypeParameter>target);
@@ -4971,34 +4971,34 @@ namespace ts {
49714971
resolved.stringIndexType || resolved.numberIndexType || getPropertyOfType(type, name)) {
49724972
return true;
49734973
}
4974-
return false;
49754974
}
4976-
if (type.flags & TypeFlags.UnionOrIntersection) {
4975+
else if (type.flags & TypeFlags.UnionOrIntersection) {
49774976
for (let t of (<UnionOrIntersectionType>type).types) {
49784977
if (isKnownProperty(t, name)) {
49794978
return true;
49804979
}
49814980
}
4982-
return false;
49834981
}
4984-
return true;
4982+
return false;
49854983
}
49864984

49874985
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
4988-
for (let prop of getPropertiesOfObjectType(source)) {
4989-
if (!isKnownProperty(target, prop.name)) {
4990-
if (reportErrors) {
4991-
// We know *exactly* where things went wrong when comparing the types.
4992-
// Use this property as the error node as this will be more helpful in
4993-
// reasoning about what went wrong.
4994-
errorNode = prop.valueDeclaration;
4995-
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
4996-
symbolToString(prop),
4997-
typeToString(target));
4986+
if (someConstituentTypeHasKind(target, TypeFlags.ObjectType)) {
4987+
for (let prop of getPropertiesOfObjectType(source)) {
4988+
if (!isKnownProperty(target, prop.name)) {
4989+
if (reportErrors) {
4990+
// We know *exactly* where things went wrong when comparing the types.
4991+
// Use this property as the error node as this will be more helpful in
4992+
// reasoning about what went wrong.
4993+
errorNode = prop.valueDeclaration;
4994+
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
4995+
symbolToString(prop), typeToString(target));
4996+
}
4997+
return true;
49984998
}
4999-
return true;
50004999
}
50015000
}
5001+
return false;
50025002
}
50035003

50045004
function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType): Ternary {
@@ -5098,11 +5098,11 @@ namespace ts {
50985098
// Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
50995099
// equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion
51005100
// and issue an error. Otherwise, actually compare the structure of the two types.
5101-
function objectTypeRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
5101+
function objectTypeRelatedTo(apparentSource: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
51025102
if (overflow) {
51035103
return Ternary.False;
51045104
}
5105-
let id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id;
5105+
let id = relation !== identityRelation || apparentSource.id < target.id ? apparentSource.id + "," + target.id : target.id + "," + apparentSource.id;
51065106
let related = relation[id];
51075107
if (related !== undefined) {
51085108
// If we computed this relation already and it was failed and reported, or if we're not being asked to elaborate
@@ -5129,28 +5129,28 @@ namespace ts {
51295129
maybeStack = [];
51305130
expandingFlags = 0;
51315131
}
5132-
sourceStack[depth] = source;
5132+
sourceStack[depth] = apparentSource;
51335133
targetStack[depth] = target;
51345134
maybeStack[depth] = {};
51355135
maybeStack[depth][id] = RelationComparisonResult.Succeeded;
51365136
depth++;
51375137
let saveExpandingFlags = expandingFlags;
5138-
if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack, depth)) expandingFlags |= 1;
5138+
if (!(expandingFlags & 1) && isDeeplyNestedGeneric(apparentSource, sourceStack, depth)) expandingFlags |= 1;
51395139
if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth)) expandingFlags |= 2;
51405140
let result: Ternary;
51415141
if (expandingFlags === 3) {
51425142
result = Ternary.Maybe;
51435143
}
51445144
else {
5145-
result = propertiesRelatedTo(source, target, reportErrors);
5145+
result = propertiesRelatedTo(apparentSource, target, reportErrors);
51465146
if (result) {
5147-
result &= signaturesRelatedTo(source, target, SignatureKind.Call, reportErrors);
5147+
result &= signaturesRelatedTo(apparentSource, target, SignatureKind.Call, reportErrors);
51485148
if (result) {
5149-
result &= signaturesRelatedTo(source, target, SignatureKind.Construct, reportErrors);
5149+
result &= signaturesRelatedTo(apparentSource, target, SignatureKind.Construct, reportErrors);
51505150
if (result) {
5151-
result &= stringIndexTypesRelatedTo(source, target, reportErrors);
5151+
result &= stringIndexTypesRelatedTo(apparentSource, originalSource, target, reportErrors);
51525152
if (result) {
5153-
result &= numberIndexTypesRelatedTo(source, target, reportErrors);
5153+
result &= numberIndexTypesRelatedTo(apparentSource, originalSource, target, reportErrors);
51545154
}
51555155
}
51565156
}
@@ -5481,12 +5481,17 @@ namespace ts {
54815481
return result;
54825482
}
54835483

5484-
function stringIndexTypesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
5484+
function stringIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
54855485
if (relation === identityRelation) {
54865486
return indexTypesIdenticalTo(IndexKind.String, source, target);
54875487
}
54885488
let targetType = getIndexTypeOfType(target, IndexKind.String);
5489-
if (targetType && !(targetType.flags & TypeFlags.Any)) {
5489+
if (targetType) {
5490+
if ((targetType.flags & TypeFlags.Any) && !(originalSource.flags & TypeFlags.Primitive)) {
5491+
// non-primitive assignment to any is always allowed, eg
5492+
// `var x: { [index: string]: any } = { property: 12 };`
5493+
return Ternary.True;
5494+
}
54905495
let sourceType = getIndexTypeOfType(source, IndexKind.String);
54915496
if (!sourceType) {
54925497
if (reportErrors) {
@@ -5506,12 +5511,17 @@ namespace ts {
55065511
return Ternary.True;
55075512
}
55085513

5509-
function numberIndexTypesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
5514+
function numberIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
55105515
if (relation === identityRelation) {
55115516
return indexTypesIdenticalTo(IndexKind.Number, source, target);
55125517
}
55135518
let targetType = getIndexTypeOfType(target, IndexKind.Number);
5514-
if (targetType && !(targetType.flags & TypeFlags.Any)) {
5519+
if (targetType) {
5520+
if ((targetType.flags & TypeFlags.Any) && !(originalSource.flags & TypeFlags.Primitive)) {
5521+
// non-primitive assignment to any is always allowed, eg
5522+
// `var x: { [index: number]: any } = { property: 12 };`
5523+
return Ternary.True;
5524+
}
55155525
let sourceStringType = getIndexTypeOfType(source, IndexKind.String);
55165526
let sourceNumberType = getIndexTypeOfType(source, IndexKind.Number);
55175527
if (!(sourceStringType || sourceNumberType)) {
@@ -7537,9 +7547,6 @@ namespace ts {
75377547
case SyntaxKind.JsxSelfClosingElement:
75387548
checkJsxSelfClosingElement(<JsxSelfClosingElement>child);
75397549
break;
7540-
default:
7541-
// No checks for JSX Text
7542-
Debug.assert(child.kind === SyntaxKind.JsxText);
75437550
}
75447551
}
75457552

0 commit comments

Comments
 (0)