Skip to content

Commit 8a51cda

Browse files
committed
Merge branch 'master' into builderApi
2 parents 2be231d + eed8573 commit 8a51cda

File tree

199 files changed

+17075
-6230
lines changed

Some content is hidden

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

199 files changed

+17075
-6230
lines changed

.npmignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ Jakefile.js
1818
.settings/
1919
.travis.yml
2020
.vscode/
21-
test.config
21+
test.config
22+
package-lock.json

issue_template.md

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,34 @@
1-
<!-- BUGS: Please use this template. -->
2-
<!-- QUESTIONS: This is not a general support forum! Ask Qs at http://stackoverflow.com/questions/tagged/typescript -->
3-
<!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md -->
1+
<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨 -->
2+
<!--
3+
Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker.
4+
5+
Please help us by doing the following steps before logging an issue:
6+
* Search: https://github.com/Microsoft/TypeScript/search?type=Issues
7+
* Read the CONTRIBUTING guidelines: https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md
8+
* Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ
9+
-->
10+
11+
<!-- If you have a QUESTION:
12+
THIS IS NOT A FORUM FOR QUESTIONS.
13+
Ask questions at http://stackoverflow.com/questions/tagged/typescript
14+
or https://gitter.im/Microsoft/TypeScript
15+
-->
16+
17+
<!-- If you have a SUGGESTION:
18+
Most suggestion reports are duplicates, please search extra hard before logging a new suggestion.
19+
See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md
20+
-->
21+
22+
<!-- If you have a BUG:
23+
Please fill in the *entire* template below.
24+
-->
425

526
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
627
**TypeScript Version:** 2.7.0-dev.201xxxxx
728

29+
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
30+
**Search Terms:**
31+
832
**Code**
933

