Skip to content

Commit 77a2d0e

Browse files
author
Arthur Ozga
committed
Merge branch 'master' into FixTripleSlashCompletions
2 parents 24938a7 + f442480 commit 77a2d0e

26 files changed

+23441
-45
lines changed

Gulpfile.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,16 +725,16 @@ declare module "convert-source-map" {
725725
}
726726

727727
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
728-
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "built/local/bundle.js" }, /*useBuiltCompiler*/ true));
728+
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "../../built/local/bundle.js" }, /*useBuiltCompiler*/ true));
729729
return testProject.src()
730730
.pipe(newer("built/local/bundle.js"))
731731
.pipe(sourcemaps.init())
732-
.pipe(testProject)
732+
.pipe(testProject())
733733
.pipe(through2.obj((file, enc, next) => {
734734
const originalMap = file.sourceMap;
735735
const prebundledContent = file.contents.toString();
736736
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
737-
originalMap.sources = originalMap.sources.map(s => path.resolve("src", s));
737+
originalMap.sources = originalMap.sources.map(s => path.resolve(s));
738738
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
739739
originalMap.file = "built/local/_stream_0.js";
740740

src/compiler/binder.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,8 +2432,7 @@ namespace ts {
24322432
}
24332433

24342434
// If the parameter's name is 'this', then it is TypeScript syntax.
2435-
if (subtreeFlags & TransformFlags.ContainsDecorators
2436-
|| (name && isIdentifier(name) && name.originalKeywordKind === SyntaxKind.ThisKeyword)) {
2435+
if (subtreeFlags & TransformFlags.ContainsDecorators || isThisIdentifier(name)) {
24372436
transformFlags |= TransformFlags.AssertTypeScript;
24382437
}
24392438

src/compiler/checker.ts

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,9 +2183,14 @@ namespace ts {
21832183
// The specified symbol flags need to be reinterpreted as type flags
21842184
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
21852185
}
2186-
else if (!(flags & TypeFormatFlags.InTypeAlias) && type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
2186+
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((type.flags & TypeFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
21872187
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
2188-
// Only write out inferred type with its corresponding type-alias if type-alias is visible
2188+
// We emit inferred type as type-alias at the current localtion if all the following is true
2189+
// the input type is has alias symbol that is accessible
2190+
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
2191+
// e.g.: export type Bar<X, Y> = () => [X, Y];
2192+
// export type Foo<Y> = Bar<any, Y>;
2193+
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
21892194
const typeArguments = type.aliasTypeArguments;
21902195
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
21912196
}
@@ -5446,7 +5451,26 @@ namespace ts {
54465451
return false;
54475452
}
54485453

5454+
function isSetOfLiteralsFromSameEnum(types: TypeSet): boolean {
5455+
const first = types[0];
5456+
if (first.flags & TypeFlags.EnumLiteral) {
5457+
const firstEnum = getParentOfSymbol(first.symbol);
5458+
for (let i = 1; i < types.length; i++) {
5459+
const other = types[i];
5460+
if (!(other.flags & TypeFlags.EnumLiteral) || (firstEnum !== getParentOfSymbol(other.symbol))) {
5461+
return false;
5462+
}
5463+
}
5464+
return true;
5465+
}
5466+
5467+
return false;
5468+
}
5469+
54495470
function removeSubtypes(types: TypeSet) {
5471+
if (types.length === 0 || isSetOfLiteralsFromSameEnum(types)) {
5472+
return;
5473+
}
54505474
let i = types.length;
54515475
while (i > 0) {
54525476
i--;
@@ -9354,7 +9378,7 @@ namespace ts {
93549378
captureLexicalThis(node, container);
93559379
}
93569380
if (isFunctionLike(container) &&
9357-
(!isInParameterInitializerBeforeContainingFunction(node) || getFunctionLikeThisParameter(container))) {
9381+
(!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
93589382
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
93599383

93609384
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
@@ -15538,10 +15562,6 @@ namespace ts {
1553815562
}
1553915563
}
1554015564

15541-
function parameterIsThisKeyword(parameter: ParameterDeclaration) {
15542-
return parameter.name && (<Identifier>parameter.name).originalKeywordKind === SyntaxKind.ThisKeyword;
15543-
}
15544-
1554515565
function parameterNameStartsWithUnderscore(parameter: ParameterDeclaration) {
1554615566
return parameter.name && parameter.name.kind === SyntaxKind.Identifier && (<Identifier>parameter.name).text.charCodeAt(0) === CharacterCodes._;
1554715567
}
@@ -20122,18 +20142,8 @@ namespace ts {
2012220142
}
2012320143

2012420144
function getAccessorThisParameter(accessor: AccessorDeclaration): ParameterDeclaration {
20125-
if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2) &&
20126-
accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
20127-
(<Identifier>accessor.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
20128-
return accessor.parameters[0];
20129-
}
20130-
}
20131-
20132-
function getFunctionLikeThisParameter(func: FunctionLikeDeclaration) {
20133-
if (func.parameters.length &&
20134-
func.parameters[0].name.kind === SyntaxKind.Identifier &&
20135-
(<Identifier>func.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
20136-
return func.parameters[0];
20145+
if (accessor.parameters.length === (accessor.kind === SyntaxKind.GetAccessor ? 1 : 2)) {
20146+
return getThisParameter(accessor);
2013720147
}
2013820148
}
2013920149

src/compiler/parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,8 +1394,8 @@ namespace ts {
13941394
// Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
13951395
return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/;
13961396
case ParsingContext.TypeArguments:
1397-
// Tokens other than '>' are here for better error recovery
1398-
return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken;
1397+
// All other tokens should cause the type-argument to terminate except comma token
1398+
return token() !== SyntaxKind.CommaToken;
13991399
case ParsingContext.HeritageClauses:
14001400
return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.CloseBraceToken;
14011401
case ParsingContext.JsxAttributes:

src/compiler/transformers/ts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2374,7 +2374,7 @@ namespace ts {
23742374
* @param node The parameter declaration node.
23752375
*/
23762376
function visitParameter(node: ParameterDeclaration) {
2377-
if (node.name && isIdentifier(node.name) && node.name.originalKeywordKind === SyntaxKind.ThisKeyword) {
2377+
if (parameterIsThisKeyword(node)) {
23782378
return undefined;
23792379
}
23802380

src/compiler/utilities.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,15 +2707,35 @@ namespace ts {
27072707
});
27082708
}
27092709

2710-
export function getSetAccessorTypeAnnotationNode(accessor: AccessorDeclaration): TypeNode {
2710+
/** Get the type annotaion for the value parameter. */
2711+
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
27112712
if (accessor && accessor.parameters.length > 0) {
2712-
const hasThis = accessor.parameters.length === 2 &&
2713-
accessor.parameters[0].name.kind === SyntaxKind.Identifier &&
2714-
(accessor.parameters[0].name as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword;
2713+
const hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
27152714
return accessor.parameters[hasThis ? 1 : 0].type;
27162715
}
27172716
}
27182717

2718+
export function getThisParameter(signature: SignatureDeclaration): ParameterDeclaration | undefined {
2719+
if (signature.parameters.length) {
2720+
const thisParameter = signature.parameters[0];
2721+
if (parameterIsThisKeyword(thisParameter)) {
2722+
return thisParameter;
2723+
}
2724+
}
2725+
}
2726+
2727+
export function parameterIsThisKeyword(parameter: ParameterDeclaration): boolean {
2728+
return isThisIdentifier(parameter.name);
2729+
}
2730+
2731+
export function isThisIdentifier(node: Node | undefined): boolean {
2732+
return node && node.kind === SyntaxKind.Identifier && identifierIsThisKeyword(node as Identifier);
2733+
}
2734+
2735+
export function identifierIsThisKeyword(id: Identifier): boolean {
2736+
return id.originalKeywordKind === SyntaxKind.ThisKeyword;
2737+
}
2738+
27192739
export interface AllAccessorDeclarations {
27202740
firstAccessor: AccessorDeclaration;
27212741
secondAccessor: AccessorDeclaration;

src/services/classifier.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -954,8 +954,7 @@ namespace ts {
954954
return;
955955
case SyntaxKind.Parameter:
956956
if ((<ParameterDeclaration>token.parent).name === token) {
957-
const isThis = token.kind === SyntaxKind.Identifier && (<Identifier>token).originalKeywordKind === SyntaxKind.ThisKeyword;
958-
return isThis ? ClassificationType.keyword : ClassificationType.parameterName;
957+
return isThisIdentifier(token) ? ClassificationType.keyword : ClassificationType.parameterName;
959958
}
960959
return;
961960
}

src/services/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ namespace ts {
376376
return true;
377377
case SyntaxKind.Identifier:
378378
// 'this' as a parameter
379-
return (node as Identifier).originalKeywordKind === SyntaxKind.ThisKeyword && node.parent.kind === SyntaxKind.Parameter;
379+
return identifierIsThisKeyword(node as Identifier) && node.parent.kind === SyntaxKind.Parameter;
380380
default:
381381
return false;
382382
}
Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
11
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2304: Cannot find name 'Foo'.
2+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2695: Left side of comma operator is unused and has no side effects.
3+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,1): error TS2695: Left side of comma operator is unused and has no side effects.
4+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,5): error TS2304: Cannot find name 'A'.
5+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,7): error TS2304: Cannot find name 'B'.
26
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,9): error TS1127: Invalid character.
7+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,11): error TS2304: Cannot find name 'C'.
8+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,14): error TS2695: Left side of comma operator is unused and has no side effects.
9+
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts(1,14): error TS2695: Left side of comma operator is unused and has no side effects.
310

411

5-
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts (2 errors) ====
12+
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/TypeArgumentLists/TypeArgumentList1.ts (9 errors) ====
613
Foo<A,B,\ C>(4, 5, 6);
714
~~~
815
!!! error TS2304: Cannot find name 'Foo'.
16+
~~~~~
17+
!!! error TS2695: Left side of comma operator is unused and has no side effects.
18+
~~~~~~~
19+
!!! error TS2695: Left side of comma operator is unused and has no side effects.
20+
~
21+
!!! error TS2304: Cannot find name 'A'.
22+
~
23+
!!! error TS2304: Cannot find name 'B'.
924

10-
!!! error TS1127: Invalid character.
25+
!!! error TS1127: Invalid character.
26+
~
27+
!!! error TS2304: Cannot find name 'C'.
28+
~
29+
!!! error TS2695: Left side of comma operator is unused and has no side effects.
30+
~~~~
31+
!!! error TS2695: Left side of comma operator is unused and has no side effects.

tests/baselines/reference/TypeArgumentList1.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
Foo<A,B,\ C>(4, 5, 6);
33

44
//// [TypeArgumentList1.js]
5-
Foo(4, 5, 6);
5+
Foo < A, B, ;
6+
C > (4, 5, 6);

0 commit comments

Comments
 (0)