Skip to content

Commit 9f25d82

Browse files
author
Andy Hanson
committed
Merge branch 'master' into completionsJsxAttributeInitializer
2 parents 8486bf2 + 0b7f6d5 commit 9f25d82

File tree

81 files changed

+1404
-297
lines changed

Some content is hidden

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

81 files changed

+1404
-297
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "typescript",
33
"author": "Microsoft Corp.",
44
"homepage": "http://typescriptlang.org/",
5-
"version": "2.7.0",
5+
"version": "2.8.0",
66
"license": "Apache-2.0",
77
"description": "TypeScript is a language for application scale JavaScript development",
88
"keywords": [

src/compiler/checker.ts

+13-10
Original file line numberDiff line numberDiff line change
@@ -2424,12 +2424,15 @@ namespace ts {
24242424
const visitedSymbolTables: SymbolTable[] = [];
24252425
return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
24262426

2427-
function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable): Symbol[] | undefined {
2427+
/**
2428+
* @param {ignoreQualification} boolean Set when a symbol is being looked for through the exports of another symbol (meaning we have a route to qualify it already)
2429+
*/
2430+
function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable, ignoreQualification?: boolean): Symbol[] | undefined {
24282431
if (!pushIfUnique(visitedSymbolTables, symbols)) {
24292432
return undefined;
24302433
}
24312434

2432-
const result = trySymbolTable(symbols);
2435+
const result = trySymbolTable(symbols, ignoreQualification);
24332436
visitedSymbolTables.pop();
24342437
return result;
24352438
}
@@ -2441,22 +2444,22 @@ namespace ts {
24412444
!!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing);
24422445
}
24432446

2444-
function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol) {
2447+
function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol, ignoreQualification?: boolean) {
24452448
return symbol === (resolvedAliasSymbol || symbolFromSymbolTable) &&
24462449
// if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
24472450
// and if symbolFromSymbolTable or alias resolution matches the symbol,
24482451
// check the symbol can be qualified, it is only then this symbol is accessible
24492452
!some(symbolFromSymbolTable.declarations, hasExternalModuleSymbol) &&
2450-
canQualifySymbol(symbolFromSymbolTable, meaning);
2453+
(ignoreQualification || canQualifySymbol(symbolFromSymbolTable, meaning));
24512454
}
24522455

24532456
function isUMDExportSymbol(symbol: Symbol) {
24542457
return symbol && symbol.declarations && symbol.declarations[0] && isNamespaceExportDeclaration(symbol.declarations[0]);
24552458
}
24562459

2457-
function trySymbolTable(symbols: SymbolTable) {
2460+
function trySymbolTable(symbols: SymbolTable, ignoreQualification: boolean | undefined) {
24582461
// If symbol is directly available by its name in the symbol table
2459-
if (isAccessible(symbols.get(symbol.escapedName))) {
2462+
if (isAccessible(symbols.get(symbol.escapedName), /*resolvedAliasSymbol*/ undefined, ignoreQualification)) {
24602463
return [symbol];
24612464
}
24622465

@@ -2469,14 +2472,14 @@ namespace ts {
24692472
&& (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration))) {
24702473

24712474
const resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
2472-
if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol)) {
2475+
if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification)) {
24732476
return [symbolFromSymbolTable];
24742477
}
24752478

