Skip to content

Instantly share code, notes, and snippets.

@Platane
Created March 6, 2017 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Platane/5b2fc3877ea64d8d9f65d810424e830b to your computer and use it in GitHub Desktop.
Save Platane/5b2fc3877ea64d8d9f65d810424e830b to your computer and use it in GitHub Desktop.
write flow anotation from jsdoc comment block
jscodeshift --parser flow -t .\transform.js .\src
var vec2 = {};
/**
* Transforms the vec2 with a mat4
* 3rd vector component is implicitly '0'
* 4th vector component is implicitly '1'
*
* @param {vec2} out the receiving vector
* @param {vec2} a the vector to transform
* @param {mat4} m matrix to transform with
* @returns {vec2} out
*/
vec2.transformMat4 = function(out, a, m) {
var x = a[0],
y = a[1];
out[0] = m[0] * x + m[4] * y + m[12];
out[1] = m[1] * x + m[5] * y + m[13];
return out;
};
const formatType = type => {
switch((type||'').toLowerCase()){
case 'mat2d':
case 'mat2':
case 'mat3':
case 'mat4':
case 'quat':
case 'vec2':
case 'vec3':
case 'vec4':
return capitalize(type)
case 'boolean':
case 'string':
case 'number':
return type.toLowerCase()
case 'object':
return 'Object'
case 'array':
return 'Array<any>'
case 'function':
return '(...args: Array<void>) => <any>'
default:
return null
}
}
const capitalize = s =>
s[0].toUpperCase() + s.slice(1).toLowerCase()
const parseParamLine = line => {
const [ _, type, name, description ] = line.match(/\@\w+\s*\{\s*(\w+)\s*\}\s*(\[?\w+\]?)\s*(.*)/) || []
return {
type : formatType( type ),
name : name && name.replace(/\[\]/g, '').trim(),
optional : name && name[0] == '[',
description,
}
}
const parseJsDoc = comment => {
const lines = comment.split('\n')
return {
params : lines
.filter( x => x.match(/^\s*\*?\s*@param/))
.map( parseParamLine )
,
return : parseParamLine( lines.find( x => x.match(/^\s*\*?\s*@returns/) ) || '' )
}
}
const buildAnotation = ({ type, optional }) =>
( optional ? '?' : '' )+':'+( type || 'any' )
export default function transformer(file, api) {
const j = api.jscodeshift
return j(file.source)
.find(j.Function)
.forEach(p => {
// find the comment block
const statement = p.parent.parent
const comment = statement.value.comments && statement.value.comments[0] && statement.value.comments[0].value
if ( !comment )
return
// extract te type from the comment block
const types = comment ? parseJsDoc( comment ) : { params: [], return: null }
// add types
p.value.params.forEach((p,i) =>
p.typeAnnotation = buildAnotation( types.params[i] )
)
p.value.returnType = buildAnotation( types.return )
})
.toSource()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment