babel-plugin-flow-type-getter
Advanced tools
Comparing version 1.0.2 to 1.0.3
@@ -33,4 +33,9 @@ class Test1 { | ||
console.log('unary typeof = ', typeof Test1.prop3); | ||
console.log('binary typeof = ', typeof Test1.prop2 == 'string'); | ||
console.log('is_array = ', Array.isArray(Test1.prop5)); | ||
const obj_test = { | ||
t1 : Test1, | ||
t2 : Test2 | ||
} | ||
typeof obj_test.t1.prop8 == 'User'); // false | ||
typeof Test1.prop2 == 'User'); // true | ||
Array.isArray(Test1.prop5)); // false |
134
index.js
@@ -5,5 +5,8 @@ const babylon = require('babylon'); | ||
const { resolve } = require('path'); | ||
const acorn = require('acorn'); | ||
const { generate } = require('astring'); | ||
let class_names_list = []; | ||
const customFunctionName = '__getFlowTypes'; | ||
const COMMENT_CONSTANT = '_____babel-plugin-flow-type-getter-marker-comment____' | ||
@@ -33,13 +36,2 @@ const typeValueGenerator = (typeAnnotation) => { | ||
} | ||
case 'ObjectTypeAnnotation': | ||
const parsed_object = properties.map(({key, value}) => { | ||
const { optional, static } = value; | ||
return `${key.name} :${optional ? '?' : ''}${static ? 'static ' : ''} ${typeValueGenerator(value).stringified}`; | ||
}).join(', '); | ||
return { | ||
stringified : '{ ' + parsed_object + ' }', | ||
is_array : false, | ||
types : ['{ ' + parsed_object + ' }'] | ||
}; | ||
case 'UnionTypeAnnotation': | ||
@@ -96,30 +88,77 @@ const union_types_list = types.map(typeValueGenerator).map(val => val.stringified); | ||
const unaryTypeofReplacementGenerator = (node) => { | ||
const obj_name = node.argument.object.name; | ||
const prop_name = node.argument.property.name; | ||
const expression = `${obj_name}.${customFunctionName}().${prop_name}.stringified`; | ||
const parsed_function = babylon.parse(expression).program.body[0]; | ||
const repeatedNode = (path) => { | ||
const parent = path.findParent(path => path.isReturnStatement()); | ||
return parsed_function; | ||
if( | ||
(parent != null) && | ||
(Array.isArray(parent.node.leadingComments)) && | ||
(parent.node.leadingComments[0].value == COMMENT_CONSTANT) | ||
) { | ||
return true; | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
const binaryTypeofReplacementGenerator = (left, right) => { | ||
const obj_name = left.argument.object.name; | ||
const prop_name = left.argument.property.name; | ||
const right_value = right.value; | ||
const expression = | ||
`${obj_name}.${customFunctionName}(). | ||
${prop_name}.types.find(__type => __type == '${right_value}') != null`; | ||
const parsed_function = babylon.parse(expression).program.body[0]; | ||
const replacementGenerator = (node, replacement_case) => { | ||
let expression, object_string, prop_name, code_expression; | ||
switch(replacement_case) { | ||
case 'unary': | ||
object_string = objectStringGenerator(node.argument.object); | ||
prop_name = node.argument.property.name; | ||
expression = `${object_string}.${customFunctionName}().${prop_name}.stringified`; | ||
code_expression = `typeof ${object_string}.${prop_name}`; | ||
break; | ||
case 'binary': | ||
const { left, right } = node; | ||
object_string = objectStringGenerator(left.argument.object); | ||
prop_name = left.argument.property.name; | ||
const right_value = right.value; | ||
if(/^Array<.*>$/.test(right_value)) { | ||
throw new Error(`Use 'Array.isArray' to check if the value is an array.`) | ||
} | ||
expression = `${object_string}.${customFunctionName}().${prop_name}.types.find(__type => __type == '${right_value}') != null`; | ||
code_expression = `typeof ${object_string}.${prop_name} == ${right_value}`; | ||
break; | ||
case 'array': | ||
const argument = node.arguments[0]; | ||
object_string = objectStringGenerator(argument.object); | ||
prop_name = argument.property.name; | ||
expression = `${object_string}.${customFunctionName}().${prop_name}.is_array`; | ||
code_expression = `Array.isArray(${object_string}.${prop_name})`; | ||
break; | ||
default: | ||
throw new Error( | ||
`Invalid argument passed in babel-plugin-flow-type-getter. | ||
Please report this issue at https://github.com/DavidDionise/babel-plugin-flow-type-getter/issues` | ||
); | ||
return; | ||
} | ||
return parsed_function; | ||
return ( | ||
babylon.parse( | ||
`(() => { | ||
if(${object_string}.__getFlowTypes != null) { | ||
return ${expression}; | ||
} | ||
else { | ||
//${COMMENT_CONSTANT} | ||
return ${code_expression} | ||
} | ||
})()` | ||
).program.body[0] | ||
) | ||
} | ||
const isArrayReplacementGenerator = (argument) => { | ||
const obj_name = argument.object.name; | ||
const prop_name = argument.property.name; | ||
const expression = `${obj_name}.${customFunctionName}().${prop_name}.is_array`; | ||
const parsed_function = babylon.parse(expression).program.body[0]; | ||
return parsed_function; | ||
const objectStringGenerator = (node) => { | ||
if(t.isMemberExpression(node)) { | ||
return `${objectStringGenerator(node.object)}.${node.property.name}`; | ||
} | ||
else if(t.isStringLiteral(node, { computed : true })) { | ||
return `${objectStringGenerator(node.object)}.['${node.property.name}']`; | ||
} | ||
else if(t.isIdentifier(node)) { | ||
return node.name; | ||
} | ||
} | ||
@@ -162,9 +201,8 @@ | ||
if( | ||
path.parent.type != 'BinaryExpression' && | ||
operator == 'typeof' && | ||
argument.type == 'MemberExpression' && | ||
class_names_list.find(c => c == argument.object.name) != null | ||
!repeatedNode(path) && | ||
!t.isBinaryExpression(path.parent, { operator : 'typeof' }) && | ||
t.isMemberExpression(argument) | ||
) { | ||
path.replaceWith( | ||
unaryTypeofReplacementGenerator(path.node) | ||
replacementGenerator(path.node, 'unary') | ||
) | ||
@@ -176,17 +214,11 @@ } | ||
const { left, right, operator } = path.node; | ||
if( | ||
left.type == 'UnaryExpression' && | ||
left.operator && | ||
left.operator == 'typeof' && | ||
left.argument && | ||
left.argument.type == 'MemberExpression' && | ||
(operator == '==' || operator == '===') && | ||
class_names_list.find(cn => cn == left.argument.object.name) != null && | ||
!repeatedNode(path) && | ||
t.isUnaryExpression(left, {operator : 'typeof'}) && | ||
t.isMemberExpression(left.argument) && | ||
right && | ||
right.value | ||
) { | ||
path.replaceWith( | ||
binaryTypeofReplacementGenerator(left, right) | ||
replacementGenerator(path.node, 'binary') | ||
) | ||
@@ -201,2 +233,3 @@ } | ||
if( | ||
!repeatedNode(path) && | ||
object && object.name && | ||
@@ -207,7 +240,6 @@ property && property.name && | ||
arguments && | ||
arguments[0].object && | ||
class_names_list.find(cn => cn == arguments[0].object.name) != null | ||
arguments[0].object | ||
) { | ||
path.replaceWith( | ||
isArrayReplacementGenerator(arguments[0]) | ||
replacementGenerator(path.node, 'array') | ||
) | ||
@@ -214,0 +246,0 @@ } |
{ | ||
"name": "babel-plugin-flow-type-getter", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"description": "Access flow types from uninstantiated classes.", | ||
@@ -23,4 +23,6 @@ "main": "index.js", | ||
"dependencies": { | ||
"acorn": "^5.0.3", | ||
"astring": "^1.0.2", | ||
"babylon": "^6.17.4" | ||
} | ||
} |
@@ -23,16 +23,41 @@ ## Access your Flow types from classes before you instantiate objects. | ||
prop1: number; | ||
prop2: Test2; | ||
prop3: string | Test1; | ||
prop2: Array<User | string>; | ||
prop3: Client; | ||
prop4: boolean; | ||
prop5: Client | User; | ||
prop6: ?Array<number>; | ||
prop7: Array<User>; | ||
prop8: ?{a: string, b: ?number}; | ||
static getType() { | ||
return 'cool'; | ||
} | ||
getTypeTwo() { | ||
return 'yeah'; | ||
} | ||
} | ||
class Test2 { | ||
prop1: string; | ||
prop2: Array<number> | ||
prop3: ?Array<Test1 | string>; | ||
prop1: number; | ||
prop2: Array<User | ID>; | ||
static getType() { | ||
return 'cool'; | ||
} | ||
getTypeTwo() { | ||
return 'yeah'; | ||
} | ||
} | ||
typeof Test1.prop1; // 'number' | ||
typeof Test1.prop3; // 'string | Test1' | ||
typeof Test1.prop2 == 'Test2'; // true | ||
typeof Test2.prop1 == 'Test1'; // false | ||
Array.isArray(Test2.prop3); // true | ||
const obj_test = { | ||
t1 : Test1, | ||
t2 : Test2 | ||
} | ||
typeof obj_test.t1.prop8 == 'User'); // false | ||
typeof Test1.prop2 == 'User'); // true | ||
Array.isArray(Test1.prop5)); // false | ||
```` | ||
@@ -39,0 +64,0 @@ --- |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
71
53165
3
1676
+ Addedacorn@^5.0.3
+ Addedastring@^1.0.2
+ Addedacorn@5.7.4(transitive)
+ Addedastring@1.9.0(transitive)