Merge branch 'master' into jsdoc-errors-become-semantic-errors
This commit is contained in:
commit
edf9f02bdd
|
@ -394,6 +394,14 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
export function mapIterator<T, U>(iter: Iterator<T>, mapFn: (x: T) => U): Iterator<U> {
|
||||
return { next };
|
||||
function next(): { value: U, done: false } | { value: never, done: true } {
|
||||
const iterRes = iter.next();
|
||||
return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false };
|
||||
}
|
||||
}
|
||||
|
||||
// Maps from T to T and avoids allocation if all elements map to themselves
|
||||
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[];
|
||||
export function sameMap<T>(array: ReadonlyArray<T>, f: (x: T, i: number) => T): ReadonlyArray<T>;
|
||||
|
@ -917,6 +925,36 @@ namespace ts {
|
|||
return array.slice().sort(comparer);
|
||||
}
|
||||
|
||||
export function best<T>(iter: Iterator<T>, isBetter: (a: T, b: T) => boolean): T | undefined {
|
||||
const x = iter.next();
|
||||
if (x.done) {
|
||||
return undefined;
|
||||
}
|
||||
let best = x.value;
|
||||
while (true) {
|
||||
const { value, done } = iter.next();
|
||||
if (done) {
|
||||
return best;
|
||||
}
|
||||
if (isBetter(value, best)) {
|
||||
best = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function arrayIterator<T>(array: ReadonlyArray<T>): Iterator<T> {
|
||||
let i = 0;
|
||||
return { next: () => {
|
||||
if (i === array.length) {
|
||||
return { value: undefined as never, done: true };
|
||||
}
|
||||
else {
|
||||
i++;
|
||||
return { value: array[i - 1], done: false };
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stable sort of an array. Elements equal to each other maintain their relative position in the array.
|
||||
*/
|
||||
|
@ -1324,6 +1362,12 @@ namespace ts {
|
|||
return Array.isArray ? Array.isArray(value) : value instanceof Array;
|
||||
}
|
||||
|
||||
export function toArray<T>(value: T | ReadonlyArray<T>): ReadonlyArray<T>;
|
||||
export function toArray<T>(value: T | T[]): T[];
|
||||
export function toArray<T>(value: T | T[]): T[] {
|
||||
return isArray(value) ? value : [value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a value is string
|
||||
*/
|
||||
|
|
|
@ -4724,6 +4724,10 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.BreakStatement;
|
||||
}
|
||||
|
||||
export function isBreakOrContinueStatement(node: Node): node is BreakOrContinueStatement {
|
||||
return node.kind === SyntaxKind.BreakStatement || node.kind === SyntaxKind.ContinueStatement;
|
||||
}
|
||||
|
||||
export function isReturnStatement(node: Node): node is ReturnStatement {
|
||||
return node.kind === SyntaxKind.ReturnStatement;
|
||||
}
|
||||
|
|
|
@ -210,6 +210,8 @@ namespace ts.projectSystem {
|
|||
|
||||
class TestSession extends server.Session {
|
||||
private seq = 0;
|
||||
public events: protocol.Event[] = [];
|
||||
public host: TestServerHost;
|
||||
|
||||
getProjectService() {
|
||||
return this.projectService;
|
||||
|
@ -229,6 +231,16 @@ namespace ts.projectSystem {
|
|||
request.type = "request";
|
||||
return this.executeCommand(<T>request);
|
||||
}
|
||||
|
||||
public event<T>(body: T, eventName: string) {
|
||||
this.events.push(server.toEvent(eventName, body));
|
||||
super.event(body, eventName);
|
||||
}
|
||||
|
||||
public clearMessages() {
|
||||
clear(this.events);
|
||||
this.host.clearOutput();
|
||||
}
|
||||
}
|
||||
|
||||
export function createSession(host: server.ServerHost, opts: Partial<server.SessionOptions> = {}) {
|
||||
|
@ -436,48 +448,29 @@ namespace ts.projectSystem {
|
|||
verifyDiagnostics(actual, []);
|
||||
}
|
||||
|
||||
function assertEvent(actualOutput: string, expectedEvent: protocol.Event, host: TestServerHost) {
|
||||
assert.equal(actualOutput, server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, host.newLine));
|
||||
function checkErrorMessage(session: TestSession, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) {
|
||||
checkNthEvent(session, ts.server.toEvent(eventName, diagnostics), 0, /*isMostRecent*/ false);
|
||||
}
|
||||
|
||||
function checkErrorMessage(host: TestServerHost, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) {
|
||||
const outputs = host.getOutput();
|
||||
assert.isTrue(outputs.length >= 1, outputs.toString());
|
||||
const event: protocol.Event = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: eventName,
|
||||
body: diagnostics
|
||||
};
|
||||
assertEvent(outputs[0], event, host);
|
||||
function checkCompleteEvent(session: TestSession, numberOfCurrentEvents: number, expectedSequenceId: number) {
|
||||
checkNthEvent(session, ts.server.toEvent("requestCompleted", { request_seq: expectedSequenceId }), numberOfCurrentEvents - 1, /*isMostRecent*/ true);
|
||||
}
|
||||
|
||||
function checkCompleteEvent(host: TestServerHost, numberOfCurrentEvents: number, expectedSequenceId: number) {
|
||||
const outputs = host.getOutput();
|
||||
assert.equal(outputs.length, numberOfCurrentEvents, outputs.toString());
|
||||
const event: protocol.RequestCompletedEvent = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: "requestCompleted",
|
||||
body: {
|
||||
request_seq: expectedSequenceId
|
||||
}
|
||||
};
|
||||
assertEvent(outputs[numberOfCurrentEvents - 1], event, host);
|
||||
function checkProjectUpdatedInBackgroundEvent(session: TestSession, openFiles: string[]) {
|
||||
checkNthEvent(session, ts.server.toEvent("projectsUpdatedInBackground", { openFiles }), 0, /*isMostRecent*/ true);
|
||||
}
|
||||
|
||||
function checkProjectUpdatedInBackgroundEvent(host: TestServerHost, openFiles: string[]) {
|
||||
const outputs = host.getOutput();
|
||||
assert.equal(outputs.length, 1, outputs.toString());
|
||||
const event: protocol.ProjectsUpdatedInBackgroundEvent = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: "projectsUpdatedInBackground",
|
||||
body: {
|
||||
openFiles
|
||||
}
|
||||
};
|
||||
assertEvent(outputs[0], event, host);
|
||||
function checkNthEvent(session: TestSession, expectedEvent: protocol.Event, index: number, isMostRecent: boolean) {
|
||||
const events = session.events;
|
||||
assert.deepEqual(events[index], expectedEvent);
|
||||
|
||||
const outputs = session.host.getOutput();
|
||||
assert.equal(outputs[index], server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, session.host.newLine));
|
||||
|
||||
if (isMostRecent) {
|
||||
assert.strictEqual(events.length, index + 1, JSON.stringify(events));
|
||||
assert.strictEqual(outputs.length, index + 1, JSON.stringify(outputs));
|
||||
}
|
||||
}
|
||||
|
||||
describe("tsserverProjectSystem", () => {
|
||||
|
@ -2891,14 +2884,14 @@ namespace ts.projectSystem {
|
|||
|
||||
assert.isFalse(hasError);
|
||||
host.checkTimeoutQueueLength(2);
|
||||
checkErrorMessage(host, "syntaxDiag", { file: untitledFile, diagnostics: [] });
|
||||
host.clearOutput();
|
||||
checkErrorMessage(session, "syntaxDiag", { file: untitledFile, diagnostics: [] });
|
||||
session.clearMessages();
|
||||
|
||||
host.runQueuedImmediateCallbacks();
|
||||
assert.isFalse(hasError);
|
||||
checkErrorMessage(host, "semanticDiag", { file: untitledFile, diagnostics: [] });
|
||||
checkErrorMessage(session, "semanticDiag", { file: untitledFile, diagnostics: [] });
|
||||
|
||||
checkCompleteEvent(host, 2, expectedSequenceId);
|
||||
checkCompleteEvent(session, 2, expectedSequenceId);
|
||||
}
|
||||
|
||||
it("has projectRoot", () => {
|
||||
|
@ -2942,7 +2935,7 @@ namespace ts.projectSystem {
|
|||
verifyErrorsInApp();
|
||||
|
||||
function verifyErrorsInApp() {
|
||||
host.clearOutput();
|
||||
session.clearMessages();
|
||||
const expectedSequenceId = session.getNextSeq();
|
||||
session.executeCommandSeq<protocol.GeterrRequest>({
|
||||
command: server.CommandNames.Geterr,
|
||||
|
@ -2952,13 +2945,13 @@ namespace ts.projectSystem {
|
|||
}
|
||||
});
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkErrorMessage(host, "syntaxDiag", { file: app.path, diagnostics: [] });
|
||||
host.clearOutput();
|
||||
checkErrorMessage(session, "syntaxDiag", { file: app.path, diagnostics: [] });
|
||||
session.clearMessages();
|
||||
|
||||
host.runQueuedImmediateCallbacks();
|
||||
checkErrorMessage(host, "semanticDiag", { file: app.path, diagnostics: [] });
|
||||
checkCompleteEvent(host, 2, expectedSequenceId);
|
||||
host.clearOutput();
|
||||
checkErrorMessage(session, "semanticDiag", { file: app.path, diagnostics: [] });
|
||||
checkCompleteEvent(session, 2, expectedSequenceId);
|
||||
session.clearMessages();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -3683,7 +3676,7 @@ namespace ts.projectSystem {
|
|||
}
|
||||
});
|
||||
checkNumberOfProjects(service, { inferredProjects: 1 });
|
||||
host.clearOutput();
|
||||
session.clearMessages();
|
||||
const expectedSequenceId = session.getNextSeq();
|
||||
session.executeCommandSeq<protocol.GeterrRequest>({
|
||||
command: server.CommandNames.Geterr,
|
||||
|
@ -3694,23 +3687,24 @@ namespace ts.projectSystem {
|
|||
});
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] });
|
||||
host.clearOutput();
|
||||
checkErrorMessage(session, "syntaxDiag", { file: file1.path, diagnostics: [] });
|
||||
session.clearMessages();
|
||||
|
||||
host.runQueuedImmediateCallbacks();
|
||||
const moduleNotFound = Diagnostics.Cannot_find_module_0;
|
||||
const startOffset = file1.content.indexOf('"') + 1;
|
||||
checkErrorMessage(host, "semanticDiag", {
|
||||
checkErrorMessage(session, "semanticDiag", {
|
||||
file: file1.path, diagnostics: [{
|
||||
start: { line: 1, offset: startOffset },
|
||||
end: { line: 1, offset: startOffset + '"pad"'.length },
|
||||
text: formatStringFromArgs(moduleNotFound.message, ["pad"]),
|
||||
code: moduleNotFound.code,
|
||||
category: DiagnosticCategory[moduleNotFound.category].toLowerCase()
|
||||
category: DiagnosticCategory[moduleNotFound.category].toLowerCase(),
|
||||
source: undefined
|
||||
}]
|
||||
});
|
||||
checkCompleteEvent(host, 2, expectedSequenceId);
|
||||
host.clearOutput();
|
||||
checkCompleteEvent(session, 2, expectedSequenceId);
|
||||
session.clearMessages();
|
||||
|
||||
const padIndex: FileOrFolder = {
|
||||
path: `${folderPath}/node_modules/@types/pad/index.d.ts`,
|
||||
|
@ -3719,15 +3713,15 @@ namespace ts.projectSystem {
|
|||
files.push(padIndex);
|
||||
host.reloadFS(files, { ignoreWatchInvokedWithTriggerAsFileCreate: true });
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkProjectUpdatedInBackgroundEvent(host, [file1.path]);
|
||||
host.clearOutput();
|
||||
checkProjectUpdatedInBackgroundEvent(session, [file1.path]);
|
||||
session.clearMessages();
|
||||
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] });
|
||||
host.clearOutput();
|
||||
checkErrorMessage(session, "syntaxDiag", { file: file1.path, diagnostics: [] });
|
||||
session.clearMessages();
|
||||
|
||||
host.runQueuedImmediateCallbacks();
|
||||
checkErrorMessage(host, "semanticDiag", { file: file1.path, diagnostics: [] });
|
||||
checkErrorMessage(session, "semanticDiag", { file: file1.path, diagnostics: [] });
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -4841,7 +4835,7 @@ namespace ts.projectSystem {
|
|||
command: "projectInfo",
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
host.clearOutput();
|
||||
session.clearMessages();
|
||||
|
||||
// cancel previously issued Geterr
|
||||
cancellationToken.setRequestToCancel(getErrId);
|
||||
|
@ -4865,7 +4859,7 @@ namespace ts.projectSystem {
|
|||
assert.equal(host.getOutput().length, 1, "expect 1 message");
|
||||
const e1 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e1.event, "syntaxDiag");
|
||||
host.clearOutput();
|
||||
session.clearMessages();
|
||||
|
||||
cancellationToken.setRequestToCancel(getErrId);
|
||||
host.runQueuedImmediateCallbacks();
|
||||
|
@ -4887,7 +4881,7 @@ namespace ts.projectSystem {
|
|||
assert.equal(host.getOutput().length, 1, "expect 1 message");
|
||||
const e1 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e1.event, "syntaxDiag");
|
||||
host.clearOutput();
|
||||
session.clearMessages();
|
||||
|
||||
// the semanticDiag message
|
||||
host.runQueuedImmediateCallbacks();
|
||||
|
@ -4910,7 +4904,7 @@ namespace ts.projectSystem {
|
|||
assert.equal(host.getOutput().length, 1, "expect 1 message");
|
||||
const e1 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e1.event, "syntaxDiag");
|
||||
host.clearOutput();
|
||||
session.clearMessages();
|
||||
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
|
@ -4924,7 +4918,7 @@ namespace ts.projectSystem {
|
|||
const event = <protocol.RequestCompletedEvent>getMessage(n);
|
||||
assert.equal(event.event, "requestCompleted");
|
||||
assert.equal(event.body.request_seq, expectedSeq, "expectedSeq");
|
||||
host.clearOutput();
|
||||
session.clearMessages();
|
||||
}
|
||||
|
||||
function getMessage(n: number) {
|
||||
|
@ -6427,7 +6421,7 @@ namespace ts.projectSystem {
|
|||
});
|
||||
|
||||
// Verified the events, reset them
|
||||
host.clearOutput();
|
||||
session.clearMessages();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -141,48 +141,33 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol_1166" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_1166" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in a class property declaration must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ein berechneter Eigenschaftenname in einer Klasseneigenschaftendeklaration muss direkt auf ein integriertes Symbol verweisen.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol_1168" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_ty_1168" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in a method overload must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ein berechneter Eigenschaftenname in einer Methodenüberladung muss direkt auf ein integriertes Symbol verweisen.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol_1170" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type__1170" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in a type literal must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ein berechneter Eigenschaftenname in einem Typliteral muss direkt auf ein integriertes Symbol verweisen.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol_1165" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_t_1165" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in an ambient context must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ein berechneter Eigenschaftenname in einem Umgebungskontext muss direkt auf ein integriertes Symbol verweisen.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol_1169" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_1169" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in an interface must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ein berechneter Eigenschaftenname in einer Schnittstelle muss direkt auf ein integriertes Symbol verweisen.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
@ -519,6 +504,18 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly_1331" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly_1330" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_required_parameter_cannot_follow_an_optional_parameter_1016" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A required parameter cannot follow an optional parameter.]]></Val>
|
||||
|
@ -762,6 +759,12 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_variable_whose_type_is_a_unique_symbol_type_must_be_const_1332" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A variable whose type is a 'unique symbol' type must be 'const'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_yield_expression_is_only_allowed_in_a_generator_body_1163" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A 'yield' expression is only allowed in a generator body.]]></Val>
|
||||
|
@ -2568,6 +2571,12 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Duplicate_declaration_0_2718" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Duplicate declaration '{0}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Duplicate_function_implementation_2393" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Duplicate function implementation.]]></Val>
|
||||
|
@ -2916,12 +2925,9 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_a_minimum_of_1_2556" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_or_more_2556" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got a minimum of {1}.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} Argumente wurden erwartet, empfangen wurde aber ein Minimum von {1}.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1} or more.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
@ -2952,12 +2958,9 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_or_more_2557" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got a minimum of {1}.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Mindestens {0} Argumente wurden erwartet, empfangen wurde aber ein Minimum von {1}.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1} or more.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
@ -4110,6 +4113,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '...' may only appear in the last parameter of a signature.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Das JSDoc-Tag "..." wird möglicherweise nur im letzten Parameter einer Signatur angezeigt.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@param' tag has name '{0}', but there is no parameter with that name.]]></Val>
|
||||
|
@ -4479,6 +4491,18 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Method_0_of_exported_interface_has_or_is_using_private_name_1_4102" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Method '{0}' of exported interface has or is using private name '{1}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Modifiers_cannot_appear_here_1184" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Modifiers cannot appear here.]]></Val>
|
||||
|
@ -5619,6 +5643,24 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4098" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public method '{0}' of exported class has or is using private name '{1}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.]]></Val>
|
||||
|
@ -5646,6 +5688,24 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_4095" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static method '{0}' of exported class has or is using private name '{1}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.]]></Val>
|
||||
|
@ -6426,6 +6486,12 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_property_declarations_must_have_the_same_type_Property_0_has_type_1_at_2_but_here_has_typ_2717" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent property declarations must have the same type. Property '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
|
@ -6648,12 +6714,9 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The inferred type of '{0}' references an inaccessible 'this' type. A type annotation is necessary.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Der abgeleitete Typ von "{0}" verweist auf einen this-Typ, auf den nicht zugegriffen werden kann. Eine Typanmerkung ist erforderlich.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
@ -8703,6 +8766,24 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";unique_symbol_types_are_not_allowed_here_1335" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['unique symbol' types are not allowed here.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement_1334" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['unique symbol' types are only allowed on variables in a variable statement.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name_1333" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['unique symbol' types may not be used on a variable declaration with a binding name.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";with_statements_are_not_allowed_in_an_async_function_block_1300" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['with' statements are not allowed in an async function block.]]></Val>
|
||||
|
|
|
@ -140,48 +140,33 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol_1166" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_1166" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in a class property declaration must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Имя вычисляемого свойства в объявлении свойства класса должно непосредственно ссылаться на встроенный символ.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_a_method_overload_must_directly_refer_to_a_built_in_symbol_1168" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_ty_1168" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in a method overload must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Имя вычисляемого свойства в перегрузке метода должно непосредственно ссылаться на встроенный символ.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_a_type_literal_must_directly_refer_to_a_built_in_symbol_1170" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type__1170" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in a type literal must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Имя вычисляемого свойства в литерале типа должно непосредственно ссылаться на встроенный символ.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol_1165" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_t_1165" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in an ambient context must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Имя вычисляемого свойства в окружающем контексте должно непосредственно ссылаться на встроенный символ.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_computed_property_name_in_an_interface_must_directly_refer_to_a_built_in_symbol_1169" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_1169" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A computed property name in an interface must directly refer to a built-in symbol.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Имя вычисляемого свойства в интерфейсе должно непосредственно ссылаться на встроенный символ.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
@ -518,6 +503,18 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly_1331" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly_1330" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_required_parameter_cannot_follow_an_optional_parameter_1016" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A required parameter cannot follow an optional parameter.]]></Val>
|
||||
|
@ -764,6 +761,12 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_variable_whose_type_is_a_unique_symbol_type_must_be_const_1332" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A variable whose type is a 'unique symbol' type must be 'const'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_yield_expression_is_only_allowed_in_a_generator_body_1163" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A 'yield' expression is only allowed in a generator body.]]></Val>
|
||||
|
@ -2576,6 +2579,12 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Duplicate_declaration_0_2718" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Duplicate declaration '{0}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Duplicate_function_implementation_2393" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Duplicate function implementation.]]></Val>
|
||||
|
@ -2924,12 +2933,9 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_a_minimum_of_1_2556" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_or_more_2556" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got a minimum of {1}.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ожидалось аргументов: {0}, получено минимум {1}.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1} or more.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
@ -2960,12 +2966,9 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_a_minimum_of_1_2557" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_or_more_2557" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got a minimum of {1}.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ожидалось аргументов не менее: {0}, получено минимум {1}.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1} or more.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
@ -4121,6 +4124,15 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '...' may only appear in the last parameter of a signature.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc "..." может использоваться только в последнем параметре сигнатуры.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@param' tag has name '{0}', but there is no parameter with that name.]]></Val>
|
||||
|
@ -4490,6 +4502,18 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Method_0_of_exported_interface_has_or_is_using_private_name_1_4102" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Method '{0}' of exported interface has or is using private name '{1}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Modifiers_cannot_appear_here_1184" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Modifiers cannot appear here.]]></Val>
|
||||
|
@ -5633,6 +5657,24 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4098" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public method '{0}' of exported class has or is using private name '{1}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.]]></Val>
|
||||
|
@ -5660,6 +5702,24 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_4095" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static method '{0}' of exported class has or is using private name '{1}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.]]></Val>
|
||||
|
@ -6446,6 +6506,12 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_property_declarations_must_have_the_same_type_Property_0_has_type_1_at_2_but_here_has_typ_2717" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent property declarations must have the same type. Property '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
|
@ -6668,12 +6734,9 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[The inferred type of '{0}' references an inaccessible 'this' type. A type annotation is necessary.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Выводимый тип "{0}" ссылается на недоступный тип this. Требуется аннотация типа.]]></Val>
|
||||
</Tgt>
|
||||
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
@ -8723,6 +8786,24 @@
|
|||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";unique_symbol_types_are_not_allowed_here_1335" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['unique symbol' types are not allowed here.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement_1334" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['unique symbol' types are only allowed on variables in a variable statement.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name_1333" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['unique symbol' types may not be used on a variable declaration with a binding name.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";with_statements_are_not_allowed_in_an_async_function_block_1300" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['with' statements are not allowed in an async function block.]]></Val>
|
||||
|
|
|
@ -155,9 +155,8 @@ namespace ts.server {
|
|||
exclude: [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it
|
||||
types: ["office"] // @types package to fetch instead
|
||||
},
|
||||
"Minified files": {
|
||||
// e.g. /whatever/blah.min.js
|
||||
match: /^(.+\.min\.js)$/i,
|
||||
"References": {
|
||||
match: /^(.*\/_references\.js)$/i,
|
||||
exclude: [["^", 1, "$"]]
|
||||
}
|
||||
};
|
||||
|
@ -1447,7 +1446,9 @@ namespace ts.server {
|
|||
}
|
||||
this.seenProjects.set(projectKey, true);
|
||||
|
||||
if (!this.eventHandler) return;
|
||||
if (!this.eventHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data: ProjectInfoTelemetryEventData = {
|
||||
projectId: this.host.createHash(projectKey),
|
||||
|
@ -2285,7 +2286,13 @@ namespace ts.server {
|
|||
}
|
||||
}
|
||||
if (!exclude) {
|
||||
filesToKeep.push(proj.rootFiles[i]);
|
||||
// Exclude any minified files that get this far
|
||||
if (/^.+[\.-]min\.js$/.test(normalizedNames[i])) {
|
||||
excludedFiles.push(normalizedNames[i]);
|
||||
}
|
||||
else {
|
||||
filesToKeep.push(proj.rootFiles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -585,7 +585,7 @@ namespace ts.server.protocol {
|
|||
errorCodes?: number[];
|
||||
}
|
||||
|
||||
export interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
|
||||
export interface ApplyCodeActionCommandRequestArgs {
|
||||
/** May also be an array of commands. */
|
||||
command: {};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/// <reference types="node" />
|
||||
/// <reference path="shared.ts" />
|
||||
/// <reference path="session.ts" />
|
||||
|
||||
|
@ -7,7 +6,11 @@ namespace ts.server {
|
|||
host: ServerHost;
|
||||
cancellationToken: ServerCancellationToken;
|
||||
canUseEvents: boolean;
|
||||
installerEventPort: number;
|
||||
/**
|
||||
* If defined, specifies the socket used to send events to the client.
|
||||
* Otherwise, events are sent through the host.
|
||||
*/
|
||||
eventPort?: number;
|
||||
useSingleInferredProject: boolean;
|
||||
useInferredProjectPerProjectRoot: boolean;
|
||||
disableAutomaticTypingAcquisition: boolean;
|
||||
|
@ -22,10 +25,6 @@ namespace ts.server {
|
|||
allowLocalPluginLoads: boolean;
|
||||
}
|
||||
|
||||
const net: {
|
||||
connect(options: { port: number }, onConnect?: () => void): NodeSocket
|
||||
} = require("net");
|
||||
|
||||
const childProcess: {
|
||||
fork(modulePath: string, args: string[], options?: { execArgv: string[], env?: MapLike<string> }): NodeChildProcess;
|
||||
execFileSync(file: string, args: string[], options: { stdio: "ignore", env: MapLike<string> }): string | Buffer;
|
||||
|
@ -36,6 +35,14 @@ namespace ts.server {
|
|||
tmpdir(): string;
|
||||
} = require("os");
|
||||
|
||||
interface NodeSocket {
|
||||
write(data: string, encoding: string): boolean;
|
||||
}
|
||||
|
||||
const net: {
|
||||
connect(options: { port: number }, onConnect?: () => void): NodeSocket
|
||||
} = require("net");
|
||||
|
||||
function getGlobalTypingsCacheLocation() {
|
||||
switch (process.platform) {
|
||||
case "win32": {
|
||||
|
@ -83,10 +90,6 @@ namespace ts.server {
|
|||
pid: number;
|
||||
}
|
||||
|
||||
interface NodeSocket {
|
||||
write(data: string, encoding: string): boolean;
|
||||
}
|
||||
|
||||
interface ReadLineOptions {
|
||||
input: NodeJS.ReadableStream;
|
||||
output?: NodeJS.WritableStream;
|
||||
|
@ -243,10 +246,7 @@ namespace ts.server {
|
|||
|
||||
class NodeTypingsInstaller implements ITypingsInstaller {
|
||||
private installer: NodeChildProcess;
|
||||
private installerPidReported = false;
|
||||
private socket: NodeSocket;
|
||||
private projectService: ProjectService;
|
||||
private eventSender: EventSender;
|
||||
private activeRequestCount = 0;
|
||||
private requestQueue: QueuedOperation[] = [];
|
||||
private requestMap = createMap<QueuedOperation>(); // Maps operation ID to newest requestQueue entry with that ID
|
||||
|
@ -267,18 +267,11 @@ namespace ts.server {
|
|||
private readonly telemetryEnabled: boolean,
|
||||
private readonly logger: server.Logger,
|
||||
private readonly host: ServerHost,
|
||||
eventPort: number,
|
||||
readonly globalTypingsCacheLocation: string,
|
||||
readonly typingSafeListLocation: string,
|
||||
readonly typesMapLocation: string,
|
||||
private readonly npmLocation: string | undefined,
|
||||
private newLine: string) {
|
||||
if (eventPort) {
|
||||
const s = net.connect({ port: eventPort }, () => {
|
||||
this.socket = s;
|
||||
this.reportInstallerProcessId();
|
||||
});
|
||||
}
|
||||
private event: Event) {
|
||||
}
|
||||
|
||||
isKnownTypesPackageName(name: string): boolean {
|
||||
|
@ -306,24 +299,6 @@ namespace ts.server {
|
|||
});
|
||||
}
|
||||
|
||||
private reportInstallerProcessId() {
|
||||
if (this.installerPidReported) {
|
||||
return;
|
||||
}
|
||||
if (this.socket && this.installer) {
|
||||
this.sendEvent(0, "typingsInstallerPid", { pid: this.installer.pid });
|
||||
this.installerPidReported = true;
|
||||
}
|
||||
}
|
||||
|
||||
private sendEvent(seq: number, event: string, body: any): void {
|
||||
this.socket.write(formatMessage({ seq, type: "event", event, body }, this.logger, Buffer.byteLength, this.newLine), "utf8");
|
||||
}
|
||||
|
||||
setTelemetrySender(telemetrySender: EventSender) {
|
||||
this.eventSender = telemetrySender;
|
||||
}
|
||||
|
||||
attach(projectService: ProjectService) {
|
||||
this.projectService = projectService;
|
||||
if (this.logger.hasLevel(LogLevel.requestTime)) {
|
||||
|
@ -363,7 +338,8 @@ namespace ts.server {
|
|||
|
||||
this.installer = childProcess.fork(combinePaths(__dirname, "typingsInstaller.js"), args, { execArgv });
|
||||
this.installer.on("message", m => this.handleMessage(m));
|
||||
this.reportInstallerProcessId();
|
||||
|
||||
this.event({ pid: this.installer.pid }, "typingsInstallerPid");
|
||||
|
||||
process.on("exit", () => {
|
||||
this.installer.kill();
|
||||
|
@ -428,92 +404,81 @@ namespace ts.server {
|
|||
break;
|
||||
}
|
||||
case EventInitializationFailed:
|
||||
{
|
||||
if (!this.eventSender) {
|
||||
break;
|
||||
}
|
||||
const body: protocol.TypesInstallerInitializationFailedEventBody = {
|
||||
message: response.message
|
||||
};
|
||||
const eventName: protocol.TypesInstallerInitializationFailedEventName = "typesInstallerInitializationFailed";
|
||||
this.eventSender.event(body, eventName);
|
||||
break;
|
||||
}
|
||||
case EventBeginInstallTypes:
|
||||
{
|
||||
if (!this.eventSender) {
|
||||
break;
|
||||
}
|
||||
const body: protocol.BeginInstallTypesEventBody = {
|
||||
eventId: response.eventId,
|
||||
packages: response.packagesToInstall,
|
||||
};
|
||||
const eventName: protocol.BeginInstallTypesEventName = "beginInstallTypes";
|
||||
this.eventSender.event(body, eventName);
|
||||
break;
|
||||
}
|
||||
case EventEndInstallTypes:
|
||||
{
|
||||
if (!this.eventSender) {
|
||||
break;
|
||||
}
|
||||
if (this.telemetryEnabled) {
|
||||
const body: protocol.TypingsInstalledTelemetryEventBody = {
|
||||
telemetryEventName: "typingsInstalled",
|
||||
payload: {
|
||||
installedPackages: response.packagesToInstall.join(","),
|
||||
installSuccess: response.installSuccess,
|
||||
typingsInstallerVersion: response.typingsInstallerVersion
|
||||
}
|
||||
{
|
||||
const body: protocol.TypesInstallerInitializationFailedEventBody = {
|
||||
message: response.message
|
||||
};
|
||||
const eventName: protocol.TelemetryEventName = "telemetry";
|
||||
this.eventSender.event(body, eventName);
|
||||
const eventName: protocol.TypesInstallerInitializationFailedEventName = "typesInstallerInitializationFailed";
|
||||
this.event(body, eventName);
|
||||
break;
|
||||
}
|
||||
case EventBeginInstallTypes:
|
||||
{
|
||||
const body: protocol.BeginInstallTypesEventBody = {
|
||||
eventId: response.eventId,
|
||||
packages: response.packagesToInstall,
|
||||
};
|
||||
const eventName: protocol.BeginInstallTypesEventName = "beginInstallTypes";
|
||||
this.event(body, eventName);
|
||||
break;
|
||||
}
|
||||
case EventEndInstallTypes:
|
||||
{
|
||||
if (this.telemetryEnabled) {
|
||||
const body: protocol.TypingsInstalledTelemetryEventBody = {
|
||||
telemetryEventName: "typingsInstalled",
|
||||
payload: {
|
||||
installedPackages: response.packagesToInstall.join(","),
|
||||
installSuccess: response.installSuccess,
|
||||
typingsInstallerVersion: response.typingsInstallerVersion
|
||||
}
|
||||
};
|
||||
const eventName: protocol.TelemetryEventName = "telemetry";
|
||||
this.event(body, eventName);
|
||||
}
|
||||
|
||||
const body: protocol.EndInstallTypesEventBody = {
|
||||
eventId: response.eventId,
|
||||
packages: response.packagesToInstall,
|
||||
success: response.installSuccess,
|
||||
};
|
||||
const eventName: protocol.EndInstallTypesEventName = "endInstallTypes";
|
||||
this.eventSender.event(body, eventName);
|
||||
break;
|
||||
}
|
||||
const body: protocol.EndInstallTypesEventBody = {
|
||||
eventId: response.eventId,
|
||||
packages: response.packagesToInstall,
|
||||
success: response.installSuccess,
|
||||
};
|
||||
const eventName: protocol.EndInstallTypesEventName = "endInstallTypes";
|
||||
this.event(body, eventName);
|
||||
break;
|
||||
}
|
||||
case ActionInvalidate:
|
||||
{
|
||||
this.projectService.updateTypingsForProject(response);
|
||||
break;
|
||||
}
|
||||
{
|
||||
this.projectService.updateTypingsForProject(response);
|
||||
break;
|
||||
}
|
||||
case ActionSet:
|
||||
{
|
||||
if (this.activeRequestCount > 0) {
|
||||
this.activeRequestCount--;
|
||||
}
|
||||
else {
|
||||
Debug.fail("Received too many responses");
|
||||
}
|
||||
|
||||
while (this.requestQueue.length > 0) {
|
||||
const queuedRequest = this.requestQueue.shift();
|
||||
if (this.requestMap.get(queuedRequest.operationId) === queuedRequest) {
|
||||
this.requestMap.delete(queuedRequest.operationId);
|
||||
this.scheduleRequest(queuedRequest);
|
||||
break;
|
||||
{
|
||||
if (this.activeRequestCount > 0) {
|
||||
this.activeRequestCount--;
|
||||
}
|
||||
else {
|
||||
Debug.fail("Received too many responses");
|
||||
}
|
||||
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Skipping defunct request for: ${queuedRequest.operationId}`);
|
||||
while (this.requestQueue.length > 0) {
|
||||
const queuedRequest = this.requestQueue.shift();
|
||||
if (this.requestMap.get(queuedRequest.operationId) === queuedRequest) {
|
||||
this.requestMap.delete(queuedRequest.operationId);
|
||||
this.scheduleRequest(queuedRequest);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Skipping defunct request for: ${queuedRequest.operationId}`);
|
||||
}
|
||||
}
|
||||
|
||||
this.projectService.updateTypingsForProject(response);
|
||||
|
||||
this.event(response, "setTypings");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
this.projectService.updateTypingsForProject(response);
|
||||
|
||||
if (this.socket) {
|
||||
this.sendEvent(0, "setTypings", response);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assertTypeIsNever(response);
|
||||
}
|
||||
|
@ -529,11 +494,30 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
class IOSession extends Session {
|
||||
private eventPort: number;
|
||||
private eventSocket: NodeSocket | undefined;
|
||||
private socketEventQueue: { body: any, eventName: string }[] | undefined;
|
||||
private constructed: boolean | undefined;
|
||||
|
||||
constructor(options: IoSessionOptions) {
|
||||
const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, canUseEvents } = options;
|
||||
const { host, eventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, canUseEvents } = options;
|
||||
|
||||
const event: Event | undefined = (body: {}, eventName: string) => {
|
||||
if (this.constructed) {
|
||||
this.event(body, eventName);
|
||||
}
|
||||
else {
|
||||
// It is unsafe to dereference `this` before initialization completes,
|
||||
// so we defer until the next tick.
|
||||
//
|
||||
// Construction should finish before the next tick fires, so we do not need to do this recursively.
|
||||
setImmediate(() => this.event(body, eventName));
|
||||
}
|
||||
};
|
||||
|
||||
const typingsInstaller = disableAutomaticTypingAcquisition
|
||||
? undefined
|
||||
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, host.newLine);
|
||||
: new NodeTypingsInstaller(telemetryEnabled, logger, host, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, event);
|
||||
|
||||
super({
|
||||
host,
|
||||
|
@ -547,11 +531,49 @@ namespace ts.server {
|
|||
canUseEvents,
|
||||
globalPlugins: options.globalPlugins,
|
||||
pluginProbeLocations: options.pluginProbeLocations,
|
||||
allowLocalPluginLoads: options.allowLocalPluginLoads });
|
||||
allowLocalPluginLoads: options.allowLocalPluginLoads
|
||||
});
|
||||
|
||||
if (telemetryEnabled && typingsInstaller) {
|
||||
typingsInstaller.setTelemetrySender(this);
|
||||
this.eventPort = eventPort;
|
||||
if (this.canUseEvents && this.eventPort) {
|
||||
const s = net.connect({ port: this.eventPort }, () => {
|
||||
this.eventSocket = s;
|
||||
if (this.socketEventQueue) {
|
||||
// flush queue.
|
||||
for (const event of this.socketEventQueue) {
|
||||
this.writeToEventSocket(event.body, event.eventName);
|
||||
}
|
||||
this.socketEventQueue = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.constructed = true;
|
||||
}
|
||||
|
||||
event<T>(body: T, eventName: string): void {
|
||||
Debug.assert(this.constructed, "Should only call `IOSession.prototype.event` on an initialized IOSession");
|
||||
|
||||
if (this.canUseEvents && this.eventPort) {
|
||||
if (!this.eventSocket) {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`eventPort: event "${eventName}" queued, but socket not yet initialized`);
|
||||
}
|
||||
(this.socketEventQueue || (this.socketEventQueue = [])).push({ body, eventName });
|
||||
return;
|
||||
}
|
||||
else {
|
||||
Debug.assert(this.socketEventQueue === undefined);
|
||||
this.writeToEventSocket(body, eventName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.event(body, eventName);
|
||||
}
|
||||
}
|
||||
|
||||
private writeToEventSocket(body: any, eventName: string): void {
|
||||
this.eventSocket.write(formatMessage(toEvent(body, eventName), this.logger, this.byteLength, this.host.newLine), "utf8");
|
||||
}
|
||||
|
||||
exit() {
|
||||
|
@ -896,7 +918,7 @@ namespace ts.server {
|
|||
cancellationToken = nullCancellationToken;
|
||||
}
|
||||
|
||||
let eventPort: number;
|
||||
let eventPort: number | undefined;
|
||||
{
|
||||
const str = findArgument("--eventPort");
|
||||
const v = str && parseInt(str);
|
||||
|
@ -936,8 +958,8 @@ namespace ts.server {
|
|||
const options: IoSessionOptions = {
|
||||
host: sys,
|
||||
cancellationToken,
|
||||
installerEventPort: eventPort,
|
||||
canUseEvents: eventPort === undefined,
|
||||
eventPort,
|
||||
canUseEvents: true,
|
||||
useSingleInferredProject,
|
||||
useInferredProjectPerProjectRoot,
|
||||
disableAutomaticTypingAcquisition,
|
||||
|
|
|
@ -105,10 +105,6 @@ namespace ts.server {
|
|||
project: Project;
|
||||
}
|
||||
|
||||
export interface EventSender {
|
||||
event<T>(payload: T, eventName: string): void;
|
||||
}
|
||||
|
||||
function allEditsBeforePos(edits: ts.TextChange[], pos: number) {
|
||||
for (const edit of edits) {
|
||||
if (textSpanEnd(edit.span) >= pos) {
|
||||
|
@ -243,6 +239,22 @@ namespace ts.server {
|
|||
}
|
||||
}
|
||||
|
||||
export type Event = <T>(body: T, eventName: string) => void;
|
||||
|
||||
export interface EventSender {
|
||||
event: Event;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function toEvent(eventName: string, body: {}): protocol.Event {
|
||||
return {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: eventName,
|
||||
body
|
||||
};
|
||||
}
|
||||
|
||||
export interface SessionOptions {
|
||||
host: ServerHost;
|
||||
cancellationToken: ServerCancellationToken;
|
||||
|
@ -252,6 +264,9 @@ namespace ts.server {
|
|||
byteLength: (buf: string, encoding?: string) => number;
|
||||
hrtime: (start?: number[]) => number[];
|
||||
logger: Logger;
|
||||
/**
|
||||
* If falsy, all events are suppressed.
|
||||
*/
|
||||
canUseEvents: boolean;
|
||||
eventHandler?: ProjectServiceEventHandler;
|
||||
throttleWaitMilliseconds?: number;
|
||||
|
@ -269,15 +284,15 @@ namespace ts.server {
|
|||
private currentRequestId: number;
|
||||
private errorCheck: MultistepOperation;
|
||||
|
||||
private eventHandler: ProjectServiceEventHandler;
|
||||
|
||||
private host: ServerHost;
|
||||
protected host: ServerHost;
|
||||
private readonly cancellationToken: ServerCancellationToken;
|
||||
protected readonly typingsInstaller: ITypingsInstaller;
|
||||
private byteLength: (buf: string, encoding?: string) => number;
|
||||
protected byteLength: (buf: string, encoding?: string) => number;
|
||||
private hrtime: (start?: number[]) => number[];
|
||||
protected logger: Logger;
|
||||
private canUseEvents: boolean;
|
||||
|
||||
protected canUseEvents: boolean;
|
||||
private eventHandler: ProjectServiceEventHandler;
|
||||
|
||||
constructor(opts: SessionOptions) {
|
||||
this.host = opts.host;
|
||||
|
@ -293,7 +308,6 @@ namespace ts.server {
|
|||
this.eventHandler = this.canUseEvents
|
||||
? opts.eventHandler || (event => this.defaultEventHandler(event))
|
||||
: undefined;
|
||||
|
||||
const multistepOperationHost: MultistepOperationHost = {
|
||||
executeWithRequestId: (requestId, action) => this.executeWithRequestId(requestId, action),
|
||||
getCurrentRequestId: () => this.currentRequestId,
|
||||
|
@ -321,13 +335,7 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
private sendRequestCompletedEvent(requestId: number): void {
|
||||
const event: protocol.RequestCompletedEvent = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: "requestCompleted",
|
||||
body: { request_seq: requestId }
|
||||
};
|
||||
this.send(event);
|
||||
this.event<protocol.RequestCompletedEventBody>({ request_seq: requestId }, "requestCompleted");
|
||||
}
|
||||
|
||||
private defaultEventHandler(event: ProjectServiceEvent) {
|
||||
|
@ -401,17 +409,12 @@ namespace ts.server {
|
|||
this.host.write(formatMessage(msg, this.logger, this.byteLength, this.host.newLine));
|
||||
}
|
||||
|
||||
public event<T>(info: T, eventName: string) {
|
||||
const ev: protocol.Event = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: eventName,
|
||||
body: info
|
||||
};
|
||||
this.send(ev);
|
||||
public event<T>(body: T, eventName: string): void {
|
||||
this.send(toEvent(eventName, body));
|
||||
}
|
||||
|
||||
// For backwards-compatibility only.
|
||||
/** @deprecated */
|
||||
public output(info: any, cmdName: string, reqSeq?: number, errorMsg?: string): void {
|
||||
this.doOutput(info, cmdName, reqSeq, /*success*/ !errorMsg, errorMsg);
|
||||
}
|
||||
|
@ -1569,15 +1572,14 @@ namespace ts.server {
|
|||
}
|
||||
|
||||
private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
|
||||
const command = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
|
||||
|
||||
project.getLanguageService().applyCodeActionCommand(file, command).then(
|
||||
result => {
|
||||
output(/*success*/ true, isArray(result) ? result.map(res => res.successMessage).join(`${this.host.newLine}${this.host.newLine}`) : result.successMessage);
|
||||
},
|
||||
error => { output(/*success*/ false, error); });
|
||||
const commands = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
|
||||
for (const command of toArray(commands)) {
|
||||
const { project } = this.getFileAndProject(command);
|
||||
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
|
||||
project.getLanguageService().applyCodeActionCommand(command).then(
|
||||
result => { output(/*success*/ true, result.successMessage); },
|
||||
error => { output(/*success*/ false, error); });
|
||||
}
|
||||
}
|
||||
|
||||
private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) {
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
"exclude": [["^", 1, "/.*"]],
|
||||
"types": ["office"]
|
||||
},
|
||||
"Minified files": {
|
||||
"match": "^(.+\\.min\\.js)$",
|
||||
"References": {
|
||||
"match": "^(.*\\/_references\\.js)$",
|
||||
"exclude": [["^", 1, "$"]]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -11,12 +11,12 @@ namespace ts.codefix {
|
|||
throw Debug.fail(); // These errors should only happen on the module name.
|
||||
}
|
||||
|
||||
const action = tryGetCodeActionForInstallPackageTypes(context.host, token.text);
|
||||
const action = tryGetCodeActionForInstallPackageTypes(context.host, sourceFile.fileName, token.text);
|
||||
return action && [action];
|
||||
},
|
||||
});
|
||||
|
||||
export function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, moduleName: string): CodeAction | undefined {
|
||||
export function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, fileName: string, moduleName: string): CodeAction | undefined {
|
||||
const { packageName } = getPackageName(moduleName);
|
||||
|
||||
if (!host.isKnownTypesPackageName(packageName)) {
|
||||
|
@ -28,7 +28,7 @@ namespace ts.codefix {
|
|||
return {
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Install_0), [typesPackageName]),
|
||||
changes: [],
|
||||
commands: [{ type: "install package", packageName: typesPackageName }],
|
||||
commands: [{ type: "install package", file: fileName, packageName: typesPackageName }],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,8 +184,10 @@ namespace ts.codefix {
|
|||
Equals
|
||||
}
|
||||
|
||||
export function getCodeActionForImport(moduleSymbol: Symbol, context: ImportCodeFixOptions): ImportCodeAction[] {
|
||||
const declarations = getImportDeclarations(moduleSymbol, context.checker, context.sourceFile, context.cachedImportDeclarations);
|
||||
export function getCodeActionForImport(moduleSymbols: Symbol | ReadonlyArray<Symbol>, context: ImportCodeFixOptions): ImportCodeAction[] {
|
||||
moduleSymbols = toArray(moduleSymbols);
|
||||
const declarations = flatMap(moduleSymbols, moduleSymbol =>
|
||||
getImportDeclarations(moduleSymbol, context.checker, context.sourceFile, context.cachedImportDeclarations));
|
||||
const actions: ImportCodeAction[] = [];
|
||||
if (context.symbolToken) {
|
||||
// It is possible that multiple import statements with the same specifier exist in the file.
|
||||
|
@ -207,7 +209,7 @@ namespace ts.codefix {
|
|||
}
|
||||
}
|
||||
}
|
||||
actions.push(getCodeActionForAddImport(moduleSymbol, context, declarations));
|
||||
actions.push(getCodeActionForAddImport(moduleSymbols, context, declarations));
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
@ -313,16 +315,19 @@ namespace ts.codefix {
|
|||
}
|
||||
}
|
||||
|
||||
export function getModuleSpecifierForNewImport(sourceFile: SourceFile, moduleSymbol: Symbol, options: CompilerOptions, getCanonicalFileName: (file: string) => string, host: LanguageServiceHost): string | undefined {
|
||||
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName;
|
||||
const sourceDirectory = getDirectoryPath(sourceFile.fileName);
|
||||
export function getModuleSpecifierForNewImport(sourceFile: SourceFile, moduleSymbols: ReadonlyArray<Symbol>, options: CompilerOptions, getCanonicalFileName: (file: string) => string, host: LanguageServiceHost): string | undefined {
|
||||
const choices = mapIterator(arrayIterator(moduleSymbols), moduleSymbol => {
|
||||
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName;
|
||||
const sourceDirectory = getDirectoryPath(sourceFile.fileName);
|
||||
|
||||
return tryGetModuleNameFromAmbientModule(moduleSymbol) ||
|
||||
tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName) ||
|
||||
tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) ||
|
||||
tryGetModuleNameFromBaseUrl(options, moduleFileName, getCanonicalFileName) ||
|
||||
options.rootDirs && tryGetModuleNameFromRootDirs(options.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) ||
|
||||
removeExtensionAndIndexPostFix(getRelativePath(moduleFileName, sourceDirectory, getCanonicalFileName), options);
|
||||
return tryGetModuleNameFromAmbientModule(moduleSymbol) ||
|
||||
tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName) ||
|
||||
tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) ||
|
||||
tryGetModuleNameFromBaseUrl(options, moduleFileName, getCanonicalFileName) ||
|
||||
options.rootDirs && tryGetModuleNameFromRootDirs(options.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) ||
|
||||
removeExtensionAndIndexPostFix(getRelativePath(moduleFileName, sourceDirectory, getCanonicalFileName), options);
|
||||
});
|
||||
return best(choices, (a, b) => a.length < b.length);
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined {
|
||||
|
@ -543,7 +548,7 @@ namespace ts.codefix {
|
|||
}
|
||||
|
||||
function getCodeActionForAddImport(
|
||||
moduleSymbol: Symbol,
|
||||
moduleSymbols: ReadonlyArray<Symbol>,
|
||||
ctx: ImportCodeFixOptions,
|
||||
declarations: ReadonlyArray<AnyImportSyntax>): ImportCodeAction {
|
||||
const fromExistingImport = firstDefined(declarations, declaration => {
|
||||
|
@ -565,7 +570,7 @@ namespace ts.codefix {
|
|||
}
|
||||
|
||||
const moduleSpecifier = firstDefined(declarations, moduleSpecifierFromAnyImport)
|
||||
|| getModuleSpecifierForNewImport(ctx.sourceFile, moduleSymbol, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host);
|
||||
|| getModuleSpecifierForNewImport(ctx.sourceFile, moduleSymbols, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host);
|
||||
return getCodeActionForNewImport(ctx, moduleSpecifier);
|
||||
}
|
||||
|
||||
|
@ -659,24 +664,33 @@ namespace ts.codefix {
|
|||
symbolName = symbol.name;
|
||||
}
|
||||
else {
|
||||
Debug.fail("Either the symbol or the JSX namespace should be a UMD global if we got here");
|
||||
throw Debug.fail("Either the symbol or the JSX namespace should be a UMD global if we got here");
|
||||
}
|
||||
|
||||
const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions);
|
||||
|
||||
return getCodeActionForImport(symbol, { ...context, symbolName, kind: getUmdImportKind(compilerOptions) });
|
||||
}
|
||||
function getUmdImportKind(compilerOptions: CompilerOptions) {
|
||||
// Import a synthetic `default` if enabled.
|
||||
if (allowSyntheticDefaultImports) {
|
||||
return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Default });
|
||||
if (getAllowSyntheticDefaultImports(compilerOptions)) {
|
||||
return ImportKind.Default;
|
||||
}
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
|
||||
// When a synthetic `default` is unavailable, use `import..require` if the module kind supports it.
|
||||
if (moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.CommonJS || moduleKind === ModuleKind.UMD) {
|
||||
return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Equals });
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.AMD:
|
||||
case ModuleKind.CommonJS:
|
||||
case ModuleKind.UMD:
|
||||
return ImportKind.Equals;
|
||||
case ModuleKind.System:
|
||||
case ModuleKind.ES2015:
|
||||
case ModuleKind.ESNext:
|
||||
case ModuleKind.None:
|
||||
// Fall back to the `import * as ns` style import.
|
||||
return ImportKind.Namespace;
|
||||
default:
|
||||
throw Debug.assertNever(moduleKind);
|
||||
}
|
||||
|
||||
// Fall back to the `import * as ns` style import.
|
||||
return getCodeActionForImport(symbol, { ...context, symbolName, kind: ImportKind.Namespace });
|
||||
}
|
||||
|
||||
function getActionsForNonUMDImport(context: ImportCodeFixContext, allSourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken): ImportCodeAction[] {
|
||||
|
|
|
@ -443,7 +443,7 @@ namespace ts.Completions {
|
|||
}
|
||||
case "symbol": {
|
||||
const { symbol, location, symbolToOriginInfoMap } = symbolCompletion;
|
||||
const { codeActions, sourceDisplay } = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, formatContext, getCanonicalFileName);
|
||||
const { codeActions, sourceDisplay } = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, formatContext, getCanonicalFileName, allSourceFiles);
|
||||
const kindModifiers = SymbolDisplay.getSymbolModifiers(symbol);
|
||||
const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All);
|
||||
return { name, kindModifiers, kind: symbolKind, displayParts, documentation, tags, codeActions, source: sourceDisplay };
|
||||
|
@ -476,6 +476,7 @@ namespace ts.Completions {
|
|||
sourceFile: SourceFile,
|
||||
formatContext: formatting.FormatContext,
|
||||
getCanonicalFileName: GetCanonicalFileName,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
): { codeActions: CodeAction[] | undefined, sourceDisplay: SymbolDisplayPart[] | undefined } {
|
||||
const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)];
|
||||
if (!symbolOriginInfo) {
|
||||
|
@ -483,9 +484,12 @@ namespace ts.Completions {
|
|||
}
|
||||
|
||||
const { moduleSymbol, isDefaultExport } = symbolOriginInfo;
|
||||
const exportedSymbol = skipAlias(symbol.exportSymbol || symbol, checker);
|
||||
const moduleSymbols = getAllReExportingModules(exportedSymbol, checker, allSourceFiles);
|
||||
Debug.assert(contains(moduleSymbols, moduleSymbol));
|
||||
|
||||
const sourceDisplay = [textPart(codefix.getModuleSpecifierForNewImport(sourceFile, moduleSymbol, compilerOptions, getCanonicalFileName, host))];
|
||||
const codeActions = codefix.getCodeActionForImport(moduleSymbol, {
|
||||
const sourceDisplay = [textPart(codefix.getModuleSpecifierForNewImport(sourceFile, moduleSymbols, compilerOptions, getCanonicalFileName, host))];
|
||||
const codeActions = codefix.getCodeActionForImport(moduleSymbols, {
|
||||
host,
|
||||
checker,
|
||||
newLineCharacter: host.getNewLine(),
|
||||
|
@ -500,6 +504,18 @@ namespace ts.Completions {
|
|||
return { sourceDisplay, codeActions };
|
||||
}
|
||||
|
||||
function getAllReExportingModules(exportedSymbol: Symbol, checker: TypeChecker, allSourceFiles: ReadonlyArray<SourceFile>): ReadonlyArray<Symbol> {
|
||||
const result: Symbol[] = [];
|
||||
codefix.forEachExternalModule(checker, allSourceFiles, module => {
|
||||
for (const exported of checker.getExportsOfModule(module)) {
|
||||
if (skipAlias(exported, checker) === exportedSymbol) {
|
||||
result.push(module);
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getCompletionEntrySymbol(
|
||||
typeChecker: TypeChecker,
|
||||
log: (message: string) => void,
|
||||
|
|
|
@ -53,95 +53,48 @@ namespace ts.DocumentHighlights {
|
|||
return [{ fileName: sourceFile.fileName, highlightSpans }];
|
||||
}
|
||||
|
||||
// returns true if 'node' is defined and has a matching 'kind'.
|
||||
function hasKind(node: Node, kind: SyntaxKind) {
|
||||
return node !== undefined && node.kind === kind;
|
||||
}
|
||||
|
||||
// Null-propagating 'parent' function.
|
||||
function parent(node: Node): Node {
|
||||
return node && node.parent;
|
||||
}
|
||||
|
||||
function getHighlightSpans(node: Node, sourceFile: SourceFile): HighlightSpan[] {
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getHighlightSpans(node: Node, sourceFile: SourceFile): HighlightSpan[] | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.IfKeyword:
|
||||
case SyntaxKind.ElseKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.IfStatement)) {
|
||||
return getIfElseOccurrences(<IfStatement>node.parent, sourceFile);
|
||||
}
|
||||
break;
|
||||
return isIfStatement(node.parent) ? getIfElseOccurrences(node.parent, sourceFile) : undefined;
|
||||
case SyntaxKind.ReturnKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.ReturnStatement)) {
|
||||
return highlightSpans(getReturnOccurrences(<ReturnStatement>node.parent));
|
||||
}
|
||||
break;
|
||||
return useParent(node.parent, isReturnStatement, getReturnOccurrences);
|
||||
case SyntaxKind.ThrowKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.ThrowStatement)) {
|
||||
return highlightSpans(getThrowOccurrences(<ThrowStatement>node.parent));
|
||||
}
|
||||
break;
|
||||
return useParent(node.parent, isThrowStatement, getThrowOccurrences);
|
||||
case SyntaxKind.TryKeyword:
|
||||
case SyntaxKind.CatchKeyword:
|
||||
case SyntaxKind.FinallyKeyword:
|
||||
const tryStatement = node.kind === SyntaxKind.CatchKeyword ? parent(parent(node)) : parent(node);
|
||||
if (hasKind(tryStatement, SyntaxKind.TryStatement)) {
|
||||
return highlightSpans(getTryCatchFinallyOccurrences(<TryStatement>tryStatement, sourceFile));
|
||||
}
|
||||
break;
|
||||
const tryStatement = node.kind === SyntaxKind.CatchKeyword ? node.parent.parent : node.parent;
|
||||
return useParent(tryStatement, isTryStatement, getTryCatchFinallyOccurrences);
|
||||
case SyntaxKind.SwitchKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.SwitchStatement)) {
|
||||
return highlightSpans(getSwitchCaseDefaultOccurrences(<SwitchStatement>node.parent));
|
||||
}
|
||||
break;
|
||||
return useParent(node.parent, isSwitchStatement, getSwitchCaseDefaultOccurrences);
|
||||
case SyntaxKind.CaseKeyword:
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
if (hasKind(parent(parent(parent(node))), SyntaxKind.SwitchStatement)) {
|
||||
return highlightSpans(getSwitchCaseDefaultOccurrences(<SwitchStatement>node.parent.parent.parent));
|
||||
}
|
||||
break;
|
||||
return useParent(node.parent.parent.parent, isSwitchStatement, getSwitchCaseDefaultOccurrences);
|
||||
case SyntaxKind.BreakKeyword:
|
||||
case SyntaxKind.ContinueKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.BreakStatement) || hasKind(node.parent, SyntaxKind.ContinueStatement)) {
|
||||
return highlightSpans(getBreakOrContinueStatementOccurrences(<BreakOrContinueStatement>node.parent));
|
||||
}
|
||||
break;
|
||||
return useParent(node.parent, isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences);
|
||||
case SyntaxKind.ForKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.ForStatement) ||
|
||||
hasKind(node.parent, SyntaxKind.ForInStatement) ||
|
||||
hasKind(node.parent, SyntaxKind.ForOfStatement)) {
|
||||
return highlightSpans(getLoopBreakContinueOccurrences(<IterationStatement>node.parent));
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.WhileKeyword:
|
||||
case SyntaxKind.DoKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.WhileStatement) || hasKind(node.parent, SyntaxKind.DoStatement)) {
|
||||
return highlightSpans(getLoopBreakContinueOccurrences(<IterationStatement>node.parent));
|
||||
}
|
||||
break;
|
||||
return useParent(node.parent, (n): n is IterationStatement => isIterationStatement(n, /*lookInLabeledStatements*/ true), getLoopBreakContinueOccurrences);
|
||||
case SyntaxKind.ConstructorKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.Constructor)) {
|
||||
return highlightSpans(getConstructorOccurrences(<ConstructorDeclaration>node.parent));
|
||||
}
|
||||
break;
|
||||
return useParent(node.parent, isConstructorDeclaration, getConstructorOccurrences);
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
if (hasKind(node.parent, SyntaxKind.GetAccessor) || hasKind(node.parent, SyntaxKind.SetAccessor)) {
|
||||
return highlightSpans(getGetAndSetOccurrences(<AccessorDeclaration>node.parent));
|
||||
}
|
||||
break;
|
||||
return useParent(node.parent, isAccessor, getGetAndSetOccurrences);
|
||||
default:
|
||||
if (isModifierKind(node.kind) && node.parent &&
|
||||
(isDeclaration(node.parent) || node.parent.kind === SyntaxKind.VariableStatement)) {
|
||||
return highlightSpans(getModifierOccurrences(node.kind, node.parent));
|
||||
}
|
||||
return isModifierKind(node.kind) && (isDeclaration(node.parent) || isVariableStatement(node.parent))
|
||||
? highlightSpans(getModifierOccurrences(node.kind, node.parent))
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function highlightSpans(nodes: Node[]): HighlightSpan[] {
|
||||
function useParent<T extends Node>(node: Node, nodeTest: (node: Node) => node is T, getNodes: (node: T, sourceFile: SourceFile) => Node[] | undefined): HighlightSpan[] | undefined {
|
||||
return nodeTest(node) ? highlightSpans(getNodes(node, sourceFile)) : undefined;
|
||||
}
|
||||
|
||||
function highlightSpans(nodes: Node[] | undefined): HighlightSpan[] | undefined {
|
||||
return nodes && nodes.map(node => getHighlightSpanForNode(node, sourceFile));
|
||||
}
|
||||
}
|
||||
|
@ -156,23 +109,21 @@ namespace ts.DocumentHighlights {
|
|||
return statementAccumulator;
|
||||
|
||||
function aggregate(node: Node): void {
|
||||
if (node.kind === SyntaxKind.ThrowStatement) {
|
||||
statementAccumulator.push(<ThrowStatement>node);
|
||||
if (isThrowStatement(node)) {
|
||||
statementAccumulator.push(node);
|
||||
}
|
||||
else if (node.kind === SyntaxKind.TryStatement) {
|
||||
const tryStatement = <TryStatement>node;
|
||||
|
||||
if (tryStatement.catchClause) {
|
||||
aggregate(tryStatement.catchClause);
|
||||
else if (isTryStatement(node)) {
|
||||
if (node.catchClause) {
|
||||
aggregate(node.catchClause);
|
||||
}
|
||||
else {
|
||||
// Exceptions thrown within a try block lacking a catch clause
|
||||
// are "owned" in the current context.
|
||||
aggregate(tryStatement.tryBlock);
|
||||
aggregate(node.tryBlock);
|
||||
}
|
||||
|
||||
if (tryStatement.finallyBlock) {
|
||||
aggregate(tryStatement.finallyBlock);
|
||||
if (node.finallyBlock) {
|
||||
aggregate(node.finallyBlock);
|
||||
}
|
||||
}
|
||||
// Do not cross function boundaries.
|
||||
|
@ -236,11 +187,11 @@ namespace ts.DocumentHighlights {
|
|||
}
|
||||
|
||||
function getBreakOrContinueOwner(statement: BreakOrContinueStatement): Node {
|
||||
for (let node = statement.parent; node; node = node.parent) {
|
||||
return findAncestor(statement, node => {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SwitchStatement:
|
||||
if (statement.kind === SyntaxKind.ContinueStatement) {
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.ForStatement:
|
||||
|
@ -248,20 +199,13 @@ namespace ts.DocumentHighlights {
|
|||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
if (!statement.label || isLabeledBy(node, statement.label.text)) {
|
||||
return node;
|
||||
}
|
||||
break;
|
||||
return !statement.label || isLabeledBy(node, statement.label.text);
|
||||
default:
|
||||
// Don't cross function boundaries.
|
||||
if (isFunctionLike(node)) {
|
||||
return undefined;
|
||||
}
|
||||
break;
|
||||
// TODO: GH#20090
|
||||
return (isFunctionLike(node) && "quit") as false | "quit";
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
function getModifierOccurrences(modifier: SyntaxKind, declaration: Node): Node[] {
|
||||
|
@ -494,16 +438,14 @@ namespace ts.DocumentHighlights {
|
|||
return keywords;
|
||||
}
|
||||
|
||||
function getReturnOccurrences(returnStatement: ReturnStatement): Node[] {
|
||||
function getReturnOccurrences(returnStatement: ReturnStatement): Node[] | undefined {
|
||||
const func = <FunctionLikeDeclaration>getContainingFunction(returnStatement);
|
||||
|
||||
// If we didn't find a containing function with a block body, bail out.
|
||||
if (!(func && hasKind(func.body, SyntaxKind.Block))) {
|
||||
if (!func) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const keywords: Node[] = [];
|
||||
forEachReturnStatement(<Block>func.body, returnStatement => {
|
||||
forEachReturnStatement(cast(func.body, isBlock), returnStatement => {
|
||||
pushKeywordIf(keywords, returnStatement.getFirstToken(), SyntaxKind.ReturnKeyword);
|
||||
});
|
||||
|
||||
|
@ -516,32 +458,7 @@ namespace ts.DocumentHighlights {
|
|||
}
|
||||
|
||||
function getIfElseOccurrences(ifStatement: IfStatement, sourceFile: SourceFile): HighlightSpan[] {
|
||||
const keywords: Node[] = [];
|
||||
|
||||
// Traverse upwards through all parent if-statements linked by their else-branches.
|
||||
while (hasKind(ifStatement.parent, SyntaxKind.IfStatement) && (<IfStatement>ifStatement.parent).elseStatement === ifStatement) {
|
||||
ifStatement = <IfStatement>ifStatement.parent;
|
||||
}
|
||||
|
||||
// Now traverse back down through the else branches, aggregating if/else keywords of if-statements.
|
||||
while (ifStatement) {
|
||||
const children = ifStatement.getChildren();
|
||||
pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword);
|
||||
|
||||
// Generally the 'else' keyword is second-to-last, so we traverse backwards.
|
||||
for (let i = children.length - 1; i >= 0; i--) {
|
||||
if (pushKeywordIf(keywords, children[i], SyntaxKind.ElseKeyword)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasKind(ifStatement.elseStatement, SyntaxKind.IfStatement)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ifStatement = <IfStatement>ifStatement.elseStatement;
|
||||
}
|
||||
|
||||
const keywords = getIfElseKeywords(ifStatement, sourceFile);
|
||||
const result: HighlightSpan[] = [];
|
||||
|
||||
// We'd like to highlight else/ifs together if they are only separated by whitespace
|
||||
|
@ -551,17 +468,17 @@ namespace ts.DocumentHighlights {
|
|||
const elseKeyword = keywords[i];
|
||||
const ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword.
|
||||
|
||||
let shouldCombindElseAndIf = true;
|
||||
let shouldCombineElseAndIf = true;
|
||||
|
||||
// Avoid recalculating getStart() by iterating backwards.
|
||||
for (let j = ifKeyword.getStart() - 1; j >= elseKeyword.end; j--) {
|
||||
for (let j = ifKeyword.getStart(sourceFile) - 1; j >= elseKeyword.end; j--) {
|
||||
if (!isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) {
|
||||
shouldCombindElseAndIf = false;
|
||||
shouldCombineElseAndIf = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldCombindElseAndIf) {
|
||||
if (shouldCombineElseAndIf) {
|
||||
result.push({
|
||||
fileName: sourceFile.fileName,
|
||||
textSpan: createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end),
|
||||
|
@ -579,6 +496,36 @@ namespace ts.DocumentHighlights {
|
|||
return result;
|
||||
}
|
||||
|
||||
function getIfElseKeywords(ifStatement: IfStatement, sourceFile: SourceFile): Node[] {
|
||||
const keywords: Node[] = [];
|
||||
|
||||
// Traverse upwards through all parent if-statements linked by their else-branches.
|
||||
while (isIfStatement(ifStatement.parent) && ifStatement.parent.elseStatement === ifStatement) {
|
||||
ifStatement = ifStatement.parent;
|
||||
}
|
||||
|
||||
// Now traverse back down through the else branches, aggregating if/else keywords of if-statements.
|
||||
while (true) {
|
||||
const children = ifStatement.getChildren(sourceFile);
|
||||
pushKeywordIf(keywords, children[0], SyntaxKind.IfKeyword);
|
||||
|
||||
// Generally the 'else' keyword is second-to-last, so we traverse backwards.
|
||||
for (let i = children.length - 1; i >= 0; i--) {
|
||||
if (pushKeywordIf(keywords, children[i], SyntaxKind.ElseKeyword)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ifStatement.elseStatement || !isIfStatement(ifStatement.elseStatement)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ifStatement = ifStatement.elseStatement;
|
||||
}
|
||||
|
||||
return keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not a 'node' is preceded by a label of the given string.
|
||||
* Note: 'node' cannot be a SourceFile.
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace ts.refactor.installTypesForPackage {
|
|||
const { file, startPosition } = context;
|
||||
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
|
||||
if (isStringLiteral(node) && isModuleIdentifier(node) && getResolvedModule(file, node.text) === undefined) {
|
||||
return codefix.tryGetCodeActionForInstallPackageTypes(context.host, node.text);
|
||||
return codefix.tryGetCodeActionForInstallPackageTypes(context.host, file.fileName, node.text);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1887,18 +1887,21 @@ namespace ts {
|
|||
});
|
||||
}
|
||||
|
||||
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
function applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
|
||||
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(path, a))) : applySingleCodeActionCommand(path, action);
|
||||
function applyCodeActionCommand(fileName: Path | CodeActionCommand | CodeActionCommand[], actionOrUndefined?: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
|
||||
const action = typeof fileName === "string" ? actionOrUndefined! : fileName as CodeActionCommand[];
|
||||
return isArray(action) ? Promise.all(action.map(applySingleCodeActionCommand)) : applySingleCodeActionCommand(action);
|
||||
}
|
||||
|
||||
function applySingleCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
|
||||
function applySingleCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
|
||||
switch (action.type) {
|
||||
case "install package":
|
||||
return host.installPackage
|
||||
? host.installPackage({ fileName, packageName: action.packageName })
|
||||
? host.installPackage({ fileName: toPath(action.file, currentDirectory, getCanonicalFileName), packageName: action.packageName })
|
||||
: Promise.reject("Host does not implement `installPackage`");
|
||||
default:
|
||||
Debug.fail();
|
||||
|
|
|
@ -293,8 +293,14 @@ namespace ts {
|
|||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
|
||||
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
|
||||
|
@ -406,6 +412,7 @@ namespace ts {
|
|||
export type CodeActionCommand = InstallPackageAction;
|
||||
|
||||
export interface InstallPackageAction {
|
||||
/* @internal */ file: string;
|
||||
/* @internal */ type: "install package";
|
||||
/* @internal */ packageName: string;
|
||||
}
|
||||
|
|
|
@ -2992,6 +2992,7 @@ declare namespace ts {
|
|||
function isForOfStatement(node: Node): node is ForOfStatement;
|
||||
function isContinueStatement(node: Node): node is ContinueStatement;
|
||||
function isBreakStatement(node: Node): node is BreakStatement;
|
||||
function isBreakOrContinueStatement(node: Node): node is BreakOrContinueStatement;
|
||||
function isReturnStatement(node: Node): node is ReturnStatement;
|
||||
function isWithStatement(node: Node): node is WithStatement;
|
||||
function isSwitchStatement(node: Node): node is SwitchStatement;
|
||||
|
@ -3974,8 +3975,14 @@ declare namespace ts {
|
|||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
|
||||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
|
||||
|
@ -5274,7 +5281,7 @@ declare namespace ts.server.protocol {
|
|||
*/
|
||||
errorCodes?: number[];
|
||||
}
|
||||
interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
|
||||
interface ApplyCodeActionCommandRequestArgs {
|
||||
/** May also be an array of commands. */
|
||||
command: {};
|
||||
}
|
||||
|
@ -6915,12 +6922,13 @@ declare namespace ts.server {
|
|||
fileName: NormalizedPath;
|
||||
project: Project;
|
||||
}
|
||||
interface EventSender {
|
||||
event<T>(payload: T, eventName: string): void;
|
||||
}
|
||||
type CommandNames = protocol.CommandTypes;
|
||||
const CommandNames: any;
|
||||
function formatMessage<T extends protocol.Message>(msg: T, logger: server.Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string;
|
||||
type Event = <T>(body: T, eventName: string) => void;
|
||||
interface EventSender {
|
||||
event: Event;
|
||||
}
|
||||
interface SessionOptions {
|
||||
host: ServerHost;
|
||||
cancellationToken: ServerCancellationToken;
|
||||
|
@ -6930,6 +6938,9 @@ declare namespace ts.server {
|
|||
byteLength: (buf: string, encoding?: string) => number;
|
||||
hrtime: (start?: number[]) => number[];
|
||||
logger: Logger;
|
||||
/**
|
||||
* If falsy, all events are suppressed.
|
||||
*/
|
||||
canUseEvents: boolean;
|
||||
eventHandler?: ProjectServiceEventHandler;
|
||||
throttleWaitMilliseconds?: number;
|
||||
|
@ -6943,21 +6954,22 @@ declare namespace ts.server {
|
|||
private changeSeq;
|
||||
private currentRequestId;
|
||||
private errorCheck;
|
||||
private eventHandler;
|
||||
private host;
|
||||
protected host: ServerHost;
|
||||
private readonly cancellationToken;
|
||||
protected readonly typingsInstaller: ITypingsInstaller;
|
||||
private byteLength;
|
||||
protected byteLength: (buf: string, encoding?: string) => number;
|
||||
private hrtime;
|
||||
protected logger: Logger;
|
||||
private canUseEvents;
|
||||
protected canUseEvents: boolean;
|
||||
private eventHandler;
|
||||
constructor(opts: SessionOptions);
|
||||
private sendRequestCompletedEvent(requestId);
|
||||
private defaultEventHandler(event);
|
||||
private projectsUpdatedInBackgroundEvent(openFiles);
|
||||
logError(err: Error, cmd: string): void;
|
||||
send(msg: protocol.Message): void;
|
||||
event<T>(info: T, eventName: string): void;
|
||||
event<T>(body: T, eventName: string): void;
|
||||
/** @deprecated */
|
||||
output(info: any, cmdName: string, reqSeq?: number, errorMsg?: string): void;
|
||||
private doOutput(info, cmdName, reqSeq, success, message?);
|
||||
private semanticCheck(file, project);
|
||||
|
|
|
@ -3045,6 +3045,7 @@ declare namespace ts {
|
|||
function isForOfStatement(node: Node): node is ForOfStatement;
|
||||
function isContinueStatement(node: Node): node is ContinueStatement;
|
||||
function isBreakStatement(node: Node): node is BreakStatement;
|
||||
function isBreakOrContinueStatement(node: Node): node is BreakOrContinueStatement;
|
||||
function isReturnStatement(node: Node): node is ReturnStatement;
|
||||
function isWithStatement(node: Node): node is WithStatement;
|
||||
function isSwitchStatement(node: Node): node is SwitchStatement;
|
||||
|
@ -3974,8 +3975,14 @@ declare namespace ts {
|
|||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
|
||||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
/** @deprecated `fileName` will be ignored */
|
||||
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
|
||||
|
|
|
@ -19,6 +19,7 @@ verify.codeFixAvailable([{
|
|||
description: "Install '@types/abs'",
|
||||
commands: [{
|
||||
type: "install package",
|
||||
file: "/a.ts",
|
||||
packageName: "@types/abs",
|
||||
}],
|
||||
}]);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// Test that the completion is for the shortest path, even if that's a re-export.
|
||||
// Note that `source` in completionEntries will still be the original exporting path, but we use the re-export in completionDetails.
|
||||
|
||||
// @moduleResolution: node
|
||||
// @module: commonJs
|
||||
|
||||
// @Filename: /foo/index.ts
|
||||
////export { foo } from "./lib/foo";
|
||||
|
||||
// @Filename: /foo/lib/foo.ts
|
||||
////export const foo = 0;
|
||||
|
||||
// @Filename: /user.ts
|
||||
////fo/**/
|
||||
|
||||
goTo.marker("");
|
||||
const options = { includeExternalModuleExports: true, sourceDisplay: "./foo" };
|
||||
verify.completionListContains({ name: "foo", source: "/foo/lib/foo" }, "const foo: 0", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true, options);
|
||||
verify.not.completionListContains({ name: "foo", source: "/foo/index" }, undefined, undefined, undefined, undefined, undefined, options);
|
||||
|
||||
verify.applyCodeActionFromCompletion("", {
|
||||
name: "foo",
|
||||
source: "/foo/lib/foo",
|
||||
description: `Import 'foo' from "./foo".`,
|
||||
// TODO: GH#18445
|
||||
newFileContent: `import { foo } from "./foo";\r
|
||||
\r
|
||||
fo`,
|
||||
});
|
Loading…
Reference in a new issue