Skip to content

Commit 40e9e85

Browse files
Merge branch 'master' into excessPropCorrection
2 parents a1ad389 + b217d96 commit 40e9e85

Some content is hidden

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

48 files changed

+907
-267
lines changed

.npmignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ Jakefile.js
1616
.gitattributes
1717
.settings/
1818
.travis.yml
19-
.vscode/
19+
.vscode/
20+
test.config

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ matrix:
1616
branches:
1717
only:
1818
- master
19+
- release-2.5
1920

2021
install:
2122
- npm uninstall typescript --no-save

netci.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ nodeVersions.each { nodeVer ->
1717
}
1818

1919
Utilities.standardJobSetup(newJob, project, true, "*/${branch}")
20-
Utilities.setMachineAffinity(newJob, 'Ubuntu', '20161020')
20+
Utilities.setMachineAffinity(newJob, 'Ubuntu14.04', '20170821-1')
2121
Utilities.addGithubPRTriggerForBranch(newJob, branch, "TypeScript Test Run ${newJobName}")
2222
}

scripts/buildProtocol.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,23 @@ function endsWith(s: string, suffix: string) {
77
return s.lastIndexOf(suffix, s.length - suffix.length) !== -1;
88
}
99

10+
function isStringEnum(declaration: ts.EnumDeclaration) {
11+
return declaration.members.length && declaration.members.every(m => m.initializer && m.initializer.kind === ts.SyntaxKind.StringLiteral);
12+
}
13+
1014
class DeclarationsWalker {
1115
private visitedTypes: ts.Type[] = [];
1216
private text = "";
1317
private removedTypes: ts.Type[] = [];
14-
18+
1519
private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
1620
}
1721

1822
static getExtraDeclarations(typeChecker: ts.TypeChecker, protocolFile: ts.SourceFile): string {
1923
let text = "declare namespace ts.server.protocol {\n";
2024
var walker = new DeclarationsWalker(typeChecker, protocolFile);
2125
walker.visitTypeNodes(protocolFile);
22-
text = walker.text
26+
text = walker.text
2327
? `declare namespace ts.server.protocol {\n${walker.text}}`
2428
: "";
2529
if (walker.removedTypes) {
@@ -52,7 +56,7 @@ class DeclarationsWalker {
5256
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
5357
return;
5458
}
55-
if (decl.kind === ts.SyntaxKind.EnumDeclaration) {
59+
if (decl.kind === ts.SyntaxKind.EnumDeclaration && !isStringEnum(decl as ts.EnumDeclaration)) {
5660
this.removedTypes.push(type);
5761
return;
5862
}
@@ -91,7 +95,7 @@ class DeclarationsWalker {
9195
for (const type of heritageClauses[0].types) {
9296
this.processTypeOfNode(type);
9397
}
94-
}
98+
}
9599
break;
96100
}
97101
}
@@ -110,7 +114,7 @@ class DeclarationsWalker {
110114
this.processType(type);
111115
}
112116
}
113-
}
117+
}
114118
}
115119

116120
function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptServicesDts: string) {

src/compiler/checker.ts

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,18 @@ namespace ts {
10161016
}
10171017
}
10181018
break;
1019-
1019+
case SyntaxKind.ExpressionWithTypeArguments:
1020+
// The type parameters of a class are not in scope in the base class expression.
1021+
if (lastLocation === (<ExpressionWithTypeArguments>location).expression && (<HeritageClause>location.parent).token === SyntaxKind.ExtendsKeyword) {
1022+
const container = location.parent.parent;
1023+
if (isClassLike(container) && (result = lookup(getSymbolOfNode(container).members, name, meaning & SymbolFlags.Type))) {
1024+
if (nameNotFoundMessage) {
1025+
error(errorLocation, Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters);
1026+
}
1027+
return undefined;
1028+
}
1029+
}
1030+
break;
10201031
// It is not legal to reference a class's own type parameters from a computed property name that
10211032
// belongs to the class. For example:
10221033
//
@@ -4929,7 +4940,7 @@ namespace ts {
49294940
}
49304941

