Skip to content

Commit

Permalink
Merge pull request #207 from zardoy/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
zardoy authored Apr 21, 2024
2 parents aba470c + 23cf01a commit 0ae5b20
Show file tree
Hide file tree
Showing 10 changed files with 4,567 additions and 3,449 deletions.
7,883 changes: 4,460 additions & 3,423 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions typescript/src/codeActions/custom/fixClosingTagName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { matchParents } from '../../utils'
import { CodeAction } from '../getCodeActions'

export default {
id: 'fixOppositeTagName',
kind: 'quickfix',
name: 'Fix opposite tag name',
tryToApply(sourceFile, position, range, node) {
const elem = matchParents(node, ['Identifier', 'JsxOpeningElement']) ?? matchParents(node, ['Identifier', 'JsxClosingElement'])
if (!elem) return
const tagNamesDiffers = elem.parent.openingElement.tagName.getText() !== elem.parent.closingElement.tagName.getText()
if (tagNamesDiffers) {
const isCurrentlyAtOpening = elem.parent.openingElement === elem
const oppositeElem = isCurrentlyAtOpening ? elem.parent.closingElement.tagName : elem.parent.openingElement.tagName
return [
{
start: oppositeElem.getStart(),
length: oppositeElem.getWidth(),
newText: elem.tagName.getText(),
},
]
}
return
},
} satisfies CodeAction
13 changes: 0 additions & 13 deletions typescript/src/codeActions/extended/declareMissingProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,3 @@ export default {
return
},
} as ExtendedCodeAction

const testCode = () => {
const tester = (code: string) => {
// ^ - problem location in which quickfix needs to be tested (applied)
// | - cursor position after quickfix is applied
// [[...]] - applied part of the code
/* TODO */
}

tester(/* ts */ `
const b = ({ b, ^a }: { b[[, a/*|*/]] }) => {}
`)
}
2 changes: 2 additions & 0 deletions typescript/src/codeActions/getCodeActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import declareMissingProperties from './extended/declareMissingProperties'
import { renameParameterToNameFromType, renameAllParametersToNameFromType } from './custom/renameParameterToNameFromType'
import addDestructure_1 from './custom/addDestructure/addDestructure'
import fromDestructure_1 from './custom/fromDestructure/fromDestructure'
import fixClosingTagName from './custom/fixClosingTagName'

