You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
8.1 KiB

6 months ago
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.processProps = exports.transformElement = void 0;
const shared_1 = require("@vue/shared");
const compiler_core_1 = require("@vue/compiler-core");
const uni_shared_1 = require("@dcloudio/uni-shared");
const errors_1 = require("../errors");
const vModel_1 = require("./vModel");
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
const transformElement = (node, context) => {
return function postTransformElement() {
node = context.currentNode;
if (!(node.type === 1 /* NodeTypes.ELEMENT */ &&
(node.tagType === 0 /* ElementTypes.ELEMENT */ ||
node.tagType === 1 /* ElementTypes.COMPONENT */))) {
return;
}
if (node.tagType === 1 /* ElementTypes.COMPONENT */) {
processComponent(node, context);
}
if (context.scopeId) {
addScopeId(node, context.scopeId);
}
const { props } = node;
if (props.length > 0) {
processProps(node, context);
}
};
};
exports.transformElement = transformElement;
function addScopeId(node, scopeId) {
return (0, uni_cli_shared_1.addStaticClass)(node, scopeId);
}
function processComponent(node, context) {
const { tag } = node;
if (context.bindingComponents[tag]) {
return;
}
// 1. dynamic component
if ((0, uni_shared_1.isComponentTag)(tag)) {
return context.onError((0, errors_1.createMPCompilerError)(8 /* MPErrorCodes.X_DYNAMIC_COMPONENT_NOT_SUPPORTED */, node.loc));
}
if ((0, compiler_core_1.findDir)(node, 'is')) {
return context.onError((0, errors_1.createMPCompilerError)(6 /* MPErrorCodes.X_V_IS_NOT_SUPPORTED */, node.loc));
}
// TODO not supported
// const isProp = findProp(node, 'is')
// if (isProp) {
// }
// 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
const builtIn = (0, compiler_core_1.isCoreComponent)(tag) || context.isBuiltInComponent(tag);
if (builtIn) {
return context.onError((0, errors_1.createMPCompilerError)(7 /* MPErrorCodes.X_NOT_SUPPORTED */, node.loc, tag));
}
// 3. user component (from setup bindings)
const fromSetup = resolveSetupReference(tag, context);
if (fromSetup) {
return (context.bindingComponents[tag] = {
name: fromSetup,
type: "setup" /* BindingComponentTypes.SETUP */,
});
}
const dotIndex = tag.indexOf('.');
if (dotIndex > 0) {
return context.onError((0, errors_1.createMPCompilerError)(7 /* MPErrorCodes.X_NOT_SUPPORTED */, node.loc, tag));
}
// 4. Self referencing component (inferred from filename)
if (context.selfName && (0, shared_1.capitalize)((0, shared_1.camelize)(tag)) === context.selfName) {
return (context.bindingComponents[tag] = {
name: (0, compiler_core_1.toValidAssetId)(tag, `component`),
type: "self" /* BindingComponentTypes.SELF */,
});
}
// 5. user component (resolve)
context.bindingComponents[tag] = {
name: (0, compiler_core_1.toValidAssetId)(tag, `component`),
type: "unknown" /* BindingComponentTypes.UNKNOWN */,
};
context.helper(compiler_core_1.RESOLVE_COMPONENT);
}
function resolveSetupReference(name, context) {
const bindings = context.bindingMetadata;
if (!bindings || bindings.__isScriptSetup === false) {
return;
}
const camelName = (0, shared_1.camelize)(name);
const PascalName = (0, shared_1.capitalize)(camelName);
const checkType = (type) => {
if (bindings[name] === type) {
return name;
}
if (bindings[camelName] === type) {
return camelName;
}
if (bindings[PascalName] === type) {
return PascalName;
}
};
const fromConst = checkType("setup-const" /* BindingTypes.SETUP_CONST */) ||
checkType("setup-reactive-const" /* BindingTypes.SETUP_REACTIVE_CONST */);
if (fromConst) {
return context.inline
? // in inline mode, const setup bindings (e.g. imports) can be used as-is
fromConst
: `$setup[${JSON.stringify(fromConst)}]`;
}
const fromMaybeRef = checkType("setup-let" /* BindingTypes.SETUP_LET */) ||
checkType("setup-ref" /* BindingTypes.SETUP_REF */) ||
checkType("setup-maybe-ref" /* BindingTypes.SETUP_MAYBE_REF */);
if (fromMaybeRef) {
return context.inline
? // setup scope bindings that may be refs need to be unrefed
`${context.helperString(compiler_core_1.UNREF)}(${fromMaybeRef})`
: `$setup[${JSON.stringify(fromMaybeRef)}]`;
}
}
function processProps(node, context, props = node.props) {
const { tag } = node;
const isComponent = node.tagType === 1 /* ElementTypes.COMPONENT */;
const isPluginComponent = isComponent && context.isMiniProgramComponent(node.tag) === 'plugin';
for (let i = 0; i < props.length; i++) {
const prop = props[i];
if (prop.type === 7 /* NodeTypes.DIRECTIVE */) {
// directives
const { name, arg, loc } = prop;
const isVBind = name === 'bind';
const isVOn = name === 'on';
// skip v-slot - it is handled by its dedicated transform.
if (name === 'slot') {
if (!isComponent) {
context.onError((0, compiler_core_1.createCompilerError)(40 /* ErrorCodes.X_V_SLOT_MISPLACED */, loc));
}
continue;
}
// skip v-once/v-memo - they are handled by dedicated transforms.
if (name === 'once' || name === 'memo') {
continue;
}
// skip v-is and :is on <component>
if (name === 'is' ||
(isVBind && (0, compiler_core_1.isStaticArgOf)(arg, 'is') && (0, uni_shared_1.isComponentTag)(tag))) {
continue;
}
if (isVBind || isVOn) {
// v-on=""
// v-bind=""
if (!arg) {
if (isVOn) {
context.onError((0, errors_1.createMPCompilerError)(0 /* MPErrorCodes.X_V_ON_NO_ARGUMENT */, loc));
}
if (isVBind && (!isComponent || isPluginComponent)) {
context.onError((0, errors_1.createMPCompilerError)(2 /* MPErrorCodes.X_V_BIND_NO_ARGUMENT */, loc));
}
continue;
}
// v-on:[a]=""
// v-on:[a.b]=""
// v-bind:[a]=""
// v-bind:[a.b]=""
if (!(arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && arg.isStatic)) {
if (isVOn) {
context.onError((0, errors_1.createMPCompilerError)(1 /* MPErrorCodes.X_V_ON_DYNAMIC_EVENT */, loc));
}
if (isVBind && (!isComponent || isPluginComponent)) {
context.onError((0, errors_1.createMPCompilerError)(3 /* MPErrorCodes.X_V_BIND_DYNAMIC_ARGUMENT */, loc));
}
continue;
}
}
const directiveTransform = context.directiveTransforms[name];
if (name !== 'model' && directiveTransform) {
const { props } = directiveTransform(prop, node, context);
if (props.length) {
prop.exp = props[0].value;
}
}
}
}
const transformVModel = (context.directiveTransforms.model ||
vModel_1.transformModel);
processVModel(node, transformVModel, context);
}
exports.processProps = processProps;
function processVModel(node, transformVModel, context) {
const { props } = node;
const dirs = [];
for (let i = 0; i < props.length; i++) {
const prop = props[i];
if (prop.type === 7 /* NodeTypes.DIRECTIVE */ && prop.name === 'model') {
dirs.push(...transformVModel(prop, node, context)
.props);
props.splice(i, 1);
i--;
}
}
if (dirs.length) {
props.push(...dirs);
}
}