import * as template from 'babel-template' ; import * as t from 'babel-types' ; import { transform } from 'babel-core' ; import { codeFrameColumns } from '@babel/code-frame' ; import { camelCase , capitalize } from 'lodash' ; import { NodePath } from 'babel-traverse' ; export function isAliasThis ( p , name ) { const binding = p . scope . getBinding ( name ) ; if ( binding ) { return binding . path . isVariableDeclarator ( ) && binding . path . get ( 'init' ) . isThisExpression ( ) ; } return false ; } export function isValidVarName ( str ? ) { if ( typeof str !== 'string' ) { return false ; } if ( str . trim ( ) !== str ) { return false ; } try { new Function ( str , 'var ' + str ) ; } catch ( e ) { return false ; } return true ; } export function parseCode ( code ) { return ( transform ( code , { parserOpts : { sourceType : 'module' , plugins : [ 'classProperties' , 'jsx' , 'flow' , 'flowComment' , 'trailingFunctionCommas' , 'asyncFunctions' , 'exponentiationOperator' , 'asyncGenerators' , 'objectRestSpread' , 'decorators' , 'dynamicImport' ] } } ) as { ast : t . File ; } ) . ast ; } export const buildTemplate = ( str ) => template ( str ) ( ) . expression as t . Expression ; export function buildBlockElement ( ) { return t . jSXElement ( t . jSXOpeningElement ( t . jSXIdentifier ( 'Block' ) , [ ] ) , t . jSXClosingElement ( t . jSXIdentifier ( 'Block' ) ) , [ ] ) ; } export function pascalName ( s ) { const str = camelCase ( s ) ; return capitalize ( str [ 0 ] ) + str . slice ( 1 ) ; } export function buildRender ( returned , stateKeys , propsKeys , templateType ? ) { const returnStatement = [ t . returnStatement ( returned ) ] ; if ( stateKeys . length ) { const stateDecl = t . variableDeclaration ( 'const' , [ t . variableDeclarator ( t . objectPattern ( Array . from ( new Set ( stateKeys ) ) . filter ( s => ! propsKeys . includes ( s ) ) . map ( s => t . objectProperty ( t . identifier ( s ) , t . identifier ( s ) , false , true ) ) as any ) , t . memberExpression ( t . thisExpression ( ) , t . identifier ( 'data' ) ) ) ] ) ; returnStatement . unshift ( stateDecl ) ; } if ( propsKeys . length ) { let patterns = t . objectPattern ( Array . from ( new Set ( propsKeys ) ) . map ( s => t . objectProperty ( t . identifier ( s ) , t . identifier ( s ) , false , true ) ) as any ) ; if ( typeof templateType === 'string' ) { patterns = t . objectPattern ( [ t . objectProperty ( t . identifier ( 'data' ) , templateType === 'wxParseData' ? t . objectPattern ( [ t . objectProperty ( t . identifier ( 'wxParseData' ) , t . identifier ( 'wxParseData' ) ) as any ] ) as any : t . identifier ( templateType ) ) as any ] ) ; } else if ( Array . isArray ( templateType ) ) { patterns = t . objectPattern ( [ t . objectProperty ( t . identifier ( 'data' ) , patterns as any ) as any ] ) ; } const stateDecl = t . variableDeclaration ( 'const' , [ t . variableDeclarator ( patterns , t . memberExpression ( t . thisExpression ( ) , t . identifier ( 'props' ) ) ) ] ) ; returnStatement . unshift ( stateDecl ) ; } return t . classMethod ( 'method' , t . identifier ( 'render' ) , [ ] , t . blockStatement ( returnStatement ) ) ; } export function buildImportStatement ( source , specifiers = [ ] , defaultSpec ? ) { return t . importDeclaration ( defaultSpec ? [ defaultSpec , ... specifiers ] . map ( ( spec , index ) => { if ( index === 0 ) { return t . importDefaultSpecifier ( t . identifier ( defaultSpec ) ) ; } return t . importSpecifier ( t . identifier ( spec ) , t . identifier ( spec ) ) ; } ) : specifiers . map ( s => t . importSpecifier ( t . identifier ( s ) , t . identifier ( s ) ) ) , t . stringLiteral ( source ) ) ; } export const setting = { sourceCode : '' , rootPath : '' } ; export function codeFrameError ( node , msg ) { let errMsg = '' ; try { errMsg = codeFrameColumns ( setting . sourceCode , node && node . type && node . loc ? node . loc : node ) ; } catch ( error ) { errMsg = 'failed to locate source' ; } return new Error ( `${ msg }
  -----
  ${ errMsg }` ) ; } export const DEFAULT_Component_SET = new Set < string > ( [ 'View' , 'Icon' , 'Progress' , 'RichText' , 'Text' , 'Button' , 'Checkbox' , 'CheckboxGroup' , 'Form' , 'Input' , 'Label' , 'Picker' , 'PickerView' , 'PickerViewColumn' , 'Radio' , 'RadioGroup' , 'Slider' , 'Switch' , 'CoverImage' , 'Textarea' , 'CoverView' , 'MovableArea' , 'MovableView' , 'ScrollView' , 'Swiper' , 'SwiperItem' , 'Navigator' , 'Audio' , 'Camera' , 'Image' , 'LivePlayer' , 'Video' , 'Canvas' , 'Ad' , 'WebView' , 'Block' , 'Map' , 'Slot' , 'SlotView' , 'Editor' , 'MatchMedia' , 'FunctionalPageNavigator' , 'LivePusher' , 'OfficialAccount' , 'OpenData' , 'NavigationBar' , 'PageMeta' , 'VoipRoom' , 'AdCustom' ] ) ;