Skip to content

Commit

Permalink
resolves englercj#108 generate dtslint compliant code
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed Jan 2, 2020
1 parent 8e8612c commit 2412aed
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 373 deletions.
95 changes: 80 additions & 15 deletions src/create_helpers.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as ts from 'typescript';
import { warn } from './logger';
import {warn} from './logger';
import {
createFunctionParams,
createFunctionReturnType,
createTypeLiteral,
resolveHeritageClauses,
resolveOptionalFromName,
resolveType,
resolveTypeParameters,
resolveOptionalFromName
resolveTypeParameters
} from './type_resolve_helpers';
import { PropTree } from "./PropTree";
import {PropTree} from "./PropTree";

const declareModifier = ts.createModifier(ts.SyntaxKind.DeclareKeyword);
const constModifier = ts.createModifier(ts.SyntaxKind.ConstKeyword);
Expand Down Expand Up @@ -67,24 +67,89 @@ function validateModuleChildren(children?: ts.Node[])
}
}

function formatMultilineComment(comment: string): string {
return comment.split('\n').join('\n * ');
}

function handlePropsComment(props: IDocletProp[], jsdocTagName: String): string[] {
return props.map(prop => {
if (prop.description) {
let name;
if (prop.optional) {
if (prop.defaultvalue !== undefined) {
name = `[${prop.name} = ${prop.defaultvalue}]`;
} else {
name = `[${prop.name}]`;
}
} else {
name = prop.name;
}
const description = ` - ${formatMultilineComment(prop.description)}`;
return `\n * @${jsdocTagName} ${name}${description}`
}
return ''
}).filter(value => value !== '')
}

function handleReturnsComment(doclet: IDocletBase): string[] {
if ('returns' in doclet) {
return (doclet['returns'] as IDocletReturn[]).map(ret => {
if (ret.description) {
return `\n * @returns ${formatMultilineComment(ret.description)}`;
}
return '';
}).filter(value => value !== '');
}
return []
}

function handleExamplesComment(doclet: IDocletBase): string[] {
if (doclet.examples !== undefined) {
return doclet.examples.map(example => {
return `\n * @example
* ${formatMultilineComment(example)}`;
});
}
return [];
}

function handleParamsComment(doclet: IDocletBase): string[] {
if ('params' in doclet) {
return handlePropsComment((doclet['params'] as IDocletProp[]), 'param');
}
return []
}

function handlePropertiesComment(doclet: IDocletBase): string[] {
if (doclet.properties && (!('isEnum' in doclet) || (doclet['isEnum'] === false))) {
return handlePropsComment(doclet.properties, 'property');
}
return []
}