const codeActions: CodeAction[] = [
addDestructure_1,
Expand All @@ -19,6 +20,7 @@ const codeActions: CodeAction[] = [
splitDeclarationAndInitialization,
renameParameterToNameFromType,
renameAllParametersToNameFromType,
fixClosingTagName,
]
const extendedCodeActions: ExtendedCodeAction[] = [declareMissingProperties]

Expand Down
6 changes: 6 additions & 0 deletions typescript/src/completions/filterJsxComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ export default (entries: ts.CompletionEntry[], node: ts.Node, position: number,
) {
return
}
// const startLineNode = ts.getLineAndCharacterOfPosition(node.getSourceFile(), node.pos).line
// const startLinePosition = ts.getLineAndCharacterOfPosition(node.getSourceFile(), position).line
// if (startLineNode !== startLinePosition) return
const identifier = ts.isJsxSelfClosingElement(node) || ts.isJsxOpeningElement(node) ? node.tagName : null
// if already got name and we are not typing it
if (identifier && identifier.end < position) return

const nodeText = node.getText().slice(0, position - (node.pos + node.getLeadingTriviaWidth()))
// workaround for <div test |></div>
Expand Down
2 changes: 1 addition & 1 deletion typescript/src/completions/fixPropertiesSorting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default (entries: ts.CompletionEntry[]) => {
const typeChecker = program.getTypeChecker()
let sourceProps: string[]
if (isJsxElem) {
const type = typeChecker.getContextualType((node as ts.JsxOpeningElement).attributes)
const type = typeChecker.getContextualType((targetNode as ts.JsxOpeningElement).attributes)
if (!type) return
// usually component own props defined first like interface Props extends ... {} or type A = Props & ..., but this is not a case with mui...
sourceProps = (type.isIntersection() ? type.types.flatMap(type => type.getProperties()) : type.getProperties()).map(symbol => symbol.name)
Expand Down
14 changes: 13 additions & 1 deletion typescript/src/completions/jsxAttributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default (
sourceFile: ts.SourceFile,
jsxCompletionsMap: Configuration['jsxCompletionsMap'],
): ts.CompletionEntry[] => {
const originalNode = node
// ++ patch with jsxCompletionsMap
// -- don't
// <div| - identifier, not attribute --
Expand Down Expand Up @@ -78,13 +79,24 @@ export default (
const enableJsxAttributesShortcuts = sharedCompletionContext.c('jsxAttributeShortcutCompletions.enable')
if (enableJsxAttributesShortcuts !== 'disable') {
const locals = collectLocalSymbols(node, sharedCompletionContext.typeChecker)
let attrib = originalNode.parent as ts.JsxAttribute | undefined
if (!ts.isJsxAttribute(attrib!)) {
attrib = undefined
}
entries = entries.flatMap(entry => {
if (locals.includes(entry.name)) {
const insertText = `${entry.name}={${entry.name}}`
const additionalSuggestions = {
const pos = attrib ? attrib.end - attrib.getWidth() : 0
const additionalSuggestions: ts.CompletionEntry = {
...entry,
name: insertText,
insertText,
replacementSpan: attrib
? {
start: pos,
length: attrib.end - pos,
}
: undefined,
}
return enableJsxAttributesShortcuts === 'after' ? [entry, additionalSuggestions] : [additionalSuggestions, entry]
}
Expand Down
11 changes: 9 additions & 2 deletions typescript/src/decorateLinkedEditing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
lastLinkedEditingRangeRequest.fileName === fileName
) {
lastLinkedEditingRangeRequest.pos = position
lastLinkedEditingRangeRequest.result.ranges[0]!.length++
const startRange = lastLinkedEditingRangeRequest.result.ranges[0]!
const endRange = lastLinkedEditingRangeRequest.result.ranges[1]!
startRange.length++
lastLinkedEditingRangeRequest.result.ranges[1]!.start++

lastLinkedEditingRangeRequest.result.ranges[1]!.length++
return lastLinkedEditingRangeRequest.result
const leadingText = fileContent.slice(startRange.start, startRange.start + startRange.length)
const endingText = fileContent.slice(endRange.start, endRange.start + endRange.length)
if (leadingText === endingText) {
return lastLinkedEditingRangeRequest.result
}
}
lastLinkedEditingRangeRequest = undefined

Expand Down
58 changes: 50 additions & 8 deletions typescript/test/completions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,21 +527,38 @@ test('Fix properties sorting', () => {
a.b({/*2*/})./*3*/
}
declare function MyComponent(props: { b?; c? } & { a? }): JSX.Element
<MyComponent /*4*/ />;
let a: { b:{}, a() } = {
/*5*/
}
declare function MyComponent(props: { b?; c? } & { a? }): JSX.Element
<MyComponent /*4*/ />;
<MyComponent
c=''
/*41*/
/>;
<MyComponent
test2=''
/*41*/
test=''
/>;
<MyComponent /*42*/
test2=''
/>;
`)
const assertSorted = (marker: number, expected: string[]) => {
const { entriesSorted } = getCompletionsAtPosition(currentTestingContext.markers[marker]!)!
expect(entriesSorted.map(x => x.name)).toEqual(expected)
expect(
entriesSorted.map(x => x.name),
`${marker}`,
).toEqual(expected)
}
assertSorted(1, ['c', 'b'])
assertSorted(2, ['c', 'b'])
assertSorted(3, ['c', 'b'])
assertSorted(4, ['b', 'c', 'a'])
assertSorted(41, ['b', 'c', 'a'])
assertSorted(42, ['b', 'c', 'a'])
assertSorted(5, ['b', 'b', 'a', 'a'])
settingsOverride.fixSuggestionsSorting = false
})
Expand Down Expand Up @@ -570,11 +587,36 @@ testTs5('Change to function kind', () => {
})

testTs5('Filter JSX Components', () => {
const tester = fourslashLikeTester(/* ts */ `
const a = () => {}
a/*1*/
overrideSettings({
// improveJsxCompletions: false,
'experiments.excludeNonJsxCompletions': true,
})
const tester = fourslashLikeTester(/* tsx */ `
const someFunction = () => {}
declare namespace JSX {
interface IntrinsicElements {
superSpan: any;
}
}
// return < // TODO
return <s/*1*/
`)
tester.completion(1, {
excludes: ['someFunction'],
includes: {
names: ['superSpan'],
},
})
// https://github.com/zardoy/typescript-vscode-plugins/issues/205
const tester2 = fourslashLikeTester(/* tsx */ `
const Img = ({ alt }) => {}
<Img\n\t/*1*/\n/>
`)
// TODO
tester2.completion(1, {
includes: {
names: ['alt'],
},
})
})

test('Omit<..., ""> suggestions', () => {
Expand Down
2 changes: 1 addition & 1 deletion typescript/test/testing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export const fourslashLikeTester = (contents: string, fileName = entrypoint, { d
)!
const newContentsActual = tsFull.textChanges.applyChanges(getCurrentFile(), edits[0]!.textChanges)
if (newContent) {
expect(dedentString(newContent), `at marker ${mark}`).toEqual(newContentsActual)
expect(newContentsActual, `at marker ${mark}`).toEqual(dedentString(newContent))
}
return newContentsActual
}
Expand Down

0 comments on commit 0ae5b20

Please sign in to comment.