24762479
// Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
24772480
// but only if the symbolFromSymbolTable can be qualified
24782481
const candidateTable = getExportsOfSymbol(resolvedImportedSymbol);
2479-
const accessibleSymbolsFromExports = candidateTable && getAccessibleSymbolChainFromSymbolTable(candidateTable);
2482+
const accessibleSymbolsFromExports = candidateTable && getAccessibleSymbolChainFromSymbolTable(candidateTable, /*ignoreQualification*/ true);
24802483
if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
24812484
return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
24822485
}
@@ -16717,7 +16720,7 @@ namespace ts {
1671716720
const isDecorator = node.kind === SyntaxKind.Decorator;
1671816721
const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
1671916722

16720-
let typeArguments: ReadonlyArray<TypeNode>;
16723+
let typeArguments: NodeArray<TypeNode>;
1672116724

1672216725
if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) {
1672316726
typeArguments = (<CallExpression>node).typeArguments;
@@ -16846,7 +16849,7 @@ namespace ts {
1684616849
max = Math.max(max, length(sig.typeParameters));
1684716850
}
1684816851
const paramCount = min < max ? min + "-" + max : min;
16849-
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length));
16852+
diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length));
1685016853
}
1685116854
else if (args) {
1685216855
let min = Number.POSITIVE_INFINITY;

src/compiler/core.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace ts {
55
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
66
// If changing the text in this section, be sure to test `configureNightly` too.
7-
export const versionMajorMinor = "2.7";
7+
export const versionMajorMinor = "2.8";
88
/** The version of the TypeScript compiler release */
99
export const version = `${versionMajorMinor}.0`;
1010
}
@@ -340,6 +340,10 @@ namespace ts {
340340
return false;
341341
}
342342

343+
export function arraysEqual<T>(a: ReadonlyArray<T>, b: ReadonlyArray<T>, equalityComparer: EqualityComparer<T> = equateValues): boolean {
344+
return a.length === b.length && a.every((x, i) => equalityComparer(x, b[i]));
345+
}
346+
343347
export function indexOfAnyCharCode(text: string, charCodes: ReadonlyArray<number>, start?: number): number {
344348
for (let i = start || 0; i < text.length; i++) {
345349
if (contains(charCodes, text.charCodeAt(i))) {

src/compiler/scanner.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,10 @@ namespace ts {
335335

336336
/* @internal */
337337
export function computePositionOfLineAndCharacter(lineStarts: ReadonlyArray<number>, line: number, character: number, debugText?: string): number {
338-
Debug.assert(line >= 0 && line < lineStarts.length);
338+
if (line < 0 || line >= lineStarts.length) {
339+
Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`);
340+
}
341+
339342
const res = lineStarts[line] + character;
340343
if (line < lineStarts.length - 1) {
341344
Debug.assert(res < lineStarts[line + 1]);

src/compiler/transformers/esnext.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ namespace ts {
148148
}
149149

150150
function visitLabeledStatement(node: LabeledStatement) {
151-
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) {
151+
if (enclosingFunctionFlags & FunctionFlags.Async) {
152152
const statement = unwrapInnermostStatementOfLabel(node);
153153
if (statement.kind === SyntaxKind.ForOfStatement && (<ForOfStatement>statement).awaitModifier) {
154154
return visitForOfStatement(<ForOfStatement>statement, node);

src/compiler/utilities.ts

+5
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,11 @@ namespace ts {
599599
return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3);
600600
}
601601

602+
export function createDiagnosticForNodeArray(sourceFile: SourceFile, nodes: NodeArray<Node>, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic {
603+
const start = skipTrivia(sourceFile.text, nodes.pos);
604+
return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2, arg3);
605+
}
606+
602607
export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic {
603608
const span = getErrorSpanForNode(sourceFile, node);
604609
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3);

src/harness/fourslash.ts

+17-34
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace FourSlash {
2323
ts.disableIncrementalParsing = false;
2424

2525
// Represents a parsed source file with metadata
26-
export interface FourSlashFile {
26+
interface FourSlashFile {
2727
// The contents of the file (with markers, etc stripped out)
2828
content: string;
2929
fileName: string;
@@ -34,7 +34,7 @@ namespace FourSlash {
3434
}
3535

3636
// Represents a set of parsed source files and options
37-
export interface FourSlashData {
37+
interface FourSlashData {
3838
// Global options (name/value pairs)
3939
globalOptions: Harness.TestCaseParser.CompilerSettings;
4040

@@ -59,7 +59,7 @@ namespace FourSlash {
5959
export interface Marker {
6060
fileName: string;
6161
position: number;
62-
data?: any;
62+
data?: {};
6363
}
6464

6565
export interface Range {
@@ -89,21 +89,6 @@ namespace FourSlash {
8989
end: number;
9090
}
9191

92-
export import IndentStyle = ts.IndentStyle;
93-
94-
const entityMap = ts.createMapFromTemplate({
95-
"&": "&amp;",
96-
"\"": "&quot;",
97-
"'": "&#39;",
98-
"/": "&#47;",
99-
"<": "&lt;",
100-
">": "&gt;"
101-
});
102-
103-
export function escapeXmlAttributeValue(s: string) {
104-
return s.replace(/[&<>"'\/]/g, ch => entityMap.get(ch));
105-
}
106-
10792
// Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions
10893
// To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames
10994
// Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data
@@ -1079,7 +1064,7 @@ namespace FourSlash {
10791064
for (const reference of expectedReferences) {
10801065
const { fileName, start, end } = reference;
10811066
if (reference.marker && reference.marker.data) {
1082-
const { isWriteAccess, isDefinition } = reference.marker.data;
1067+
const { isWriteAccess, isDefinition } = reference.marker.data as { isWriteAccess?: boolean, isDefinition?: boolean };
10831068
this.verifyReferencesWorker(actualReferences, fileName, start, end, isWriteAccess, isDefinition);
10841069
}
10851070
else {
@@ -1108,7 +1093,16 @@ namespace FourSlash {
11081093
}
11091094
const fullExpected = ts.map<FourSlashInterface.ReferenceGroup, ReferenceGroupJson>(parts, ({ definition, ranges }) => ({
11101095
definition: typeof definition === "string" ? definition : { ...definition, range: textSpanFromRange(definition.range) },
1111-
references: ranges.map(rangeToReferenceEntry),
1096+
references: ranges.map<ts.ReferenceEntry>(r => {
1097+
const { isWriteAccess = false, isDefinition = false, isInString } = (r.marker && r.marker.data || {}) as { isWriteAccess?: boolean, isDefinition?: boolean, isInString?: true };
1098+
return {
1099+
isWriteAccess,
1100+
isDefinition,
1101+
fileName: r.fileName,
1102+
textSpan: textSpanFromRange(r),
1103+
...(isInString ? { isInString: true } : undefined),
1104+
};
1105+
}),
11121106
}));
11131107

11141108
for (const startRange of toArray(startRanges)) {
@@ -1122,15 +1116,6 @@ namespace FourSlash {
11221116
});
11231117
this.assertObjectsEqual(fullActual, fullExpected);
11241118
}
1125-
1126-
function rangeToReferenceEntry(r: Range): ts.ReferenceEntry {
1127-
const { isWriteAccess, isDefinition, isInString } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false, isInString: undefined };
1128-
const result: ts.ReferenceEntry = { fileName: r.fileName, textSpan: textSpanFromRange(r), isWriteAccess: !!isWriteAccess, isDefinition: !!isDefinition };
1129-
if (isInString !== undefined) {
1130-
result.isInString = isInString;
1131-
}
1132-
return result;
1133-
}
11341119
}
11351120

11361121
public verifyNoReferences(markerNameOrRange?: string | Range) {
@@ -2587,12 +2572,10 @@ Actual: ${stringify(fullActual)}`);
25872572
actualTextArray.push(text);
25882573
scriptInfo.updateContent(originalContent);
25892574
}
2590-
const sortedExpectedArray = expectedTextArray.sort();
2591-
const sortedActualArray = actualTextArray.sort();
2592-
if (sortedExpectedArray.length !== sortedActualArray.length) {
2593-
this.raiseError(`Expected ${sortedExpectedArray.length} import fixes, got ${sortedActualArray.length}`);
2575+
if (expectedTextArray.length !== actualTextArray.length) {
2576+
this.raiseError(`Expected ${expectedTextArray.length} import fixes, got ${actualTextArray.length}`);
25942577
}
2595-
ts.zipWith(sortedExpectedArray, sortedActualArray, (expected, actual, index) => {
2578+
ts.zipWith(expectedTextArray, actualTextArray, (expected, actual, index) => {
25962579
if (expected !== actual) {
25972580
this.raiseError(`Import fix at index ${index} doesn't match.\n${showTextDiff(expected, actual)}`);
25982581
}

src/harness/unittests/extractConstants.ts

+7
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,13 @@ let i: I = [#|{ a: 1 }|];
273273
const myObj: { member(x: number, y: string): void } = {
274274
member: [#|(x, y) => x + y|],
275275
}
276+
`);
277+
278+
testExtractConstant("extractConstant_CaseClauseExpression", `
279+
switch (1) {
280+
case [#|1|]:
281+
break;
282+
}
276283
`);
277284
});
278285

src/harness/unittests/extractRanges.ts

+52
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,58 @@ switch (x) {
365365
refactor.extractSymbol.Messages.cannotExtractRange.message
366366
]);
367367

368+
testExtractRangeFailed("extractRangeFailed14",
369+
`
370+
switch(1) {
371+
case [#|1:
372+
break;|]
373+
}
374+
`,
375+
[
376+
refactor.extractSymbol.Messages.cannotExtractRange.message
377+
]);
378+
379+
testExtractRangeFailed("extractRangeFailed15",
380+
`
381+
switch(1) {
382+
case [#|1:
383+
break|];
384+
}
385+
`,
386+
[
387+
refactor.extractSymbol.Messages.cannotExtractRange.message
388+
]);
389+
390+
// Documentation only - it would be nice if the result were [$|1|]
391+
testExtractRangeFailed("extractRangeFailed16",
392+
`
393+
switch(1) {
394+
[#|case 1|]:
395+
break;
396+
}
397+
`,
398+
[
399+
refactor.extractSymbol.Messages.cannotExtractRange.message
400+
]);
401+
402+
// Documentation only - it would be nice if the result were [$|1|]
403+
testExtractRangeFailed("extractRangeFailed17",
404+
`
405+
switch(1) {
406+
[#|case 1:|]
407+
break;
408+
}
409+
`,
410+
[
411+
refactor.extractSymbol.Messages.cannotExtractRange.message
412+
]);
413+
414+
testExtractRangeFailed("extractRangeFailed18",
415+
`[#|{ 1;|] }`,
416+
[
417+
refactor.extractSymbol.Messages.cannotExtractRange.message
418+
]);
419+
368420
testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.cannotExtractIdentifier.message]);
369421
});
370422
}

src/harness/unittests/tsserverProjectSystem.ts

+39
Original file line numberDiff line numberDiff line change
@@ -2846,6 +2846,45 @@ namespace ts.projectSystem {
28462846
const options = project.getCompilerOptions();
28472847
assert.equal(options.outDir, "C:/a/b", "");
28482848
});
2849+
2850+
it("dynamic file without external project", () => {
2851+
const file: FileOrFolder = {
2852+
path: "^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js",
2853+
content: "var x = 10;"
2854+
};
2855+
const host = createServerHost([libFile], { useCaseSensitiveFileNames: true });
2856+
const projectService = createProjectService(host);
2857+
projectService.setCompilerOptionsForInferredProjects({
2858+
module: ModuleKind.CommonJS,
2859+
allowJs: true,
2860+
allowSyntheticDefaultImports: true,
2861+
allowNonTsExtensions: true
2862+
});
2863+
projectService.openClientFile(file.path, "var x = 10;");
2864+
2865+
projectService.checkNumberOfProjects({ inferredProjects: 1 });
2866+
const project = projectService.inferredProjects[0];
2867+
checkProjectRootFiles(project, [file.path]);
2868+
checkProjectActualFiles(project, [file.path, libFile.path]);
2869+
2870+
assert.strictEqual(projectService.getDefaultProjectForFile(server.toNormalizedPath(file.path), /*ensureProject*/ true), project);
2871+
const indexOfX = file.content.indexOf("x");
2872+
assert.deepEqual(project.getLanguageService(/*ensureSynchronized*/ true).getQuickInfoAtPosition(file.path, indexOfX), {
2873+
kind: ScriptElementKind.variableElement,
2874+
kindModifiers: "",
2875+
textSpan: { start: indexOfX, length: 1 },
2876+
displayParts: [
2877+
{ text: "var", kind: "keyword" },
2878+
{ text: " ", kind: "space" },
2879+
{ text: "x", kind: "localName" },
2880+
{ text: ":", kind: "punctuation" },
2881+
{ text: " ", kind: "space" },
2882+
{ text: "number", kind: "keyword" }
2883+
],
2884+
documentation: [],
2885+
tags: []
2886+
});
2887+
});
28492888
});
28502889

28512890
describe("tsserverProjectSystem Proper errors", () => {

src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<Cmt Name="LcxAdmin" />
1515
<Cmt Name="Loc" />
1616
<Cmt Name="Note" />
17-
<Cmt Name="Rccx" />
17+
<Cmt Name="RCCX" />
1818
</OwnedComments>
1919
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
2020
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">

src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<Cmt Name="LcxAdmin" />
1515
<Cmt Name="Loc" />
1616
<Cmt Name="Note" />
17-
<Cmt Name="Rccx" />
17+
<Cmt Name="RCCX" />
1818
</OwnedComments>
1919
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
2020
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">

src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<Cmt Name="ManifestData" />
2020
<Cmt Name="Mnemonic" />
2121
<Cmt Name="Note" />
22-
<Cmt Name="Rccx" />
22+
<Cmt Name="RCCX" />
2323
<Cmt Name="UIType" />
2424
<Cmt Name="UTSData" />
2525
<Cmt Name="UTSUI" />

0 commit comments

Comments
 (0)