function handleComment<T extends ts.Node>(doclet: IDocletBase, node: T): T
{
if (doclet.comment && doclet.comment.length > 4)
{
let comment = doclet.comment;

// remove '/*' and '*/'
comment = comment.substring(2, doclet.comment.length - 2);

// remove ' *' leading spaces
comment = comment.replace(/[ \t]+\*/g, ' *');
let description = '';
if (doclet.description) {
description = `\n * ${formatMultilineComment(doclet.description)}`;
} else if ('classdesc' in doclet) {
description = `\n * ${formatMultilineComment((doclet['classdesc'] as string))}`;
}
const examples = handleExamplesComment(doclet);
const properties = handlePropertiesComment(doclet);
const params = handleParamsComment(doclet);
const returns = handleReturnsComment(doclet);

// remove trailing spacesgit dif
comment = comment.trim() + '\n ';
if (description || examples.length > 0 || properties.length > 0 || params.length > 0 || returns.length > 0) {
let comment = `*${description}${examples.join('')}${properties.join('')}${params.join('')}${returns.join('')}
`;

const kind = ts.SyntaxKind.MultiLineCommentTrivia;
const kind = ts.SyntaxKind.MultiLineCommentTrivia;

ts.addSyntheticLeadingComment(node, kind, comment, true);
ts.addSyntheticLeadingComment(node, kind, comment, true);
}
}

return node;
Expand Down
2 changes: 1 addition & 1 deletion src/typings/jsdoc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ declare interface IDocletBase {
memberof?: string;
see?: string;
access?: ('public' | 'private' | 'protected');
examples?: string;
examples?: string[];
deprecated?: string;
defaultvalue?: string;
comment?: string;
Expand Down
135 changes: 23 additions & 112 deletions test/expected/class_all.d.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,21 @@
/**
* @this OtherThing
*/
declare function doStuff(): void;

/**
* @class
* @abstract
*/
declare class OtherThing {
/**
*
*/
copy(): void;
}

/**
*
*/
declare class Stuff {
/**
*
*/
doStuff(): void;
}

/**
*
*/
declare class Things {
/**
*
*/
doThings(): void;
/**
* @method Things#[foobar1]
*/
foobar1?(): void;
/**
* @type {Number}
* @name Things#[foobar2]
*/
foobar2?: number;
}

/**
* Deep class #1
*
* @class
*/
declare class DeepClass1 {
constructor();
Expand All @@ -55,26 +24,20 @@ declare class DeepClass1 {
declare namespace DeepClass1 {
/**
* Deep class #2
*
* @class
*/
class DeepClass2 {
constructor();
}
namespace DeepClass2 {
/**
* Deep class #3
*
* @class
*/
class DeepClass3 {
constructor();
}
namespace DeepClass3 {
/**
* Deep class #4
*
* @class
*/
class DeepClass4 {
constructor();
Expand All @@ -83,35 +46,24 @@ declare namespace DeepClass1 {
}
}

/** @module util
*/
declare module "util" {
/**
* @class MyClass
* @param {string} message
* @returns {MyClass}
*/
class MyClass {
constructor(message: string);
/** @type {string}
*/
message: string;
}
/**
* GitGraph
* @class GitGraph
* @param {object} options - GitGraph options
* @param {string} [options.elementId = "gitGraph"] - Id of the canvas container
* @param {Template|string|object} [options.template] - Template of the graph
* @param {string} [options.author = "Sergio Flores <saxo-guy@epic.com>"] - Default author for commits
* @param {string} [options.mode = (null|"compact")] - Display mode
* @param {HTMLElement} [options.canvas] - DOM canvas (ex: document.getElementById("id"))
* @param {string} [options.orientation = ("vertical-reverse"|"horizontal"|"horizontal-reverse")] - Graph orientation
* @param {boolean} [options.reverseArrow = false] - Make arrows point to ancestors if true
* @param {number} [options.initCommitOffsetX = 0] - Add custom offsetX to initial commit.
* @param {number} [options.initCommitOffsetY = 0] - Add custom offsetY to initial commit.
* @param {HTMLElement} [options.tooltipContainer = document.body] - HTML Element containing tooltips in compact mode.
* @this GitGraph
* @param options - GitGraph options
* @param [options.elementId = "gitGraph"] - Id of the canvas container
* @param [options.template] - Template of the graph
* @param [options.author = "Sergio Flores <saxo-guy@epic.com>"] - Default author for commits
* @param [options.mode = (null|"compact")] - Display mode
* @param [options.canvas] - DOM canvas (ex: document.getElementById("id"))
* @param [options.orientation = ("vertical-reverse"|"horizontal"|"horizontal-reverse")] - Graph orientation
* @param [options.reverseArrow = false] - Make arrows point to ancestors if true
* @param [options.initCommitOffsetX = 0] - Add custom offsetX to initial commit.
* @param [options.initCommitOffsetY = 0] - Add custom offsetY to initial commit.
* @param [options.tooltipContainer = document.body] - HTML Element containing tooltips in compact mode.
*/
class GitGraph {
constructor(options: {
Expand All @@ -127,130 +79,89 @@ declare module "util" {
tooltipContainer?: HTMLElement;
});
}
/**
* @typedef Something
* @type boolean
*/
type Something = boolean;
interface MyThing extends Stuff, Things {
}
/**
* @class MyThing
* @extends OtherThing
* @mixes Stuff
* @mixes Things
*/
class MyThing extends OtherThing implements Stuff, Things {
/**
* Derp or something.
*
* @member {string}
* @readonly
*/
readonly derp: string;
/**
* @member {Object<string, Array<(number|string)>>}
*/
map: {
[key: string]: (number | string)[];
};
/**
* @member {Array<Array.<Array<Array.<string[]>>>>}
*/
superArray: string[][][][][];
/**
* @member {Array}
*/
simpleArray: any[];
/**
* Creates a new thing.
*
* @param {!FoobarNS.CircleOptions} opts - Namespace test!
* @return {MyThing} the new thing.
* @param opts - Namespace test!
* @returns the new thing.
*/
static create(opts: FoobarNS.CircleOptions): MyThing;
/**
* Gets a Promise that will resolve with an Object, or reject with OtherThing
*
* @return {Promise<Object, OtherThing>} The Promise
* @returns The Promise
*/
promiseMe(): Promise<object>;
/**
* Gets a Promise that will resolve with an array of OtherThings
*
* @return {Promise<Array.<OtherThing>>} The Promise
* @returns The Promise
*/
promiseYou(): Promise<OtherThing[]>;
/**
* Gets a Promise that will resolve with a bunch of possible types
*
* @return {Promise<Array.<*>|Object|number|string>} The Promise
* @returns The Promise
*/
promiseFoo(): Promise<any[] | object | number | string>;
/**
* Gets a Promise that will resolve with an object with complex properties
*
* @return {Promise<{newChannels: Channel[], foo: Bar}>} The Promise
* @returns The Promise
*/
promiseBar(): Promise<{ newChannels: Channel[]; foo: Bar; }>;
/**
* Gets a Promise that will resolve with a generic function
*
* @return {Promise<Function>} The Promise
* @returns The Promise
*/
promiseGenericFunc(): Promise<(...params: any[]) => void>;
/**
* Gets a Promise that will resolve with a function with no arguments
* that returns a string.
*
* @return {Promise<Function(): string>} The Promise
* @returns The Promise
*/
promiseStringFunc(): Promise<(...params: any[]) => string>;
/**
* Gets a Promise that will resolve with a function with lots of arguments
* that returns an object.
*
* @return {Promise<Function(Array.<OtherThing>, object, number, string): object>} The Promise
* @returns The Promise
*/
promiseLotsArgsFunc(): Promise<(arg0: OtherThing[], arg1: object, arg2: number, arg3: string) => object>;
/**
* Gets a Promise that will resolve with a function with lots of arguments
* that returns the default type.
*
* @return {Promise<Function(Array.<OtherThing>, object, number, string)>} The Promise
* @returns The Promise
*/
promiseDefaultRetFunc(): Promise<(arg0: OtherThing[], arg1: object, arg2: number, arg3: string) => void>;
/**
* A param that is a function
* Note: doesn't matter what I put, a @param only gets "FUNCTION" from jsdoc
* @param {function(number): object}
*/
takeFuncParam(f: (...params: any[]) => any): void;
/**
* A param that is a complex function
* Note: doesn't matter what I put, a @param only gets "FUNCTION" from jsdoc
* @param {function(Array.<OtherThing>, object, number): object}
*/
takeFuncParamComplex(f: (...params: any[]) => any): void;
/**
*
* @param {GitGraphOptions} options - GitGraph options
* @param options - GitGraph options
*/
objParam(options: GitGraphOptions): void;
/**
* Gets derp.
*
* @member {string}
*/
D: string;
/**
* @member {number}
* @static
*/
static me: number;
/**
* @param {OtherThing} other - To copy from.
* @override
* @param other - To copy from.
*/
copy(other: OtherThing): void;
}
Expand Down
Loading

0 comments on commit 2412aed

Please sign in to comment.