fix: 🐛 更改复杂类型生成工具的接口形式,减少调用复杂度

This commit is contained in:
春希 2020-08-10 14:37:08 +08:00
parent de941da231
commit ce616b53d5
10 changed files with 72 additions and 44 deletions

View File

@ -13,7 +13,7 @@ import {
type PluginConfig = { type PluginConfig = {
fileType: string; fileType: string;
} };
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => { const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
const cfg: PluginConfig = { const cfg: PluginConfig = {
@ -30,9 +30,9 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
if (ir.state) { if (ir.state) {
const state = ir.state; const state = ir.state;
const fields = Object.keys(state).map<string>(stateName => { const fields = Object.keys(state).map<string>((stateName) => {
const [isString, value] = generateCompositeType(state[stateName]); const value = generateCompositeType(state[stateName]);
return `${stateName}: ${isString ? `'${value}'` : value},`; return `${stateName}: ${value},`;
}); });
next.chunks.push({ next.chunks.push({

View File

@ -14,7 +14,7 @@ import {
type PluginConfig = { type PluginConfig = {
fileType: string; fileType: string;
implementType: 'inConstructor' | 'insMember' | 'hooks'; implementType: 'inConstructor' | 'insMember' | 'hooks';
} };
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => { const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
const cfg: PluginConfig = { const cfg: PluginConfig = {
@ -32,9 +32,9 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
if (ir.state) { if (ir.state) {
const state = ir.state; const state = ir.state;
const fields = Object.keys(state).map<string>(stateName => { const fields = Object.keys(state).map<string>((stateName) => {
const [isString, value] = generateCompositeType(state[stateName]); const value = generateCompositeType(state[stateName]);
return `${stateName}: ${isString ? `'${value}'` : value},`; return `${stateName}: ${value},`;
}); });
if (cfg.implementType === 'inConstructor') { if (cfg.implementType === 'inConstructor') {

View File

@ -11,7 +11,7 @@ import {
CompositeValue, CompositeValue,
} from '../../../types'; } from '../../../types';
import { generateCompositeType, handleStringValueDefault } from '../../../utils/compositeType'; import { generateCompositeType } from '../../../utils/compositeType';
import { generateExpression } from '../../../utils/jsExpression'; import { generateExpression } from '../../../utils/jsExpression';
function packJsExpression(exp: unknown): string { function packJsExpression(exp: unknown): string {
@ -35,19 +35,17 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
const extConfigs = Object.keys(rest).map((extConfigName) => { const extConfigs = Object.keys(rest).map((extConfigName) => {
const value = (rest as Record<string, CompositeValue>)[extConfigName]; const value = (rest as Record<string, CompositeValue>)[extConfigName];
const [isString, valueStr] = generateCompositeType(value); const valueStr = generateCompositeType(value);
return `${extConfigName}: ${isString ? `'${valueStr}'` : valueStr}`; return `${extConfigName}: ${valueStr}`;
}); });
attrs = [...attrs, ...extConfigs]; attrs = [...attrs, ...extConfigs];
const listProp = handleStringValueDefault( const listProp = generateCompositeType((list as unknown) as CompositeValue, {
generateCompositeType((list as unknown) as CompositeValue, { handlers: {
handlers: { expression: packJsExpression,
expression: packJsExpression, },
}, });
}),
);
attrs.push(`list: ${listProp}`); attrs.push(`list: ${listProp}`);

View File

@ -13,7 +13,7 @@ import { COMMON_CHUNK_NAME } from '../../../const/generator';
import { createNodeGenerator, generateString } from '../../../utils/nodeToJSX'; import { createNodeGenerator, generateString } from '../../../utils/nodeToJSX';
import { generateExpression } from '../../../utils/jsExpression'; import { generateExpression } from '../../../utils/jsExpression';
import { generateCompositeType, handleStringValueDefault } from '../../../utils/compositeType'; import { generateCompositeType } from '../../../utils/compositeType';
const generateGlobalProps = (ctx: INodeGeneratorContext, nodeItem: IComponentNodeItem): CodePiece[] => { const generateGlobalProps = (ctx: INodeGeneratorContext, nodeItem: IComponentNodeItem): CodePiece[] => {
return [ return [
@ -28,7 +28,7 @@ const generateCtrlLine = (ctx: INodeGeneratorContext, nodeItem: IComponentNodeIt
const pieces: CodePiece[] = []; const pieces: CodePiece[] = [];
if (nodeItem.loop && nodeItem.loopArgs) { if (nodeItem.loop && nodeItem.loopArgs) {
const loopDataExp = handleStringValueDefault(generateCompositeType(nodeItem.loop)); const loopDataExp = generateCompositeType(nodeItem.loop);
pieces.push({ pieces.push({
type: PIECE_TYPE.ATTR, type: PIECE_TYPE.ATTR,
value: `x-for={${loopDataExp}}`, value: `x-for={${loopDataExp}}`,
@ -41,7 +41,7 @@ const generateCtrlLine = (ctx: INodeGeneratorContext, nodeItem: IComponentNodeIt
} }
if (nodeItem.condition) { if (nodeItem.condition) {
const conditionExp = handleStringValueDefault(generateCompositeType(nodeItem.condition)); const conditionExp = generateCompositeType(nodeItem.condition);
pieces.push({ pieces.push({
type: PIECE_TYPE.ATTR, type: PIECE_TYPE.ATTR,
value: `x-if={${conditionExp}}`, value: `x-if={${conditionExp}}`,

View File

@ -17,7 +17,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
const ir = next.ir as IProjectInfo; const ir = next.ir as IProjectInfo;
if (ir.constants) { if (ir.constants) {
const [, constantStr] = generateCompositeType(ir.constants); const constantStr = generateCompositeType(ir.constants);
next.chunks.push({ next.chunks.push({
type: ChunkType.STRING, type: ChunkType.STRING,

View File

@ -17,7 +17,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
const ir = next.ir as IProjectInfo; const ir = next.ir as IProjectInfo;
if (ir.i18n) { if (ir.i18n) {
const [, i18nStr] = generateCompositeType(ir.i18n); const i18nStr = generateCompositeType(ir.i18n);
next.chunks.push({ next.chunks.push({
type: ChunkType.STRING, type: ChunkType.STRING,

View File

@ -179,6 +179,7 @@ export interface INodeGeneratorContext {
// } // }
export type CompositeValueCustomHandler = (data: unknown) => string; export type CompositeValueCustomHandler = (data: unknown) => string;
export type CompositeTypeContainerHandler = (value: string) => string;
export interface CompositeValueCustomHandlerSet { export interface CompositeValueCustomHandlerSet {
boolean?: CompositeValueCustomHandler; boolean?: CompositeValueCustomHandler;
number?: CompositeValueCustomHandler; number?: CompositeValueCustomHandler;
@ -188,7 +189,13 @@ export interface CompositeValueCustomHandlerSet {
expression?: CompositeValueCustomHandler; expression?: CompositeValueCustomHandler;
} }
export interface CompositeTypeContainerHandlerSet {
default?: CompositeTypeContainerHandler;
string?: CompositeValueCustomHandler;
}
export interface CompositeValueGeneratorOptions { export interface CompositeValueGeneratorOptions {
handlers?: CompositeValueCustomHandlerSet; handlers?: CompositeValueCustomHandlerSet;
containerHandlers?: CompositeTypeContainerHandlerSet;
nodeGenerator?: NodeGenerator; nodeGenerator?: NodeGenerator;
} }

View File

@ -3,10 +3,18 @@ import {
CompositeValue, CompositeValue,
ICompositeObject, ICompositeObject,
CompositeValueGeneratorOptions, CompositeValueGeneratorOptions,
CompositeTypeContainerHandlerSet,
CodeGeneratorError, CodeGeneratorError,
} from '../types'; } from '../types';
import { generateExpression, generateFunction, isJsExpression, isJsFunction } from './jsExpression'; import { generateExpression, generateFunction, isJsExpression, isJsFunction } from './jsExpression';
import { isJsSlot, generateJsSlot } from './jsSlot'; import { isJsSlot, generateJsSlot } from './jsSlot';
import { isValidIdentifier } from './validate';
import { camelize } from './common';
const defaultContainerHandlers: CompositeTypeContainerHandlerSet = {
default: (v) => v,
string: (v) => `'${v}'`,
};
function generateArray(value: CompositeArray, options: CompositeValueGeneratorOptions = {}): string { function generateArray(value: CompositeArray, options: CompositeValueGeneratorOptions = {}): string {
const body = value.map((v) => generateUnknownType(v, options)).join(','); const body = value.map((v) => generateUnknownType(v, options)).join(',');
@ -34,8 +42,25 @@ function generateObject(value: ICompositeObject, options: CompositeValueGenerato
const body = Object.keys(value) const body = Object.keys(value)
.map((key) => { .map((key) => {
let propName = key;
// TODO: 可以增加更多智能修复的方法
const fixMethods: Array<(v: string) => string> = [camelize];
// Try to fix propName
while (!isValidIdentifier(propName)) {
const fixMethod = fixMethods.pop();
if (fixMethod) {
try {
propName = fixMethod(propName);
} catch (error) {
throw new CodeGeneratorError(error.message);
}
} else {
throw new CodeGeneratorError(`Propname: ${key} is not a valid identifier.`);
}
}
const v = generateUnknownType(value[key], options); const v = generateUnknownType(value[key], options);
return `${key}: ${v}`; return `${propName}: ${v}`;
}) })
.join(',\n'); .join(',\n');
@ -66,22 +91,16 @@ export function generateUnknownType(value: CompositeValue, options: CompositeVal
return `${value}`; return `${value}`;
} }
export function generateCompositeType( export function generateCompositeType(value: CompositeValue, options: CompositeValueGeneratorOptions = {}): string {
value: CompositeValue,
options: CompositeValueGeneratorOptions = {},
): [boolean, string] {
const result = generateUnknownType(value, options); const result = generateUnknownType(value, options);
const containerHandlers = {
...defaultContainerHandlers,
...(options.containerHandlers || {}),
};
if (result.substr(0, 1) === "'" && result.substr(-1, 1) === "'") { const isStringType = result.substr(0, 1) === "'" && result.substr(-1, 1) === "'";
return [true, result.substring(1, result.length - 1)]; if (isStringType) {
return (containerHandlers.string && containerHandlers.string(result.substring(1, result.length - 1))) || '';
} }
return (containerHandlers.default && containerHandlers.default(result)) || '';
return [false, result];
}
export function handleStringValueDefault([isString, result]: [boolean, string]) {
if (isString) {
return `'${result}'`;
}
return result;
} }

View File

@ -104,12 +104,16 @@ export function generateAttr(ctx: INodeGeneratorContext, attrName: string, attrV
if (attrName === 'initValue') { if (attrName === 'initValue') {
return []; return [];
} }
const [isString, valueStr] = generateCompositeType(attrValue, { const valueStr = generateCompositeType(attrValue, {
containerHandlers: {
default: (v) => `{${v}}`,
string: (v) => `"${v}"`,
},
nodeGenerator: ctx.generator, nodeGenerator: ctx.generator,
}); });
return [ return [
{ {
value: `${attrName}=${isString ? `"${valueStr}"` : `{${valueStr}}`}`, value: `${attrName}=${valueStr}`,
type: PIECE_TYPE.ATTR, type: PIECE_TYPE.ATTR,
}, },
]; ];
@ -180,12 +184,12 @@ export function generateReactCtrlLine(ctx: INodeGeneratorContext, nodeItem: ICom
} }
if (nodeItem.condition) { if (nodeItem.condition) {
const [isString, value] = generateCompositeType(nodeItem.condition, { const value = generateCompositeType(nodeItem.condition, {
nodeGenerator: ctx.generator, nodeGenerator: ctx.generator,
}); });
pieces.unshift({ pieces.unshift({
value: `(${isString ? `'${value}'` : value}) && (`, value: `(${value}) && (`,
type: PIECE_TYPE.BEFORE, type: PIECE_TYPE.BEFORE,
}); });
pieces.push({ pieces.push({

View File

@ -21,7 +21,7 @@ interface BasicSection {
[k: string]: any; [k: string]: any;
} }
const CODEOUT_SERVICE_HOST = '30.13.90.55:3000'; const CODEOUT_SERVICE_HOST = '30.13.88.126:3000';
const Codeout = ({ editor }: PluginProps) => { const Codeout = ({ editor }: PluginProps) => {
const handleClick = () => { const handleClick = () => {