Skip to content

Commit

Permalink
feat(transformer): 支持 Context.Provider JSX 成员表达式
Browse files Browse the repository at this point in the history
  • Loading branch information
yuche committed May 24, 2019
1 parent 56b4074 commit d5085ea
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 18 deletions.
57 changes: 40 additions & 17 deletions packages/taro-transformer-wx/src/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
isDerivedFromProps,
findFirstIdentifierFromMemberExpression
} from './utils'
import { DEFAULT_Component_SET, COMPONENTS_PACKAGE_NAME, ANONYMOUS_FUNC, DEFAULT_Component_SET_COPY, FN_PREFIX, CLASS_COMPONENT_UID } from './constant'
import { DEFAULT_Component_SET, COMPONENTS_PACKAGE_NAME, ANONYMOUS_FUNC, DEFAULT_Component_SET_COPY, FN_PREFIX, CLASS_COMPONENT_UID, CONTEXT_PROVIDER } from './constant'
import { kebabCase, uniqueId, get as safeGet, set as safeSet } from 'lodash'
import { RenderParser } from './render'
import { findJSXAttrByName } from './jsx'
Expand Down Expand Up @@ -688,23 +688,46 @@ class Transformer {
const id = path.node.openingElement.name
if (
t.isJSXIdentifier(id) &&
!DEFAULT_Component_SET.has(id.name) &&
self.moduleNames.indexOf(id.name) !== -1
!DEFAULT_Component_SET.has(id.name)
) {
const name = id.name
const binding = self.classPath.scope.getBinding(name)
if (binding && t.isImportDeclaration(binding.path.parent)) {
const sourcePath = binding.path.parent.source.value
if (binding.path.isImportDefaultSpecifier()) {
self.customComponents.set(name, {
sourcePath,
type: 'default'
})
} else {
self.customComponents.set(name, {
sourcePath,
type: 'pattern'
})
if (self.moduleNames.indexOf(id.name) !== -1) {
const name = id.name
const binding = self.classPath.scope.getBinding(name)
if (binding && t.isImportDeclaration(binding.path.parent)) {
const sourcePath = binding.path.parent.source.value
if (binding.path.isImportDefaultSpecifier()) {
self.customComponents.set(name, {
sourcePath,
type: 'default'
})
} else {
self.customComponents.set(name, {
sourcePath,
type: 'pattern'
})
}
}
}

if (id.name.endsWith(CONTEXT_PROVIDER)) {
const valueAttr = path.node.openingElement.attributes.find(a => a.name.name === 'value')
const contextName = id.name.slice(0, id.name.length - CONTEXT_PROVIDER.length)
if (valueAttr) {
if (t.isJSXElement(valueAttr.value)) {
throw codeFrameError(valueAttr.value, 'Provider 的 value 只能传入一个字符串或普通表达式,不能传入 JSX')
} else {
const value = t.isStringLiteral(valueAttr.value) ? valueAttr.value : valueAttr.value.expression
const expr = t.expressionStatement(t.callExpression(
t.memberExpression(t.identifier(contextName), t.identifier('Provider')),
[value]
))
path.getStatementParent().insertBefore(expr)
path.replaceWith(t.jSXElement(
t.jSXOpeningElement(t.jSXIdentifier('Block'), []),
t.jSXClosingElement(t.jSXIdentifier('Block')),
path.node.children
))
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/taro-transformer-wx/src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export let LOOP_CALLEE = '$anonymousCallee_'

export let setLoopCallee = (s: string) => LOOP_CALLEE = s

export const CONTEXT_PROVIDER = 'PrivateContextProvider'

export const SPECIAL_COMPONENT_PROPS = new Map<string, Set<string>>()

SPECIAL_COMPONENT_PROPS.set(
Expand Down
20 changes: 19 additions & 1 deletion packages/taro-transformer-wx/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ import {
setLoopState,
PROPS_MANAGER,
GEN_COMP_ID,
GEN_LOOP_COMPID
GEN_LOOP_COMPID,
CONTEXT_PROVIDER
} from './constant'
import { Adapters, setAdapter, Adapter } from './adapter'
import { Options, setTransformOptions, buildBabelTransformOptions } from './options'
Expand Down Expand Up @@ -416,6 +417,23 @@ export default function transform (options: Options): TransformResult {
// const expr = parentPath.get('value.expression')

// },
JSXMemberExpression (path) {
const { property, object } = path.node
if (!t.isJSXIdentifier(property, { name: 'Provider' })) {
throw codeFrameError(property, '只能在使用 Context.Provider 的情况下才能使用 JSX 成员表达式')
}
if (!t.isJSXIdentifier(object)) {
return
}
const jsx = path.parentPath.parentPath
if (jsx.isJSXElement()) {
const componentName = `${object.name}${CONTEXT_PROVIDER}`
jsx.node.openingElement.name = t.jSXIdentifier(componentName)
if (jsx.node.closingElement) {
jsx.node.closingElement.name = t.jSXIdentifier(componentName)
}
}
},
JSXElement (path) {
const assignment = path.findParent(p => p.isAssignmentExpression())
if (assignment && assignment.isAssignmentExpression() && !options.isTyped) {
Expand Down

0 comments on commit d5085ea

Please sign in to comment.