mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Implemented support for trigger characters in signature help.
This commit is contained in:
+28
-21
@@ -1435,16 +1435,15 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifyNoSignatureHelp(markers: ReadonlyArray<string>) {
|
||||
public verifyNoSignatureHelp(triggerCharacter: ts.SignatureHelpTriggerCharacter | undefined, markers: ReadonlyArray<string>) {
|
||||
if (markers.length) {
|
||||
for (const marker of markers) {
|
||||
this.goToMarker(marker);
|
||||
this.verifyNoSignatureHelp(ts.emptyArray);
|
||||
this.verifyNoSignatureHelp(triggerCharacter, ts.emptyArray);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const actual = this.getSignatureHelp();
|
||||
const actual = this.getSignatureHelp({ triggerCharacter });
|
||||
if (actual) {
|
||||
this.raiseError(`Expected no signature help, but got "${stringify(actual)}"`);
|
||||
}
|
||||
@@ -1465,7 +1464,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
private verifySignatureHelpWorker(options: FourSlashInterface.VerifySignatureHelpOptions) {
|
||||
const help = this.getSignatureHelp()!;
|
||||
const help = this.getSignatureHelp({ triggerCharacter: options.triggerCharacter })!;
|
||||
const selectedItem = help.items[help.selectedItemIndex];
|
||||
// Argument index may exceed number of parameters
|
||||
const currentParameter = selectedItem.parameters[help.argumentIndex] as ts.SignatureHelpParameter | undefined;
|
||||
@@ -1507,6 +1506,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
const allKeys: ReadonlyArray<keyof FourSlashInterface.VerifySignatureHelpOptions> = [
|
||||
"marker",
|
||||
"triggerCharacter",
|
||||
"overloadsCount",
|
||||
"docComment",
|
||||
"text",
|
||||
@@ -1733,7 +1733,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public printCurrentParameterHelp() {
|
||||
const help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
|
||||
const help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition, /*options*/ undefined);
|
||||
Harness.IO.log(stringify(help));
|
||||
}
|
||||
|
||||
@@ -1774,12 +1774,14 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public printCurrentSignatureHelp() {
|
||||
const help = this.getSignatureHelp()!;
|
||||
const help = this.getSignatureHelp(ts.emptyOptions)!;
|
||||
Harness.IO.log(stringify(help.items[help.selectedItemIndex]));
|
||||
}
|
||||
|
||||
private getSignatureHelp(): ts.SignatureHelpItems | undefined {
|
||||
return this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
|
||||
private getSignatureHelp({ triggerCharacter }: FourSlashInterface.VerifySignatureHelpOptions): ts.SignatureHelpItems | undefined {
|
||||
return this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition, {
|
||||
triggerCharacter
|
||||
});
|
||||
}
|
||||
|
||||
public printCompletionListMembers(preferences: ts.UserPreferences | undefined) {
|
||||
@@ -1875,13 +1877,13 @@ Actual: ${stringify(fullActual)}`);
|
||||
offset++;
|
||||
|
||||
if (highFidelity) {
|
||||
if (ch === "(" || ch === ",") {
|
||||
if (ch === "(" || ch === "," || ch === "<") {
|
||||
/* Signature help*/
|
||||
this.languageService.getSignatureHelpItems(this.activeFile.fileName, offset);
|
||||
this.languageService.getSignatureHelpItems(this.activeFile.fileName, offset, { triggerCharacter: ch });
|
||||
}
|
||||
else if (prevChar === " " && /A-Za-z_/.test(ch)) {
|
||||
/* Completions */
|
||||
this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset, ts.defaultPreferences);
|
||||
this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset, ts.emptyOptions);
|
||||
}
|
||||
|
||||
if (i % checkCadence === 0) {
|
||||
@@ -2514,7 +2516,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
`Expected '${fixId}'. Available action ids: ${ts.mapDefined(this.getCodeFixes(this.activeFile.fileName), a => a.fixId)}`);
|
||||
ts.Debug.assertEqual(fixWithId!.fixAllDescription, fixAllDescription);
|
||||
|
||||
const { changes, commands } = this.languageService.getCombinedCodeFix({ type: "file", fileName: this.activeFile.fileName }, fixId, this.formatCodeSettings, ts.defaultPreferences);
|
||||
const { changes, commands } = this.languageService.getCombinedCodeFix({ type: "file", fileName: this.activeFile.fileName }, fixId, this.formatCodeSettings, ts.emptyOptions);
|
||||
assert.deepEqual<ReadonlyArray<{}> | undefined>(commands, expectedCommands);
|
||||
assert(changes.every(c => c.fileName === this.activeFile.fileName), "TODO: support testing codefixes that touch multiple files");
|
||||
this.applyChanges(changes);
|
||||
@@ -2594,7 +2596,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
* Rerieves a codefix satisfying the parameters, or undefined if no such codefix is found.
|
||||
* @param fileName Path to file where error should be retrieved from.
|
||||
*/
|
||||
private getCodeFixes(fileName: string, errorCode?: number, preferences: ts.UserPreferences = ts.defaultPreferences): ts.CodeFixAction[] {
|
||||
private getCodeFixes(fileName: string, errorCode?: number, preferences: ts.UserPreferences = ts.emptyOptions): ts.CodeFixAction[] {
|
||||
const diagnosticsForCodeFix = this.getDiagnostics(fileName, /*includeSuggestions*/ true).map(diagnostic => ({
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
@@ -3072,7 +3074,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.raiseError(`Expected action description to be ${JSON.stringify(actionDescription)}, got: ${JSON.stringify(action.description)}`);
|
||||
}
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactorName, actionName, ts.defaultPreferences)!;
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactorName, actionName, ts.emptyOptions)!;
|
||||
for (const edit of editInfo.edits) {
|
||||
this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false);
|
||||
}
|
||||
@@ -3124,7 +3126,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
const action = ts.first(refactor.actions);
|
||||
assert(action.name === "Move to a new file" && action.description === "Move to a new file");
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactor.name, action.name, options.preferences || ts.defaultPreferences)!;
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactor.name, action.name, options.preferences || ts.emptyOptions)!;
|
||||
this.testNewFileContents(editInfo.edits, options.newFileContents);
|
||||
}
|
||||
|
||||
@@ -3162,14 +3164,14 @@ Actual: ${stringify(fullActual)}`);
|
||||
formattingOptions = formattingOptions || this.formatCodeSettings;
|
||||
const markerPos = this.getMarkerByName(markerName).position;
|
||||
|
||||
const applicableRefactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, markerPos, ts.defaultPreferences);
|
||||
const applicableRefactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, markerPos, ts.emptyOptions);
|
||||
const applicableRefactorToApply = ts.find(applicableRefactors, refactor => refactor.name === refactorNameToApply);
|
||||
|
||||
if (!applicableRefactorToApply) {
|
||||
this.raiseError(`The expected refactor: ${refactorNameToApply} is not available at the marker location.`);
|
||||
}
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, formattingOptions, markerPos, refactorNameToApply, actionName, ts.defaultPreferences)!;
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, formattingOptions, markerPos, refactorNameToApply, actionName, ts.emptyOptions)!;
|
||||
|
||||
for (const edit of editInfo.edits) {
|
||||
this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false);
|
||||
@@ -3358,11 +3360,11 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public getEditsForFileRename(options: FourSlashInterface.GetEditsForFileRenameOptions): void {
|
||||
const changes = this.languageService.getEditsForFileRename(options.oldPath, options.newPath, this.formatCodeSettings, ts.defaultPreferences);
|
||||
const changes = this.languageService.getEditsForFileRename(options.oldPath, options.newPath, this.formatCodeSettings, ts.emptyOptions);
|
||||
this.testNewFileContents(changes, options.newFileContents);
|
||||
}
|
||||
|
||||
private getApplicableRefactors(positionOrRange: number | ts.TextRange, preferences = ts.defaultPreferences): ReadonlyArray<ts.ApplicableRefactorInfo> {
|
||||
private getApplicableRefactors(positionOrRange: number | ts.TextRange, preferences = ts.emptyOptions): ReadonlyArray<ts.ApplicableRefactorInfo> {
|
||||
return this.languageService.getApplicableRefactors(this.activeFile.fileName, positionOrRange, preferences) || ts.emptyArray;
|
||||
}
|
||||
}
|
||||
@@ -4038,7 +4040,11 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
public noSignatureHelp(...markers: string[]): void {
|
||||
this.state.verifyNoSignatureHelp(markers);
|
||||
this.state.verifyNoSignatureHelp(/*triggerCharacter*/ undefined, markers);
|
||||
}
|
||||
|
||||
public noSignatureHelpForTriggerCharacter(triggerCharacter: ts.SignatureHelpTriggerCharacter, ...markers: string[]): void {
|
||||
this.state.verifyNoSignatureHelp(triggerCharacter, markers);
|
||||
}
|
||||
|
||||
public signatureHelp(...options: VerifySignatureHelpOptions[]): void {
|
||||
@@ -4765,6 +4771,7 @@ namespace FourSlashInterface {
|
||||
readonly isVariadic?: boolean;
|
||||
/** @default ts.emptyArray */
|
||||
readonly tags?: ReadonlyArray<ts.JSDocTagInfo>;
|
||||
readonly triggerCharacter?: ts.SignatureHelpTriggerCharacter;
|
||||
}
|
||||
|
||||
export type ArrayOrSingle<T> = T | ReadonlyArray<T>;
|
||||
|
||||
@@ -434,8 +434,8 @@ namespace Harness.LanguageService {
|
||||
getBreakpointStatementAtPosition(fileName: string, position: number): ts.TextSpan {
|
||||
return unwrapJSONCallResult(this.shim.getBreakpointStatementAtPosition(fileName, position));
|
||||
}
|
||||
getSignatureHelpItems(fileName: string, position: number): ts.SignatureHelpItems {
|
||||
return unwrapJSONCallResult(this.shim.getSignatureHelpItems(fileName, position));
|
||||
getSignatureHelpItems(fileName: string, position: number, options: ts.SignatureHelpItemsOptions | undefined): ts.SignatureHelpItems {
|
||||
return unwrapJSONCallResult(this.shim.getSignatureHelpItems(fileName, position, options));
|
||||
}
|
||||
getRenameInfo(fileName: string, position: number): ts.RenameInfo {
|
||||
return unwrapJSONCallResult(this.shim.getRenameInfo(fileName, position));
|
||||
|
||||
@@ -471,7 +471,7 @@ namespace ts.server {
|
||||
|
||||
this.hostConfiguration = {
|
||||
formatCodeOptions: getDefaultFormatCodeSettings(this.host),
|
||||
preferences: defaultPreferences,
|
||||
preferences: emptyOptions,
|
||||
hostInfo: "Unknown host",
|
||||
extraFileExtensions: []
|
||||
};
|
||||
|
||||
@@ -1787,6 +1787,10 @@ namespace ts.server.protocol {
|
||||
* Optional prefix to apply to possible completions.
|
||||
*/
|
||||
prefix?: string;
|
||||
/**
|
||||
* Character that was responsible for triggering completion.
|
||||
* Should be `undefined` if a user manually requested completion.
|
||||
*/
|
||||
triggerCharacter?: CompletionsTriggerCharacter;
|
||||
/**
|
||||
* @deprecated Use UserPreferences.includeCompletionsForModuleExports
|
||||
@@ -2048,10 +2052,17 @@ namespace ts.server.protocol {
|
||||
argumentCount: number;
|
||||
}
|
||||
|
||||
export type SignatureHelpTriggerCharacter = "," | "(" | "<";
|
||||
|
||||
/**
|
||||
* Arguments of a signature help request.
|
||||
*/
|
||||
export interface SignatureHelpRequestArgs extends FileLocationRequestArgs {
|
||||
/**
|
||||
* Character that was responsible for triggering signature help.
|
||||
* Should be `undefined` if a user manually requested completion.
|
||||
*/
|
||||
triggerCharacter?: SignatureHelpTriggerCharacter;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -419,7 +419,7 @@ namespace ts.server {
|
||||
|
||||
if (preferences) {
|
||||
if (!this.preferences) {
|
||||
this.preferences = defaultPreferences;
|
||||
this.preferences = emptyOptions;
|
||||
}
|
||||
this.preferences = { ...this.preferences, ...preferences };
|
||||
}
|
||||
|
||||
@@ -1398,7 +1398,7 @@ namespace ts.server {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
const helpItems = project.getLanguageService().getSignatureHelpItems(file, position);
|
||||
const helpItems = project.getLanguageService().getSignatureHelpItems(file, position, args);
|
||||
if (!helpItems) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
+10
-10
@@ -1425,7 +1425,7 @@ namespace ts {
|
||||
return [...program.getOptionsDiagnostics(cancellationToken), ...program.getGlobalDiagnostics(cancellationToken)];
|
||||
}
|
||||
|
||||
function getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions = defaultPreferences): CompletionInfo | undefined {
|
||||
function getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions = emptyOptions): CompletionInfo | undefined {
|
||||
// Convert from deprecated options names to new names
|
||||
const fullPreferences: UserPreferences = {
|
||||
...identity<UserPreferences>(options), // avoid excess property check
|
||||
@@ -1443,7 +1443,7 @@ namespace ts {
|
||||
options.triggerCharacter);
|
||||
}
|
||||
|
||||
function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions: FormatCodeSettings | undefined, source: string | undefined, preferences: UserPreferences = defaultPreferences): CompletionEntryDetails | undefined {
|
||||
function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions: FormatCodeSettings | undefined, source: string | undefined, preferences: UserPreferences = emptyOptions): CompletionEntryDetails | undefined {
|
||||
synchronizeHostData();
|
||||
return Completions.getCompletionEntryDetails(
|
||||
program,
|
||||
@@ -1769,12 +1769,12 @@ namespace ts {
|
||||
/**
|
||||
* This is a semantic operation.
|
||||
*/
|
||||
function getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems | undefined {
|
||||
function getSignatureHelpItems(fileName: string, position: number, { triggerCharacter }: SignatureHelpItemsOptions = emptyOptions): SignatureHelpItems | undefined {
|
||||
synchronizeHostData();
|
||||
|
||||
const sourceFile = getValidSourceFile(fileName);
|
||||
|
||||
return SignatureHelp.getSignatureHelpItems(program, sourceFile, position, cancellationToken);
|
||||
return SignatureHelp.getSignatureHelpItems(program, sourceFile, position, triggerCharacter, cancellationToken);
|
||||
}
|
||||
|
||||
/// Syntactic features
|
||||
@@ -1953,7 +1953,7 @@ namespace ts {
|
||||
return [];
|
||||
}
|
||||
|
||||
function getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings, preferences: UserPreferences = defaultPreferences): ReadonlyArray<CodeFixAction> {
|
||||
function getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): ReadonlyArray<CodeFixAction> {
|
||||
synchronizeHostData();
|
||||
const sourceFile = getValidSourceFile(fileName);
|
||||
const span = createTextSpanFromBounds(start, end);
|
||||
@@ -1965,7 +1965,7 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences = defaultPreferences): CombinedCodeActions {
|
||||
function getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): CombinedCodeActions {
|
||||
synchronizeHostData();
|
||||
Debug.assert(scope.type === "file");
|
||||
const sourceFile = getValidSourceFile(scope.fileName);
|
||||
@@ -1974,7 +1974,7 @@ namespace ts {
|
||||
return codefix.getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext, preferences });
|
||||
}
|
||||
|
||||
function organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences = defaultPreferences): ReadonlyArray<FileTextChanges> {
|
||||
function organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): ReadonlyArray<FileTextChanges> {
|
||||
synchronizeHostData();
|
||||
Debug.assert(scope.type === "file");
|
||||
const sourceFile = getValidSourceFile(scope.fileName);
|
||||
@@ -1983,7 +1983,7 @@ namespace ts {
|
||||
return OrganizeImports.organizeImports(sourceFile, formatContext, host, program, preferences);
|
||||
}
|
||||
|
||||
function getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences = defaultPreferences): ReadonlyArray<FileTextChanges> {
|
||||
function getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): ReadonlyArray<FileTextChanges> {
|
||||
return ts.getEditsForFileRename(getProgram()!, oldFilePath, newFilePath, host, formatting.getFormatContext(formatOptions), preferences);
|
||||
}
|
||||
|
||||
@@ -2233,7 +2233,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences = defaultPreferences): ApplicableRefactorInfo[] {
|
||||
function getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences = emptyOptions): ApplicableRefactorInfo[] {
|
||||
synchronizeHostData();
|
||||
const file = getValidSourceFile(fileName);
|
||||
return refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange, preferences));
|
||||
@@ -2245,7 +2245,7 @@ namespace ts {
|
||||
positionOrRange: number | TextRange,
|
||||
refactorName: string,
|
||||
actionName: string,
|
||||
preferences: UserPreferences = defaultPreferences,
|
||||
preferences: UserPreferences = emptyOptions,
|
||||
): RefactorEditInfo | undefined {
|
||||
synchronizeHostData();
|
||||
const file = getValidSourceFile(fileName);
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace ts {
|
||||
getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): string;
|
||||
getBreakpointStatementAtPosition(fileName: string, position: number): string;
|
||||
|
||||
getSignatureHelpItems(fileName: string, position: number): string;
|
||||
getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): string;
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded value of the type:
|
||||
@@ -769,10 +769,10 @@ namespace ts {
|
||||
|
||||
/// SIGNATUREHELP
|
||||
|
||||
public getSignatureHelpItems(fileName: string, position: number): string {
|
||||
public getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): string {
|
||||
return this.forwardJSONCall(
|
||||
`getSignatureHelpItems('${fileName}', ${position})`,
|
||||
() => this.languageService.getSignatureHelpItems(fileName, position)
|
||||
() => this.languageService.getSignatureHelpItems(fileName, position, options)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ts.SignatureHelp {
|
||||
argumentCount: number;
|
||||
}
|
||||
|
||||
export function getSignatureHelpItems(program: Program, sourceFile: SourceFile, position: number, cancellationToken: CancellationToken): SignatureHelpItems | undefined {
|
||||
export function getSignatureHelpItems(program: Program, sourceFile: SourceFile, position: number, triggerCharacter: SignatureHelpTriggerCharacter | undefined, cancellationToken: CancellationToken): SignatureHelpItems | undefined {
|
||||
const typeChecker = program.getTypeChecker();
|
||||
|
||||
// Decide whether to show signature help
|
||||
@@ -29,6 +29,11 @@ namespace ts.SignatureHelp {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// In the middle of a string, don't provide signature help unless the user explicitly requested it.
|
||||
if (triggerCharacter !== undefined && isInString(sourceFile, position, startingToken)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile);
|
||||
if (!argumentInfo) return undefined;
|
||||
|
||||
|
||||
+16
-3
@@ -242,7 +242,7 @@ namespace ts {
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
}
|
||||
/* @internal */
|
||||
export const defaultPreferences: UserPreferences = {};
|
||||
export const emptyOptions = {};
|
||||
|
||||
//
|
||||
// Public services of a language service instance associated
|
||||
@@ -292,7 +292,7 @@ namespace ts {
|
||||
|
||||
getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan | undefined;
|
||||
|
||||
getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems | undefined;
|
||||
getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): SignatureHelpItems | undefined;
|
||||
|
||||
getRenameInfo(fileName: string, position: number): RenameInfo;
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] | undefined;
|
||||
@@ -371,7 +371,10 @@ namespace ts {
|
||||
export type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<";
|
||||
|
||||
export interface GetCompletionsAtPositionOptions extends UserPreferences {
|
||||
/** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */
|
||||
/**
|
||||
* If the editor is asking for completions because a certain character was typed
|
||||
* (as opposed to when the user explicitly requested them) this should be set.
|
||||
*/
|
||||
triggerCharacter?: CompletionsTriggerCharacter;
|
||||
/** @deprecated Use includeCompletionsForModuleExports */
|
||||
includeExternalModuleExports?: boolean;
|
||||
@@ -379,6 +382,16 @@ namespace ts {
|
||||
includeInsertTextCompletions?: boolean;
|
||||
}
|
||||
|
||||
export type SignatureHelpTriggerCharacter = "," | "(" | "<";
|
||||
|
||||
export interface SignatureHelpItemsOptions {
|
||||
/**
|
||||
* If the editor is asking for signature help because a certain character was typed
|
||||
* (as opposed to when the user explicitly requested them) this should be set.
|
||||
*/
|
||||
triggerCharacter?: SignatureHelpTriggerCharacter;
|
||||
}
|
||||
|
||||
export interface ApplyCodeActionCommandResult {
|
||||
successMessage: string;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace ts {
|
||||
`;
|
||||
it("can cancel signature help mid-request", () => {
|
||||
verifyOperationCancelledAfter(file, 4, service => // Two calls are top-level in services, one is the root type, and the second should be for the parameter type
|
||||
service.getSignatureHelpItems("file.ts", file.lastIndexOf("f"))!,
|
||||
service.getSignatureHelpItems("file.ts", file.lastIndexOf("f"), emptyOptions)!,
|
||||
r => assert.exists(r.items[0])
|
||||
);
|
||||
});
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace ts {
|
||||
endPosition: selectionRange.end,
|
||||
host: notImplementedHost,
|
||||
formatContext: formatting.getFormatContext(testFormatOptions),
|
||||
preferences: defaultPreferences,
|
||||
preferences: emptyOptions,
|
||||
};
|
||||
const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromRange(selectionRange));
|
||||
assert.equal(rangeToExtract.errors, undefined, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText);
|
||||
@@ -188,7 +188,7 @@ namespace ts {
|
||||
endPosition: selectionRange.end,
|
||||
host: notImplementedHost,
|
||||
formatContext: formatting.getFormatContext(testFormatOptions),
|
||||
preferences: defaultPreferences,
|
||||
preferences: emptyOptions,
|
||||
};
|
||||
const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromRange(selectionRange));
|
||||
assert.isUndefined(rangeToExtract.errors, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText);
|
||||
|
||||
@@ -270,7 +270,7 @@ export const Other = 1;
|
||||
content: "function F() { }",
|
||||
};
|
||||
const languageService = makeLanguageService(testFile);
|
||||
const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatOptions, defaultPreferences);
|
||||
const changes = languageService.organizeImports({ type: "file", fileName: testFile.path }, testFormatOptions, emptyOptions);
|
||||
assert.isEmpty(changes);
|
||||
});
|
||||
|
||||
@@ -741,7 +741,7 @@ export * from "lib";
|
||||
function runBaseline(baselinePath: string, testFile: TestFSWithWatch.File, ...otherFiles: TestFSWithWatch.File[]) {
|
||||
const { path: testPath, content: testContent } = testFile;
|
||||
const languageService = makeLanguageService(testFile, ...otherFiles);
|
||||
const changes = languageService.organizeImports({ type: "file", fileName: testPath }, testFormatOptions, defaultPreferences);
|
||||
const changes = languageService.organizeImports({ type: "file", fileName: testPath }, testFormatOptions, emptyOptions);
|
||||
assert.equal(changes.length, 1);
|
||||
assert.equal(changes[0].fileName, testPath);
|
||||
|
||||
|
||||
@@ -1497,13 +1497,13 @@ namespace ts.projectSystem {
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]);
|
||||
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, defaultPreferences)!;
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, emptyOptions)!;
|
||||
// should contain completions for string
|
||||
assert.isTrue(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'");
|
||||
assert.isFalse(completions1.entries.some(e => e.name === "toExponential"), "should not contain 'toExponential'");
|
||||
|
||||
service.closeClientFile(f2.path);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, defaultPreferences)!;
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, emptyOptions)!;
|
||||
// should contain completions for string
|
||||
assert.isFalse(completions2.entries.some(e => e.name === "charAt"), "should not contain 'charAt'");
|
||||
assert.isTrue(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'");
|
||||
@@ -1529,11 +1529,11 @@ namespace ts.projectSystem {
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]);
|
||||
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, defaultPreferences)!;
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, emptyOptions)!;
|
||||
assert.isTrue(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'");
|
||||
|
||||
service.closeClientFile(f2.path);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, defaultPreferences)!;
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, emptyOptions)!;
|
||||
assert.isFalse(completions2.entries.some(e => e.name === "somelongname"), "should not contain 'somelongname'");
|
||||
const sf2 = service.externalProjects[0].getLanguageService().getProgram()!.getSourceFile(f2.path)!;
|
||||
assert.equal(sf2.text, "");
|
||||
@@ -2173,7 +2173,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// Check identifiers defined in HTML content are available in .ts file
|
||||
const project = configuredProjectAt(projectService, 0);
|
||||
let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, defaultPreferences);
|
||||
let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, emptyOptions);
|
||||
assert(completions && completions.entries[0].name === "hello", `expected entry hello to be in completion list`);
|
||||
|
||||
// Close HTML file
|
||||
@@ -2187,7 +2187,7 @@ namespace ts.projectSystem {
|
||||
checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]);
|
||||
|
||||
// Check identifiers defined in HTML content are not available in .ts file
|
||||
completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, defaultPreferences);
|
||||
completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, emptyOptions);
|
||||
assert(completions && completions.entries[0].name !== "hello", `unexpected hello entry in completion list`);
|
||||
});
|
||||
|
||||
@@ -8613,7 +8613,7 @@ new C();`
|
||||
|
||||
Debug.assert(!!project.resolveModuleNames);
|
||||
|
||||
const edits = project.getLanguageService().getEditsForFileRename("/old.ts", "/new.ts", testFormatOptions, defaultPreferences);
|
||||
const edits = project.getLanguageService().getEditsForFileRename("/old.ts", "/new.ts", testFormatOptions, emptyOptions);
|
||||
assert.deepEqual<ReadonlyArray<FileTextChanges>>(edits, [{
|
||||
fileName: "/user.ts",
|
||||
textChanges: [{
|
||||
|
||||
@@ -262,7 +262,8 @@ declare namespace FourSlashInterface {
|
||||
rangesAreRenameLocations(options?: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges?: Range[] });
|
||||
findReferencesDefinitionDisplayPartsAtCaretAre(expected: ts.SymbolDisplayPart[]): void;
|
||||
noSignatureHelp(...markers: string[]): void;
|
||||
signatureHelp(...options: VerifySignatureHelpOptions[]): void;
|
||||
noSignatureHelpForTriggerCharacter(triggerCharacter: string, ...markers: string[]): void
|
||||
signatureHelp(...options: VerifySignatureHelpOptions[], ): void;
|
||||
// Checks that there are no compile errors.
|
||||
noErrors(): void;
|
||||
numberOfErrorsInCurrentFile(expected: number): void;
|
||||
@@ -560,6 +561,7 @@ declare namespace FourSlashInterface {
|
||||
argumentCount?: number;
|
||||
isVariadic?: boolean;
|
||||
tags?: ReadonlyArray<JSDocTagInfo>;
|
||||
triggerCharacter?: string;
|
||||
}
|
||||
|
||||
interface JSDocTagInfo {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function foo<T>(x: T): T {
|
||||
//// throw null;
|
||||
////}
|
||||
////
|
||||
////foo("/**/")
|
||||
|
||||
goTo.marker();
|
||||
for (const triggerCharacter of ["<", "(", ","]) {
|
||||
edit.insert(triggerCharacter);
|
||||
verify.noSignatureHelpForTriggerCharacter(triggerCharacter);
|
||||
edit.backspace();
|
||||
}
|
||||
verify.signatureHelp({ triggerCharacter: undefined });
|
||||
Reference in New Issue
Block a user