49314942
function resolveBaseTypesOfClass(type: InterfaceType): void {
4932-
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
4943+
type.resolvedBaseTypes = emptyArray;
49334944
const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
49344945
if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.Any))) {
49354946
return;
@@ -4976,17 +4987,12 @@ namespace ts {
49764987
error(baseTypeNode.expression, Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType));
49774988
return;
49784989
}
4979-
if (type === baseType || hasBaseType(<BaseType>baseType, type)) {
4990+
if (type === baseType || hasBaseType(baseType, type)) {
49804991
error(valueDecl, Diagnostics.Type_0_recursively_references_itself_as_a_base_type,
49814992
typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType));
49824993
return;
49834994
}
4984-
if (type.resolvedBaseTypes === emptyArray) {
4985-
type.resolvedBaseTypes = [<ObjectType>baseType];
4986-
}
4987-
else {
4988-
type.resolvedBaseTypes.push(<ObjectType>baseType);
4989-
}
4995+
type.resolvedBaseTypes = [baseType];
49904996
}
49914997

49924998
function areAllOuterTypeParametersApplied(type: Type): boolean {
@@ -5003,7 +5009,7 @@ namespace ts {
50035009

50045010
// A valid base type is `any`, any non-generic object type or intersection of non-generic
50055011
// object types.
5006-
function isValidBaseType(type: Type): boolean {
5012+
function isValidBaseType(type: Type): type is BaseType {
50075013
return type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.Any) && !isGenericMappedType(type) ||
50085014
type.flags & TypeFlags.Intersection && !forEach((<IntersectionType>type).types, t => !isValidBaseType(t));
50095015
}
@@ -5016,12 +5022,12 @@ namespace ts {
50165022
const baseType = getTypeFromTypeNode(node);
50175023
if (baseType !== unknownType) {
50185024
if (isValidBaseType(baseType)) {
5019-
if (type !== baseType && !hasBaseType(<BaseType>baseType, type)) {
5025+
if (type !== baseType && !hasBaseType(baseType, type)) {
50205026
if (type.resolvedBaseTypes === emptyArray) {
50215027
type.resolvedBaseTypes = [<ObjectType>baseType];
50225028
}
50235029
else {
5024-
type.resolvedBaseTypes.push(<ObjectType>baseType);
5030+
type.resolvedBaseTypes.push(baseType);
50255031
}
50265032
}
50275033
else {
@@ -5657,17 +5663,12 @@ namespace ts {
56575663
else {
56585664
// Combinations of function, class, enum and module
56595665
let members = emptySymbols;
5660-
let constructSignatures: Signature[] = emptyArray;
56615666
let stringIndexInfo: IndexInfo = undefined;
56625667
if (symbol.exports) {
56635668
members = getExportsOfSymbol(symbol);
56645669
}
56655670
if (symbol.flags & SymbolFlags.Class) {
56665671
const classType = getDeclaredTypeOfClassOrInterface(symbol);
5667-
constructSignatures = getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor));
5668-
if (!constructSignatures.length) {
5669-
constructSignatures = getDefaultConstructSignatures(classType);
5670-
}
56715672
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
56725673
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) {
56735674
members = createSymbolTable(getNamedMembers(members));
@@ -5678,14 +5679,23 @@ namespace ts {
56785679
}
56795680
}
56805681
const numberIndexInfo = symbol.flags & SymbolFlags.Enum ? enumNumberIndexInfo : undefined;
5681-
setStructuredTypeMembers(type, members, emptyArray, constructSignatures, stringIndexInfo, numberIndexInfo);
5682+
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
56825683
// We resolve the members before computing the signatures because a signature may use
56835684
// typeof with a qualified name expression that circularly references the type we are
56845685
// in the process of resolving (see issue #6072). The temporarily empty signature list
56855686
// will never be observed because a qualified name can't reference signatures.
56865687
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
56875688
(<ResolvedType>type).callSignatures = getSignaturesOfSymbol(symbol);
56885689
}
5690+
// And likewise for construct signatures for classes
5691+
if (symbol.flags & SymbolFlags.Class) {
5692+
const classType = getDeclaredTypeOfClassOrInterface(symbol);
5693+
let constructSignatures = getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor));
5694+
if (!constructSignatures.length) {
5695+
constructSignatures = getDefaultConstructSignatures(classType);
5696+
}
5697+
(<ResolvedType>type).constructSignatures = constructSignatures;
5698+
}
56895699
}
56905700
}
56915701

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,6 +1916,10 @@
19161916
"category": "Error",
19171917
"code": 2561
19181918
},
1919+
"Base class expressions cannot reference class type parameters.": {
1920+
"category": "Error",
1921+
"code": 2562
1922+
},
19191923
"JSX element attributes type '{0}' may not be a union type.": {
19201924
"category": "Error",
19211925
"code": 2600

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ namespace ts {
647647
}
648648

649649
export function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode: SourceFile) {
650-
return getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
650+
return node.kind !== SyntaxKind.JsxText ? getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined;
651651
}
652652

653653
export function getJSDocCommentRanges(node: Node, text: string) {

src/harness/fourslash.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2508,6 +2508,23 @@ namespace FourSlash {
25082508
}
25092509
}
25102510

2511+
public verifySpanOfEnclosingComment(negative: boolean, onlyMultiLineDiverges?: boolean) {
2512+
const expected = !negative;
2513+
const position = this.currentCaretPosition;
2514+
const fileName = this.activeFile.fileName;
2515+
const actual = !!this.languageService.getSpanOfEnclosingComment(fileName, position, /*onlyMultiLine*/ false);
2516+
const actualOnlyMultiLine = !!this.languageService.getSpanOfEnclosingComment(fileName, position, /*onlyMultiLine*/ true);
2517+
if (expected !== actual || onlyMultiLineDiverges === (actual === actualOnlyMultiLine)) {
2518+
this.raiseError(`verifySpanOfEnclosingComment failed:
2519+
position: '${position}'
2520+
fileName: '${fileName}'
2521+
onlyMultiLineDiverges: '${onlyMultiLineDiverges}'
2522+
actual: '${actual}'
2523+
actualOnlyMultiLine: '${actualOnlyMultiLine}'
2524+
expected: '${expected}'.`);
2525+
}
2526+
}
2527+
25112528
/*
25122529
Check number of navigationItems which match both searchValue and matchKind,
25132530
if a filename is passed in, limit the results to that file.
@@ -3648,6 +3665,10 @@ namespace FourSlashInterface {
36483665
this.state.verifyBraceCompletionAtPosition(this.negative, openingBrace);
36493666
}
36503667

3668+
public isInCommentAtPosition(onlyMultiLineDiverges?: boolean) {
3669+
this.state.verifySpanOfEnclosingComment(this.negative, onlyMultiLineDiverges);
3670+
}
3671+
36513672
public codeFixAvailable() {
36523673
this.state.verifyCodeFixAvailable(this.negative);
36533674
}

src/harness/harnessLanguageService.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,9 @@ namespace Harness.LanguageService {
487487
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
488488
return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace));
489489
}
490+
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan {
491+
return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine));
492+
}
490493
getCodeFixesAtPosition(): ts.CodeAction[] {
491494
throw new Error("Not supported on the shim.");
492495
}
@@ -686,7 +689,7 @@ namespace Harness.LanguageService {
686689
this.host.log(message);
687690
}
688691

689-
err(message: string): void {
692+
msg(message: string): void {
690693
this.host.log(message);
691694
}
692695

@@ -702,7 +705,8 @@ namespace Harness.LanguageService {
702705
return false;
703706
}
704707

705-
group() { throw ts.notImplemented(); }
708+
startGroup() { throw ts.notImplemented(); }
709+
endGroup() { throw ts.notImplemented(); }
706710

707711
perftrc(message: string): void {
708712
return this.host.log(message);

src/harness/rwcRunner.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,16 @@ namespace RWC {
9090
ts.setConfigFileInOptions(opts.options, configParseResult.options.configFile);
9191
}
9292

93-
// Load the files
93+
// Deduplicate files so they are only printed once in baselines (they are deduplicated within the compiler already)
94+
const uniqueNames = ts.createMap<true>();
9495
for (const fileName of fileNames) {
95-
inputFiles.push(getHarnessCompilerInputUnit(fileName));
96+
// Must maintain order, build result list while checking map
97+
const normalized = ts.normalizeSlashes(fileName);
98+
if (!uniqueNames.has(normalized)) {
99+
uniqueNames.set(normalized, true);
100+
// Load the file
101+
inputFiles.push(getHarnessCompilerInputUnit(fileName));
102+
}
96103
}
97104

98105
// Add files to compilation

0 commit comments

Comments
 (0)