forked from alibaba/lowcode-engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcore.ts
More file actions
196 lines (164 loc) · 5.22 KB
/
core.ts
File metadata and controls
196 lines (164 loc) · 5.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import {
JSONArray,
JSONObject,
CompositeArray,
CompositeObject,
ResultDir,
ResultFile,
NodeDataType,
ProjectSchema,
JSExpression,
JSFunction,
JSSlot,
} from '@alilc/lowcode-types';
import { IParseResult } from './intermediate';
import { IScopeBindings } from '../utils/ScopeBindings';
export enum FileType {
CSS = 'css',
SCSS = 'scss',
LESS = 'less',
HTML = 'html',
JS = 'js',
JSX = 'jsx',
TS = 'ts',
TSX = 'tsx',
JSON = 'json',
}
export enum ChunkType {
AST = 'ast',
STRING = 'string',
JSON = 'json',
}
export enum PluginType {
COMPONENT = 'component',
UTILS = 'utils',
I18N = 'i18n',
}
export type ChunkContent = string | any;
export type CodeGeneratorFunction<T> = (content: T) => string;
export interface ICodeChunk {
type: ChunkType;
fileType: string;
name: string;
subModule?: string;
content: ChunkContent;
linkAfter: string[];
ext?: Record<string, unknown>;
}
export interface IBaseCodeStruct {
chunks: ICodeChunk[];
depNames: string[];
}
export interface ICodeStruct extends IBaseCodeStruct {
ir: any;
// FIXME: 这个方案不太好,想清楚场景,结构化表达,不要那么通用
contextData: Record<string, any>;
}
export type BuilderComponentPlugin = (initStruct: ICodeStruct) => Promise<ICodeStruct>;
export type BuilderComponentPluginFactory<T> = (config?: T) => BuilderComponentPlugin;
export interface IChunkBuilder {
run: (ir: any, initialStructure?: ICodeStruct) => Promise<{ chunks: ICodeChunk[][] }>;
getPlugins: () => BuilderComponentPlugin[];
addPlugin: (plugin: BuilderComponentPlugin) => void;
}
export interface ICodeBuilder {
link: (chunkDefinitions: ICodeChunk[]) => string;
generateByType: (type: string, content: unknown) => string;
}
export interface ICompiledModule {
files: ResultFile[];
}
export interface IModuleBuilder {
generateModule: (input: unknown) => Promise<ICompiledModule>;
generateModuleCode: (schema: ProjectSchema | string) => Promise<ResultDir>;
linkCodeChunks: (chunks: Record<string, ICodeChunk[]>, fileName: string) => ResultFile[];
addPlugin: (plugin: BuilderComponentPlugin) => void;
}
/**
* 引擎对外接口
*
* @export
* @interface ICodeGenerator
*/
export interface ICodeGenerator {
/**
* 出码接口,把 Schema 转换成代码文件系统描述
*
* @param {(ProjectSchema)} schema 传入的 Schema
* @returns {ResultDir}
* @memberof ICodeGenerator
*/
toCode: (schema: ProjectSchema) => Promise<ResultDir>;
}
export interface ISchemaParser {
validate: (schema: ProjectSchema) => boolean;
parse: (schema: ProjectSchema | string) => IParseResult;
}
export interface IProjectTemplate {
slots: Record<string, IProjectSlot>;
generateTemplate: () => ResultDir | Promise<ResultDir>;
}
export interface IProjectSlot {
path: string[];
fileName?: string;
}
export interface IProjectPlugins {
[slotName: string]: BuilderComponentPlugin[];
}
export interface IProjectBuilder {
generateProject: (schema: ProjectSchema | string) => Promise<ResultDir>;
}
/** 项目级别的前置处理器 */
export type ProjectPreProcessor = (schema: ProjectSchema) => Promise<ProjectSchema> | ProjectSchema;
/** 项目级别的后置处理器 */
export type ProjectPostProcessor = (
result: ResultDir,
schema: ProjectSchema,
originalSchema: ProjectSchema | string,
) => Promise<ResultDir> | ResultDir;
/** 模块级别的后置处理器的工厂方法 */
export type PostProcessorFactory<T> = (config?: T) => PostProcessor;
/** 模块级别的后置处理器 */
export type PostProcessor = (content: string, fileType: string) => string;
// TODO: temp interface, need modify
export interface IPluginOptions {
fileDirDepth: number;
}
export type BaseGenerator<I, T, C> = (
input: I,
scope: IScope,
config?: C,
next?: BaseGenerator<I, T, C>,
) => T;
type CompositeTypeGenerator<I, T> =
| BaseGenerator<I, T, CompositeValueGeneratorOptions>
| Array<BaseGenerator<I, T, CompositeValueGeneratorOptions>>;
export type NodeGenerator<T> = (nodeItem: NodeDataType, scope: IScope) => T;
// FIXME: 在新的实现中,添加了第一参数 this: CustomHandlerSet 作为上下文。究其本质
// scopeBindings?: IScopeBindings;
// 这个组合只用来用来处理 CompositeValue 类型,不是这个类型的不要放在这里
export interface HandlerSet<T> {
string?: CompositeTypeGenerator<string, T>;
boolean?: CompositeTypeGenerator<boolean, T>;
number?: CompositeTypeGenerator<number, T>;
expression?: CompositeTypeGenerator<JSExpression, T>;
function?: CompositeTypeGenerator<JSFunction, T>;
slot?: CompositeTypeGenerator<JSSlot, T>;
array?: CompositeTypeGenerator<JSONArray | CompositeArray, T>;
object?: CompositeTypeGenerator<JSONObject | CompositeObject, T>;
}
export interface CompositeValueGeneratorOptions {
handlers?: HandlerSet<string>;
nodeGenerator?: NodeGenerator<string>;
}
/**
* 作用域定义,维护作用域内定义,支持作用域链上溯
*/
export interface IScope {
// 父级作用域(如果是根作用域则为 null)
readonly parent: IScope | null;
// 作用域内定义的变量/函数等 bindings
readonly bindings?: IScopeBindings;
// TODO: 需要有上下文信息吗? 描述什么内容
createSubScope: (ownIndentifiers: string[]) => IScope;
}