1034
```ts
@@ -16,4 +40,6 @@
1640

1741
**Actual behavior:**
1842

19-
**Related:**
43+
**Playground Link:** <!-- A link to a TypeScript Playground "Share" link which demonstrates this behavior -->
44+
45+
**Related Issues:**

src/compiler/checker.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6564,7 +6564,7 @@ namespace ts {
65646564
// b) It references `arguments` somewhere
65656565
const lastParam = lastOrUndefined(declaration.parameters);
65666566
const lastParamTags = lastParam && getJSDocParameterTags(lastParam);
6567-
const lastParamVariadicType = lastParamTags && firstDefined(lastParamTags, p =>
6567+
const lastParamVariadicType = firstDefined(lastParamTags, p =>
65686568
p.typeExpression && isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined);
65696569
if (!lastParamVariadicType && !containsArgumentsReference(declaration)) {
65706570
return false;
@@ -9639,7 +9639,7 @@ namespace ts {
96399639
}
96409640
else if (target.flags & TypeFlags.IndexedAccess) {
96419641
// A type S is related to a type T[K] if S is related to A[K], where K is string-like and
9642-
// A is the apparent type of T.
9642+
// A is the constraint of T.
96439643
const constraint = getConstraintOfIndexedAccess(<IndexedAccessType>target);
96449644
if (constraint) {
96459645
if (result = isRelatedTo(source, constraint, reportErrors)) {
@@ -9675,18 +9675,19 @@ namespace ts {
96759675
}
96769676
else if (source.flags & TypeFlags.IndexedAccess) {
96779677
// A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
9678-
// A is the apparent type of S.
9678+
// A is the constraint of S.
96799679
const constraint = getConstraintOfIndexedAccess(<IndexedAccessType>source);
96809680
if (constraint) {
96819681
if (result = isRelatedTo(constraint, target, reportErrors)) {
96829682
errorInfo = saveErrorInfo;
96839683
return result;
96849684
}
96859685
}
9686-
else if (target.flags & TypeFlags.IndexedAccess && (<IndexedAccessType>source).indexType === (<IndexedAccessType>target).indexType) {
9687-
// if we have indexed access types with identical index types, see if relationship holds for
9688-
// the two object types.
9686+
else if (target.flags & TypeFlags.IndexedAccess) {
96899687
if (result = isRelatedTo((<IndexedAccessType>source).objectType, (<IndexedAccessType>target).objectType, reportErrors)) {
9688+
result &= isRelatedTo((<IndexedAccessType>source).indexType, (<IndexedAccessType>target).indexType, reportErrors);
9689+
}
9690+
if (result) {
96909691
errorInfo = saveErrorInfo;
96919692
return result;
96929693
}
@@ -10967,7 +10968,7 @@ namespace ts {
1096710968
return type === typeParameter || type.flags & TypeFlags.UnionOrIntersection && forEach((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter));
1096810969
}
1096910970

10970-
/** Create an object with properties named in the string literal type. Every property has type `{}` */
10971+
/** Create an object with properties named in the string literal type. Every property has type `any` */
1097110972
function createEmptyObjectTypeFromStringLiteral(type: Type) {
1097210973
const members = createSymbolTable();
1097310974
forEachType(type, t => {
@@ -10976,7 +10977,7 @@ namespace ts {
1097610977
}
1097710978
const name = escapeLeadingUnderscores((t as StringLiteralType).value);
1097810979
const literalProp = createSymbol(SymbolFlags.Property, name);
10979-
literalProp.type = emptyObjectType;
10980+
literalProp.type = anyType;
1098010981
if (t.symbol) {
1098110982
literalProp.declarations = t.symbol.declarations;
1098210983
literalProp.valueDeclaration = t.symbol.valueDeclaration;
@@ -11031,7 +11032,9 @@ namespace ts {
1103111032
const templateType = getTemplateTypeFromMappedType(target);
1103211033
const inference = createInferenceInfo(typeParameter);
1103311034
inferTypes([inference], sourceType, templateType);
11034-
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType;
11035+
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) :
11036+
inference.contraCandidates ? getCommonSubtype(inference.contraCandidates) :
11037+
emptyObjectType;
1103511038
}
1103611039

1103711040
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) {
@@ -18377,6 +18380,9 @@ namespace ts {
1837718380

1837818381
function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type): Type {
1837918382
const properties = node.properties;
18383+
if (strictNullChecks && properties.length === 0) {
18384+
return checkNonNullType(sourceType, node);
18385+
}
1838018386
for (const p of properties) {
1838118387
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties);
1838218388
}
@@ -21446,7 +21452,13 @@ namespace ts {
2144621452
if (isBindingPattern(node.name)) {
2144721453
// Don't validate for-in initializer as it is already an error
2144821454
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
21449-
checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
21455+
const initializerType = checkExpressionCached(node.initializer);
21456+
if (strictNullChecks && node.name.elements.length === 0) {
21457+
checkNonNullType(initializerType, node);
21458+
}
21459+
else {
21460+
checkTypeAssignableTo(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
21461+
}
2145021462
checkParameterInitializer(node);
2145121463
}
2145221464
return;
@@ -26196,14 +26208,18 @@ namespace ts {
2619626208
function checkGrammarBindingElement(node: BindingElement) {
2619726209
if (node.dotDotDotToken) {
2619826210
const elements = (<BindingPattern>node.parent).elements;
26199-
if (node !== lastOrUndefined(elements)) {
26211+
if (node !== last(elements)) {
2620026212
return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
2620126213
}
2620226214

2620326215
if (node.name.kind === SyntaxKind.ArrayBindingPattern || node.name.kind === SyntaxKind.ObjectBindingPattern) {
2620426216
return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
2620526217
}
2620626218

26219+
if (node.propertyName) {
26220+
return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_have_a_property_name);
26221+
}
26222+
2620726223
if (node.initializer) {
2620826224
// Error on equals token which immediately precedes the initializer
2620926225
return grammarErrorAtPos(node, node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer);

src/compiler/core.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ namespace ts {
183183

184184
/** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
185185
export function firstDefined<T, U>(array: ReadonlyArray<T> | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
186+
if (array === undefined) {
187+
return undefined;
188+
}
189+
186190
for (let i = 0; i < array.length; i++) {
187191
const result = callback(array[i], i);
188192
if (result !== undefined) {

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,6 +1976,10 @@
19761976
"category": "Error",
19771977
"code": 2565
19781978
},
1979+
"A rest element cannot have a property name.": {
1980+
"category": "Error",
1981+
"code": 2566
1982+
},
19791983
"JSX element attributes type '{0}' may not be a union type.": {
19801984
"category": "Error",
19811985
"code": 2600
@@ -3893,10 +3897,6 @@
38933897
"category": "Message",
38943898
"code": 95002
38953899
},
3896-
"Extract symbol": {
3897-
"category": "Message",
3898-
"code": 95003
3899-
},
39003900
"Extract to {0} in {1}": {
39013901
"category": "Message",
39023902
"code": 95004

src/compiler/emitter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,12 +1268,12 @@ namespace ts {
12681268
}
12691269

12701270
function emitBindingElement(node: BindingElement) {
1271+
emitIfPresent(node.dotDotDotToken);
12711272
if (node.propertyName) {
12721273
emit(node.propertyName);
12731274
writePunctuation(":");
12741275
writeSpace();
12751276
}
1276-
emitIfPresent(node.dotDotDotToken);
12771277
emit(node.name);
12781278
emitInitializer(node.initializer);
12791279
}

src/compiler/parser.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ namespace ts {
126126
case SyntaxKind.BindingElement:
127127
return visitNodes(cbNode, cbNodes, node.decorators) ||
128128
visitNodes(cbNode, cbNodes, node.modifiers) ||
129-
visitNode(cbNode, (<BindingElement>node).propertyName) ||
130129
visitNode(cbNode, (<BindingElement>node).dotDotDotToken) ||
130+
visitNode(cbNode, (<BindingElement>node).propertyName) ||
131131
visitNode(cbNode, (<BindingElement>node).name) ||
132132
visitNode(cbNode, (<BindingElement>node).initializer);
133133
case SyntaxKind.FunctionType:
@@ -6830,7 +6830,7 @@ namespace ts {
68306830
}
68316831

68326832
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag | undefined {
6833-
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
6833+
if (some(tags, isJSDocTemplateTag)) {
68346834
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText);
68356835
}
68366836

@@ -6839,14 +6839,14 @@ namespace ts {
68396839
const typeParametersPos = getNodePos();
68406840

68416841
while (true) {
6842-
const name = parseJSDocIdentifierName();
6842+
const typeParameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter);
6843+
const name = parseJSDocIdentifierNameWithOptionalBraces();
68436844
skipWhitespace();
68446845
if (!name) {
68456846
parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected);
68466847
return undefined;
68476848
}
68486849

6849-
const typeParameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter, name.pos);
68506850
typeParameter.name = name;
68516851
finishNode(typeParameter);
68526852

@@ -6869,6 +6869,15 @@ namespace ts {
68696869
return result;
68706870
}
68716871

6872+
function parseJSDocIdentifierNameWithOptionalBraces(): Identifier | undefined {
6873+
const parsedBrace = parseOptional(SyntaxKind.OpenBraceToken);
6874+
const res = parseJSDocIdentifierName();
6875+
if (parsedBrace) {
6876+
parseExpected(SyntaxKind.CloseBraceToken);
6877+
}
6878+
return res;
6879+
}
6880+
68726881
function nextJSDocToken(): JsDocSyntaxKind {
68736882
return currentToken = scanner.scanJSDocToken();
68746883
}

src/compiler/resolutionCache.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -474,11 +474,6 @@ namespace ts {
474474
cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
475475
}
476476

477-
// Ignore emits from the program
478-
if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectory)) {
479-
return;
480-
}
481-
482477
// If the files are added to project root or node_modules directory, always run through the invalidation process
483478
// Otherwise run through invalidation only if adding to the immediate directory
484479
if (!allFilesHaveInvalidatedResolution &&
@@ -582,6 +577,10 @@ namespace ts {
582577
if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
583578
return false;
584579
}
580+
// Ignore emits from the program
581+
if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) {
582+
return false;
583+
}
585584
// Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
586585
isChangedFailedLookupLocation = location => resolutionHost.toPath(location) === fileOrDirectoryPath;
587586
}

src/compiler/utilities.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2029,7 +2029,13 @@ namespace ts {
20292029
return token !== undefined && isNonContextualKeyword(token);
20302030
}
20312031

2032-
export function isTrivia(token: SyntaxKind) {
2032+
export type TriviaKind = SyntaxKind.SingleLineCommentTrivia
2033+
| SyntaxKind.MultiLineCommentTrivia
2034+
| SyntaxKind.NewLineTrivia
2035+
| SyntaxKind.WhitespaceTrivia
2036+
| SyntaxKind.ShebangTrivia
2037+
| SyntaxKind.ConflictMarkerTrivia;
2038+
export function isTrivia(token: SyntaxKind): token is TriviaKind {
20332039
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
20342040
}
20352041

src/harness/externalCompileRunner.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,15 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
3333
});
3434
}
3535
private runTest(directoryName: string) {
36-
describe(directoryName, () => {
36+
// tslint:disable-next-line:no-this-assignment
37+
const cls = this;
38+
const timeout = 600_000; // 10 minutes
39+
describe(directoryName, function(this: Mocha.ISuiteCallbackContext) {
40+
this.timeout(timeout);
3741
const cp = require("child_process");
3842

3943
it("should build successfully", () => {
40-
let cwd = path.join(__dirname, "../../", this.testDir, directoryName);
41-
const timeout = 600000; // 600s = 10 minutes
44+
let cwd = path.join(__dirname, "../../", cls.testDir, directoryName);
4245
const stdio = isWorker ? "pipe" : "inherit";
4346
let types: string[];
4447
if (fs.existsSync(path.join(cwd, "test.json"))) {
@@ -61,18 +64,18 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
6164
fs.unlinkSync(path.join(cwd, "package-lock.json"));
6265
}
6366
if (fs.existsSync(path.join(cwd, "node_modules"))) {
64-
require("del").sync(path.join(cwd, "node_modules"));
67+
require("del").sync(path.join(cwd, "node_modules"), { force: true });
6568
}
66-
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio });
69+
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
6770
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed: ${install.stderr.toString()}`);
6871
}
6972
const args = [path.join(__dirname, "tsc.js")];
7073
if (types) {
7174
args.push("--types", types.join(","));
7275
}
7376
args.push("--noEmit");
74-
Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => {
75-
return this.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd);
77+
Harness.Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, () => {
78+
return cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd);
7679
});
7780
});
7881
});

0 commit comments

Comments
 (0)