|
|
|
@ -279,7 +279,7 @@ export function migrate(source, { filename, use_ts } = {}) {
|
|
|
|
|
type = `interface ${type_name} {${newline_separator}${state.props
|
|
|
|
|
.map((prop) => {
|
|
|
|
|
const comment = prop.comment ? `${prop.comment}${newline_separator}` : '';
|
|
|
|
|
return `${comment}${prop.exported}${prop.optional ? '?' : ''}: ${prop.type};`;
|
|
|
|
|
return `${comment}${prop.exported}${prop.optional ? '?' : ''}: ${prop.type};${prop.trailing_comment ? ' ' + prop.trailing_comment : ''}`;
|
|
|
|
|
})
|
|
|
|
|
.join(newline_separator)}`;
|
|
|
|
|
if (analysis.uses_props || analysis.uses_rest_props) {
|
|
|
|
@ -289,7 +289,7 @@ export function migrate(source, { filename, use_ts } = {}) {
|
|
|
|
|
} else {
|
|
|
|
|
type = `/**\n${indent} * @typedef {Object} ${type_name}${state.props
|
|
|
|
|
.map((prop) => {
|
|
|
|
|
return `\n${indent} * @property {${prop.type}} ${prop.optional ? `[${prop.exported}]` : prop.exported}${prop.comment ? ` - ${prop.comment}` : ''}`;
|
|
|
|
|
return `\n${indent} * @property {${prop.type}} ${prop.optional ? `[${prop.exported}]` : prop.exported}${prop.comment ? ` - ${prop.comment}` : ''}${prop.trailing_comment ? ` - ${prop.trailing_comment.trim()}` : ''}`;
|
|
|
|
|
})
|
|
|
|
|
.join(``)}\n${indent} */`;
|
|
|
|
|
}
|
|
|
|
@ -414,7 +414,7 @@ export function migrate(source, { filename, use_ts } = {}) {
|
|
|
|
|
* analysis: ComponentAnalysis;
|
|
|
|
|
* filename?: string;
|
|
|
|
|
* indent: string;
|
|
|
|
|
* props: Array<{ local: string; exported: string; init: string; bindable: boolean; slot_name?: string; optional: boolean; type: string; comment?: string; type_only?: boolean; needs_refine_type?: boolean; }>;
|
|
|
|
|
* props: Array<{ local: string; exported: string; init: string; bindable: boolean; slot_name?: string; optional: boolean; type: string; comment?: string; trailing_comment?: string; type_only?: boolean; needs_refine_type?: boolean; }>;
|
|
|
|
|
* props_insertion_point: number;
|
|
|
|
|
* has_props_rune: boolean;
|
|
|
|
|
* has_type_or_fallback: boolean;
|
|
|
|
@ -1497,13 +1497,28 @@ function extract_type_and_comment(declarator, state, path) {
|
|
|
|
|
str.update(comment_start, comment_end, '');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find trailing comments
|
|
|
|
|
const trailing_comment_node = /** @type {Node} */ (parent)?.trailingComments?.at(0);
|
|
|
|
|
const trailing_comment_start = /** @type {any} */ (trailing_comment_node)?.start;
|
|
|
|
|
const trailing_comment_end = /** @type {any} */ (trailing_comment_node)?.end;
|
|
|
|
|
let trailing_comment =
|
|
|
|
|
trailing_comment_node && str.original.substring(trailing_comment_start, trailing_comment_end);
|
|
|
|
|
|
|
|
|
|
if (trailing_comment_node) {
|
|
|
|
|
str.update(trailing_comment_start, trailing_comment_end, '');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (declarator.id.typeAnnotation) {
|
|
|
|
|
state.has_type_or_fallback = true;
|
|
|
|
|
let start = declarator.id.typeAnnotation.start + 1; // skip the colon
|
|
|
|
|
while (str.original[start] === ' ') {
|
|
|
|
|
start++;
|
|
|
|
|
}
|
|
|
|
|
return { type: str.original.substring(start, declarator.id.typeAnnotation.end), comment };
|
|
|
|
|
return {
|
|
|
|
|
type: str.original.substring(start, declarator.id.typeAnnotation.end),
|
|
|
|
|
comment,
|
|
|
|
|
trailing_comment
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let cleaned_comment_arr = comment
|
|
|
|
@ -1526,12 +1541,43 @@ function extract_type_and_comment(declarator, state, path) {
|
|
|
|
|
?.slice(0, first_at_comment !== -1 ? first_at_comment : cleaned_comment_arr.length)
|
|
|
|
|
.join('\n');
|
|
|
|
|
|
|
|
|
|
let cleaned_comment_arr_trailing = trailing_comment
|
|
|
|
|
?.split('\n')
|
|
|
|
|
.map((line) =>
|
|
|
|
|
line
|
|
|
|
|
.trim()
|
|
|
|
|
// replace `// ` for one liners
|
|
|
|
|
.replace(/^\/\/\s*/g, '')
|
|
|
|
|
// replace `\**` for the initial JSDoc
|
|
|
|
|
.replace(/^\/\*\*?\s*/g, '')
|
|
|
|
|
// migrate `*/` for the end of JSDoc
|
|
|
|
|
.replace(/\s*\*\/$/g, '')
|
|
|
|
|
// remove any initial `* ` to clean the comment
|
|
|
|
|
.replace(/^\*\s*/g, '')
|
|
|
|
|
)
|
|
|
|
|
.filter(Boolean);
|
|
|
|
|
const first_at_comment_trailing = cleaned_comment_arr_trailing?.findIndex((line) =>
|
|
|
|
|
line.startsWith('@')
|
|
|
|
|
);
|
|
|
|
|
let cleaned_comment_trailing = cleaned_comment_arr_trailing
|
|
|
|
|
?.slice(
|
|
|
|
|
0,
|
|
|
|
|
first_at_comment_trailing !== -1
|
|
|
|
|
? first_at_comment_trailing
|
|
|
|
|
: cleaned_comment_arr_trailing.length
|
|
|
|
|
)
|
|
|
|
|
.join('\n');
|
|
|
|
|
|
|
|
|
|
// try to find a comment with a type annotation, hinting at jsdoc
|
|
|
|
|
if (parent?.type === 'ExportNamedDeclaration' && comment_node) {
|
|
|
|
|
state.has_type_or_fallback = true;
|
|
|
|
|
const match = /@type {(.+)}/.exec(comment_node.value);
|
|
|
|
|
if (match) {
|
|
|
|
|
return { type: match[1], comment: cleaned_comment };
|
|
|
|
|
return {
|
|
|
|
|
type: match[1],
|
|
|
|
|
comment: cleaned_comment,
|
|
|
|
|
trailing_comment: cleaned_comment_trailing
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1540,11 +1586,19 @@ function extract_type_and_comment(declarator, state, path) {
|
|
|
|
|
state.has_type_or_fallback = true; // only assume type if it's trivial to infer - else someone would've added a type annotation
|
|
|
|
|
const type = typeof declarator.init.value;
|
|
|
|
|
if (type === 'string' || type === 'number' || type === 'boolean') {
|
|
|
|
|
return { type, comment: state.uses_ts ? comment : cleaned_comment };
|
|
|
|
|
return {
|
|
|
|
|
type,
|
|
|
|
|
comment: state.uses_ts ? comment : cleaned_comment,
|
|
|
|
|
trailing_comment: state.uses_ts ? trailing_comment : cleaned_comment_trailing
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { type: 'any', comment: state.uses_ts ? comment : cleaned_comment };
|
|
|
|
|
return {
|
|
|
|
|
type: 'any',
|
|
|
|
|
comment: state.uses_ts ? comment : cleaned_comment,
|
|
|
|
|
trailing_comment: state.uses_ts ? trailing_comment : cleaned_comment_trailing
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ensure modifiers are applied in the same order as Svelte 4
|
|
|
|
@ -1779,10 +1833,13 @@ function handle_identifier(node, state, path) {
|
|
|
|
|
comment = state.str.original.substring(comment_node.start, comment_node.end);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const trailing_comment = member.trailingComments?.at(0)?.value;
|
|
|
|
|
|
|
|
|
|
if (prop) {
|
|
|
|
|
prop.type = type;
|
|
|
|
|
prop.optional = member.optional;
|
|
|
|
|
prop.comment = comment ?? prop.comment;
|
|
|
|
|
prop.trailing_comment = trailing_comment ?? prop.trailing_comment;
|
|
|
|
|
} else {
|
|
|
|
|
state.props.push({
|
|
|
|
|
local: member.key.name,
|
|
|
|
@ -1792,6 +1849,7 @@ function handle_identifier(node, state, path) {
|
|
|
|
|
optional: member.optional,
|
|
|
|
|
type,
|
|
|
|
|
comment,
|
|
|
|
|
trailing_comment,
|
|
|
|
|
type_only: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|