Skip to content

Commit

Permalink
(feat) show doc for props (hover/completion) (#529)
Browse files Browse the repository at this point in the history
  • Loading branch information
dummdidumm committed Sep 7, 2020
1 parent a630dea commit cc2fc95
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 34 deletions.
66 changes: 59 additions & 7 deletions packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import ts from 'typescript';

export interface IExportedNames {
has(name: string): boolean;
}
Expand All @@ -9,34 +11,84 @@ export class ExportedNames
type?: string;
identifierText?: string;
required?: boolean;
doc?: string;
}
>
implements IExportedNames {
/**
* Adds export to map
*/
addExport(
name: ts.BindingName,
target: ts.BindingName = null,
type: ts.TypeNode = null,
required = false,
): void {
if (name.kind != ts.SyntaxKind.Identifier) {
throw Error('export source kind not supported ' + name);
}
if (target && target.kind != ts.SyntaxKind.Identifier) {
throw Error('export target kind not supported ' + target);
}

if (target) {
this.set(name.text, {
type: type?.getText(),
identifierText: (target as ts.Identifier).text,
required,
doc: this.getDoc(target),
});
} else {
this.set(name.text, {});
}
}

private getDoc(target: ts.BindingName) {
let doc = undefined;
// Traverse `a` up to `export let a`
const exportExpr = target?.parent?.parent?.parent;

if (exportExpr) {
const fileText = exportExpr.getSourceFile().getFullText();
const comment = ts.getLeadingCommentRanges(fileText, exportExpr.getFullStart());

if (comment) {
doc = fileText.substring(comment[0].pos, comment[0].end);
}
}

return doc;
}

/**
* Creates a string from the collected props
*
* @param isTsFile Whether this is a TypeScript file or not.
*/
createPropsStr(isTsFile: boolean) {
const names = Array.from(this.entries());
const dontAddTypeDef =
!isTsFile ||
names.length === 0 ||
names.every(([_, value]) => !value.type && value.required);

const returnElements = names.map(([key, value]) => {
// Important to not use shorthand props for rename functionality
return `${value.identifierText || key}: ${key}`;
return `${dontAddTypeDef && value.doc ? `\n${value.doc}` : ''}${
value.identifierText || key
}: ${key}`;
});

if (
!isTsFile ||
names.length === 0 ||
names.every(([_, value]) => !value.type && value.required)
) {
if (dontAddTypeDef) {
// No exports or only `typeof` exports -> omit the `as {...}` completely.
// If not TS, omit the types to not have a "cannot use types in jsx" error.
return `{${returnElements.join(' , ')}}`;
}

const returnElementsType = names.map(([key, value]) => {
const identifier = `${value.identifierText || key}${value.required ? '' : '?'}`;
const identifier = `${value.doc ? `\n${value.doc}` : ''}${value.identifierText || key}${
value.required ? '' : '?'
}`;
if (!value.type) {
return `${identifier}: typeof ${key}`;
}
Expand Down
30 changes: 4 additions & 26 deletions packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,28 +58,6 @@ export function processInstanceScriptContent(
const pushScope = () => (scope = new Scope(scope));
const popScope = () => (scope = scope.parent);

const addExport = (
name: ts.BindingName,
target: ts.BindingName = null,
type: ts.TypeNode = null,
required = false,
) => {
if (name.kind != ts.SyntaxKind.Identifier) {
throw Error('export source kind not supported ' + name);
}
if (target && target.kind != ts.SyntaxKind.Identifier) {
throw Error('export target kind not supported ' + target);
}
if (target) {
exportedNames.set(name.text, {
type: type?.getText(),
identifierText: (target as ts.Identifier).text,
required,
});
} else {
exportedNames.set(name.text, {});
}
};
const addGetter = (node: ts.Identifier) => {
if (!node) {
return;
Expand Down Expand Up @@ -277,14 +255,14 @@ export function processInstanceScriptContent(
ts.forEachChild(list, (node) => {
if (ts.isVariableDeclaration(node)) {
if (ts.isIdentifier(node.name)) {
addExport(node.name, node.name, node.type, !node.initializer);
exportedNames.addExport(node.name, node.name, node.type, !node.initializer);
} else if (
ts.isObjectBindingPattern(node.name) ||
ts.isArrayBindingPattern(node.name)
) {
ts.forEachChild(node.name, (element) => {
if (ts.isBindingElement(element)) {
addExport(element.name);
exportedNames.addExport(element.name);
}
});
}
Expand Down Expand Up @@ -376,9 +354,9 @@ export function processInstanceScriptContent(
if (ts.isNamedExports(exportClause)) {
for (const ne of exportClause.elements) {
if (ne.propertyName) {
addExport(ne.propertyName, ne.name);
exportedNames.addExport(ne.propertyName, ne.name);
} else {
addExport(ne.name);
exportedNames.addExport(ne.name);
}
}
//we can remove entire statement
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
///<reference types="svelte" />
<></>;function render() {

/**
* DOCS!
*/
let a;
/**
* MORE DOCS!
*/
let b;
let c;
;
() => (<></>);
return { props: {
/**
* DOCS!
*/a: a ,
/**
* MORE DOCS!
*/b: b , c: c}, slots: {}, getters: {}, events: {} }}

export default class Input__SvelteComponent_ extends createSvelte2TsxComponent(__sveltets_partial(__sveltets_with_any_event(render))) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
/**
* DOCS!
*/
export let a;
/**
* MORE DOCS!
*/
export let b;
export let c;
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
world = '';
;
() => (<></>);
return { props: {name: name , world: world}, slots: {}, getters: {}, events: {} }}
return { props: {
/**@type { string | number }*/name: name ,
/**@type { string | number }*/world: world}, slots: {}, getters: {}, events: {} }}

export default class Input__SvelteComponent_ extends createSvelte2TsxComponent(__sveltets_partial(__sveltets_with_any_event(render))) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
///<reference types="svelte" />
<></>;function render() {

/**
* DOCS!
*/
let a: string;
/**
* MORE DOCS!
*/
let b = 1;
let c;
;
() => (<></>);
return { props: {a: a , b: b , c: c} as {
/**
* DOCS!
*/a: string,
/**
* MORE DOCS!
*/b?: typeof b, c: typeof c}, slots: {}, getters: {}, events: {} }}

export default class Input__SvelteComponent_ extends createSvelte2TsxComponent(__sveltets_partial(__sveltets_with_any_event(render))) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
/**
* DOCS!
*/
export let a: string;
/**
* MORE DOCS!
*/
export let b = 1;
export let c;
</script>

0 comments on commit cc2fc95

Please sign in to comment.