Skip to content

Commit e38a707

Browse files
committed
Merge branch 'master' into watchImprovements
2 parents 835153b + 637ed57 commit e38a707

21 files changed

+124
-152
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,8 +1272,10 @@ namespace ts {
12721272
case SyntaxKind.PropertyAccessExpression:
12731273
return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined;
12741274
case SyntaxKind.ExpressionWithTypeArguments:
1275-
Debug.assert(isEntityNameExpression((<ExpressionWithTypeArguments>node).expression));
1276-
return <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression;
1275+
if (isEntityNameExpression((<ExpressionWithTypeArguments>node).expression)) {
1276+
return <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression;
1277+
}
1278+
// falls through
12771279
default:
12781280
return undefined;
12791281
}
@@ -4917,6 +4919,8 @@ namespace ts {
49174919
*/
49184920
function getBaseConstructorTypeOfClass(type: InterfaceType): Type {
49194921
if (!type.resolvedBaseConstructorType) {
4922+
const decl = <ClassLikeDeclaration>type.symbol.valueDeclaration;
4923+
const extended = getClassExtendsHeritageClauseElement(decl);
49204924
const baseTypeNode = getBaseTypeNodeOfClass(type);
49214925
if (!baseTypeNode) {
49224926
return type.resolvedBaseConstructorType = undefinedType;
@@ -4925,6 +4929,10 @@ namespace ts {
49254929
return unknownType;
49264930
}
49274931
const baseConstructorType = checkExpression(baseTypeNode.expression);
4932+
if (extended && baseTypeNode !== extended) {
4933+
Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag
4934+
checkExpression(extended.expression);
4935+
}
49284936
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
49294937
// Resolving the members of a class requires us to resolve the base class of that class.
49304938
// We force resolution here such that we catch circularities now.
@@ -14866,6 +14874,7 @@ namespace ts {
1486614874

1486714875
function getSuggestionForNonexistentSymbol(location: Node, name: __String, meaning: SymbolFlags): string {
1486814876
const result = resolveNameHelper(location, name, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ false, (symbols, name, meaning) => {
14877+
// `name` from the callback === the outer `name`
1486914878
const symbol = getSymbol(symbols, name, meaning);
1487014879
// Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function
1487114880
// So the table *contains* `x` but `x` isn't actually in scope.
@@ -19792,7 +19801,7 @@ namespace ts {
1979219801
if (!getParameterSymbolFromJSDoc(node)) {
1979319802
error(node.name,
1979419803
Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name,
19795-
unescapeLeadingUnderscores((node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name).escapedText));
19804+
idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name));
1979619805
}
1979719806
}
1979819807

@@ -19808,9 +19817,7 @@ namespace ts {
1980819817
if (extend) {
1980919818
const className = getIdentifierFromEntityNameExpression(extend.expression);
1981019819
if (className && name.escapedText !== className.escapedText) {
19811-
error(name, Diagnostics.JSDoc_augments_0_does_not_match_the_extends_1_clause,
19812-
unescapeLeadingUnderscores(name.escapedText),
19813-
unescapeLeadingUnderscores(className.escapedText));
19820+
error(name, Diagnostics.JSDoc_augments_0_does_not_match_the_extends_1_clause, idText(name), idText(className));
1981419821
}
1981519822
}
1981619823
}

src/compiler/transformers/esnext.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ namespace ts {
378378
const catchVariable = getGeneratedNameForNode(errorRecord);
379379
const returnMethod = createTempVariable(/*recordTempVariable*/ undefined);
380380
const callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
381-
const callNext = createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, []);
381+
const callNext = createCall(createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
382382
const getDone = createPropertyAccess(result, "done");
383383
const getValue = createPropertyAccess(result, "value");
384384
const callReturn = createFunctionCall(returnMethod, iterator, []);

src/harness/fourslash.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2824,7 +2824,7 @@ Actual: ${stringify(fullActual)}`);
28242824
const refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, range);
28252825
const refactor = refactors.find(r => r.name === refactorName);
28262826
if (!refactor) {
2827-
this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.`);
2827+
this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.\nAvailable refactors: ${refactors.map(r => r.name)}`);
28282828
}
28292829

28302830
const action = refactor.actions.find(a => a.name === actionName);

src/harness/unittests/extractFunctions.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,6 @@ namespace ts {
109109
return C.foo();|]
110110
}
111111
}
112-
}`);
113-
testExtractFunction("extractFunction8",
114-
`namespace A {
115-
let x = 1;
116-
namespace B {
117-
function a() {
118-
let a1 = 1;
119-
return 1 + [#|a1 + x|] + 100;
120-
}
121-
}
122112
}`);
123113
testExtractFunction("extractFunction9",
124114
`namespace A {

src/harness/unittests/extractRanges.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,6 @@ namespace ts {
152152
}
153153
}
154154
`);
155-
testExtractRange(`
156-
function f() {
157-
return [$|1 + [#|2 + 3|]|];
158-
}
159-
}
160-
`);
161-
testExtractRange(`
162-
function f() {
163-
return [$|1 + 2 + [#|3 + 4|]|];
164-
}
165-
}
166-
`);
167155
});
168156

169157
testExtractRangeFailed("extractRangeFailed1",
@@ -311,7 +299,18 @@ switch (x) {
311299
testExtractRangeFailed("extractRangeFailed9",
312300
`var x = ([#||]1 + 2);`,
313301
[
314-
"Cannot extract empty range."
302+
refactor.extractSymbol.Messages.CannotExtractEmpty.message
303+
]);
304+
305+
testExtractRangeFailed("extractRangeFailed10",
306+
`
307+
function f() {
308+
return 1 + [#|2 + 3|];
309+
}
310+
}
311+
`,
312+
[
313+
refactor.extractSymbol.Messages.CannotExtractRange.message
315314
]);
316315

317316
testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.CannotExtractIdentifier.message]);

src/lib/es2015.core.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ interface Math {
162162
* If any argument is NaN, the result is NaN.
163163
* If all arguments are either +0 or −0, the result is +0.
164164
*/
165-
hypot(...values: number[] ): number;
165+
hypot(...values: number[]): number;
166166

167167
/**
168168
* Returns the integral part of the a numeric expression, x, removing any fractional digits.

src/server/project.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,9 +976,10 @@ namespace ts.server {
976976
// unknown version - return everything
977977
const projectFileNames = this.getFileNames();
978978
const externalFiles = this.getExternalFiles().map(f => toNormalizedPath(f));
979-
this.lastReportedFileNames = arrayToSet(projectFileNames.concat(externalFiles));
979+
const allFiles = projectFileNames.concat(externalFiles);
980+
this.lastReportedFileNames = arrayToSet(allFiles);
980981
this.lastReportedVersion = this.projectStructureVersion;
981-
return { info, files: projectFileNames, projectErrors: this.getGlobalProjectErrors() };
982+
return { info, files: allFiles, projectErrors: this.getGlobalProjectErrors() };
982983
}
983984
}
984985

src/services/formatting/rulesMap.ts

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,20 @@ namespace ts.formatting {
66
public map: RulesBucket[];
77
public mapRowLength: number;
88

9-
constructor() {
10-
this.map = [];
11-
this.mapRowLength = 0;
12-
}
13-
14-
static create(rules: Rule[]): RulesMap {
15-
const result = new RulesMap();
16-
result.Initialize(rules);
17-
return result;
18-
}
19-
20-
public Initialize(rules: Rule[]) {
9+
constructor(rules: ReadonlyArray<Rule>) {
2110
this.mapRowLength = SyntaxKind.LastToken + 1;
22-
this.map = <any>new Array(this.mapRowLength * this.mapRowLength); // new Array<RulesBucket>(this.mapRowLength * this.mapRowLength);
11+
this.map = new Array<RulesBucket>(this.mapRowLength * this.mapRowLength);
2312

2413
// This array is used only during construction of the rulesbucket in the map
25-
const rulesBucketConstructionStateList: RulesBucketConstructionState[] = <any>new Array(this.map.length); // new Array<RulesBucketConstructionState>(this.map.length);
26-
27-
this.FillRules(rules, rulesBucketConstructionStateList);
28-
return this.map;
29-
}
30-
31-
public FillRules(rules: Rule[], rulesBucketConstructionStateList: RulesBucketConstructionState[]): void {
32-
rules.forEach((rule) => {
14+
const rulesBucketConstructionStateList: RulesBucketConstructionState[] = new Array<RulesBucketConstructionState>(this.map.length);
15+
for (const rule of rules) {
3316
this.FillRule(rule, rulesBucketConstructionStateList);
34-
});
17+
}
3518
}
3619

3720
private GetRuleBucketIndex(row: number, column: number): number {
3821
Debug.assert(row <= SyntaxKind.LastKeyword && column <= SyntaxKind.LastKeyword, "Must compute formatting context from tokens");
39-
const rulesBucketIndex = (row * this.mapRowLength) + column;
40-
return rulesBucketIndex;
22+
return (row * this.mapRowLength) + column;
4123
}
4224

4325
private FillRule(rule: Rule, rulesBucketConstructionStateList: RulesBucketConstructionState[]): void {
@@ -57,7 +39,7 @@ namespace ts.formatting {
5739
});
5840
}
5941

60-
public GetRule(context: FormattingContext): Rule {
42+
public GetRule(context: FormattingContext): Rule | undefined {
6143
const bucketIndex = this.GetRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind);
6244
const bucket = this.map[bucketIndex];
6345
if (bucket) {
@@ -74,7 +56,7 @@ namespace ts.formatting {
7456
const MaskBitSize = 5;
7557
const Mask = 0x1f;
7658

77-
export enum RulesPosition {
59+
enum RulesPosition {
7860
IgnoreRulesSpecific = 0,
7961
IgnoreRulesAny = MaskBitSize * 1,
8062
ContextRulesSpecific = MaskBitSize * 2,

src/services/formatting/rulesProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace ts.formatting {
1010
constructor() {
1111
this.globalRules = new Rules();
1212
const activeRules = this.globalRules.HighPriorityCommonRules.concat(this.globalRules.UserConfigurableRules).concat(this.globalRules.LowPriorityCommonRules);
13-
this.rulesMap = RulesMap.create(activeRules);
13+
this.rulesMap = new RulesMap(activeRules);
1414
}
1515

1616
public getRulesMap() {

src/services/refactors/extractSymbol.ts

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,9 @@ namespace ts.refactor.extractSymbol {
201201

202202
// Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span.
203203
// This may fail (e.g. you select two statements in the root of a source file)
204-
let start = getParentNodeInSpan(getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span);
204+
const start = getParentNodeInSpan(getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span);
205205
// Do the same for the ending position
206-
let end = getParentNodeInSpan(findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span)), sourceFile, span);
206+
const end = getParentNodeInSpan(findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span)), sourceFile, span);
207207

208208
const declarations: Symbol[] = [];
209209

@@ -217,31 +217,10 @@ namespace ts.refactor.extractSymbol {
217217
}
218218

219219
if (start.parent !== end.parent) {
220-
// handle cases like 1 + [2 + 3] + 4
221-
// user selection is marked with [].
222-
// in this case 2 + 3 does not belong to the same tree node
223-
// instead the shape of the tree looks like this:
224-
// +
225-
// / \
226-
// + 4
227-
// / \
228-
// + 3
229-
// / \
230-
// 1 2
231-
// in this case there is no such one node that covers ends of selection and is located inside the selection
232-
// to handle this we check if both start and end of the selection belong to some binary operation
233-
// and start node is parented by the parent of the end node
234-
// if this is the case - expand the selection to the entire parent of end node (in this case it will be [1 + 2 + 3] + 4)
235-
const startParent = skipParentheses(start.parent);
236-
const endParent = skipParentheses(end.parent);
237-
if (isBinaryExpression(startParent) && isBinaryExpression(endParent) && isNodeDescendantOf(startParent, endParent)) {
238-
start = end = endParent;
239-
}
240-
else {
241-
// start and end nodes belong to different subtrees
242-
return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
243-
}
220+
// start and end nodes belong to different subtrees
221+
return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
244222
}
223+
245224
if (start !== end) {
246225
// start and end should be statements and parent should be either block or a source file
247226
if (!isBlockLike(start.parent)) {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
tests/cases/compiler/classExtendsInterface_not.ts(1,20): error TS2339: Property 'bogus' does not exist on type '""'.
2+
3+
4+
==== tests/cases/compiler/classExtendsInterface_not.ts (1 errors) ====
5+
class C extends "".bogus {}
6+
~~~~~
7+
!!! error TS2339: Property 'bogus' does not exist on type '""'.
8+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//// [classExtendsInterface_not.ts]
2+
class C extends "".bogus {}
3+
4+
5+
//// [classExtendsInterface_not.js]
6+
var __extends = (this && this.__extends) || (function () {
7+
var extendStatics = Object.setPrototypeOf ||
8+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
9+
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
10+
return function (d, b) {
11+
extendStatics(d, b);
12+
function __() { this.constructor = d; }
13+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14+
};
15+
})();
16+
var C = /** @class */ (function (_super) {
17+
__extends(C, _super);
18+
function C() {
19+
return _super !== null && _super.apply(this, arguments) || this;
20+
}
21+
return C;
22+
}("".bogus));
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== tests/cases/compiler/classExtendsInterface_not.ts ===
2+
class C extends "".bogus {}
3+
>C : Symbol(C, Decl(classExtendsInterface_not.ts, 0, 0))
4+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
=== tests/cases/compiler/classExtendsInterface_not.ts ===
2+
class C extends "".bogus {}
3+
>C : C
4+
>"".bogus : any
5+
>"" : ""
6+
>bogus : any
7+

tests/baselines/reference/extractFunction/extractFunction8.ts

Lines changed: 0 additions & 65 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/a.js(3,17): error TS2304: Cannot find name 'err'.
2+
3+
4+
==== /a.js (1 errors) ====
5+
class A {}
6+
/** @augments A */
7+
class B extends err() {}
8+
~~~
9+
!!! error TS2304: Cannot find name 'err'.
10+

0 commit comments

Comments
 (0)