Fix updating detailed completion for overloaded methods (#2633)

* For languages that allow method overloads, where the same method name
can be defined with different arguments (e.g. C++), the `label` of a
completion may be duplicated in the completions list, but the `detail`
should be different.
* Hence use the `detail` field, if available, to disambiguate between
completion items when updating them with the result of a
`completionItem/resolve`.
This commit is contained in:
feltech 2018-10-14 22:31:19 +01:00 committed by Akin
parent ca6a4d1c14
commit fdc740c280
2 changed files with 76 additions and 0 deletions

View File

@ -134,6 +134,16 @@ export const completionResultsReducer: Reducer<ICompletionResults> = (
return {
...state,
completions: state.completions.map(completion => {
// Prefer `detail` field if available, to avoid splatting e.g. methods with
// the same name but different signature.
if (completion.detail && action.completionItemWithDetails.detail) {
if (completion.detail === action.completionItemWithDetails.detail) {
return action.completionItemWithDetails
} else {
return completion
}
}
if (completion.label === action.completionItemWithDetails.label) {
return action.completionItemWithDetails
} else {

View File

@ -0,0 +1,66 @@
import * as assert from "assert"
import * as _ from "lodash"
import { DefaultCompletionResults } from "./../../../src/Services/Completion/CompletionState"
import { completionResultsReducer } from "./../../../src/Services/Completion/CompletionStore"
describe("completionResultsReducer", () => {
let oldState: any
beforeEach(() => {
oldState = _.cloneDeep(DefaultCompletionResults)
})
describe("GET_COMPLETION_ITEM_DETAILS_RESULT", () => {
beforeEach(() => {
oldState.completions = [
{ label: "other" },
{ label: "matchme", detail: "matchme(signature)" },
{ label: "matchme", detail: "other(signature)" },
{ label: "matchme" },
]
})
it("updates relevant items with detailed version by label field", () => {
const completionItemWithDetails = {
label: "matchme",
}
const newState = completionResultsReducer(oldState, {
type: "GET_COMPLETION_ITEM_DETAILS_RESULT",
completionItemWithDetails,
})
assert.deepStrictEqual(newState, {
...oldState,
completions: [
{ label: "other" },
completionItemWithDetails,
completionItemWithDetails,
completionItemWithDetails,
],
})
})
it("updates relevant items with detailed version by detail field", () => {
const completionItemWithDetails = {
label: "matchme",
detail: "matchme(signature)",
}
const newState = completionResultsReducer(oldState, {
type: "GET_COMPLETION_ITEM_DETAILS_RESULT",
completionItemWithDetails,
})
assert.deepStrictEqual(newState, {
...oldState,
completions: [
{ label: "other" },
completionItemWithDetails,
{ label: "matchme", detail: "other(signature)" },
completionItemWithDetails,
],
})
})
})
})