@hadss/hmrouter-plugin 1.0.0-rc.0 → 1.0.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +77 -77
- package/README.md +260 -37
- package/dist/HMRouterAnalyzer.d.ts +31 -0
- package/dist/HMRouterAnalyzer.js +293 -0
- package/dist/HMRouterHvigorPlugin.d.ts +15 -0
- package/dist/HMRouterHvigorPlugin.js +139 -0
- package/dist/HMRouterPluginConfig.d.ts +39 -0
- package/dist/HMRouterPluginConfig.js +73 -0
- package/dist/HMRouterPluginHandle.d.ts +23 -0
- package/dist/HMRouterPluginHandle.js +231 -0
- package/dist/Index.d.ts +4 -0
- package/dist/Index.js +124 -0
- package/dist/common/Constant.d.ts +27 -0
- package/dist/common/Constant.js +35 -0
- package/dist/common/Logger.d.ts +13 -0
- package/dist/common/Logger.js +55 -0
- package/dist/common/PluginModel.d.ts +50 -0
- package/dist/common/PluginModel.js +23 -0
- package/dist/constants/CommonConstants.d.ts +39 -0
- package/dist/constants/CommonConstants.js +46 -0
- package/dist/constants/ConfigConstants.d.ts +11 -0
- package/dist/constants/ConfigConstants.js +15 -0
- package/dist/constants/TaskConstants.d.ts +9 -0
- package/dist/constants/TaskConstants.js +13 -0
- package/dist/store/PluginStore.d.ts +12 -0
- package/dist/store/PluginStore.js +19 -0
- package/dist/utils/ConfusionUtil.d.ts +4 -0
- package/dist/utils/ConfusionUtil.js +27 -0
- package/dist/utils/FileUtil.d.ts +11 -0
- package/dist/utils/FileUtil.js +20 -0
- package/dist/utils/ObfuscationUtil.d.ts +4 -0
- package/dist/utils/ObfuscationUtil.js +34 -0
- package/dist/utils/StringUtil.d.ts +3 -0
- package/dist/utils/StringUtil.js +18 -0
- package/dist/utils/TsAstUtil.d.ts +9 -0
- package/dist/utils/TsAstUtil.js +89 -0
- package/package.json +46 -27
- package/viewBuilder.ejs +103 -0
- package/lib/HMRouterAnalyzer.js +0 -223
- package/lib/HMRouterHvigorPlugin.js +0 -175
- package/lib/HMRouterPluginConfig.js +0 -31
- package/lib/Index.js +0 -201
- package/lib/PluginModel.js +0 -33
- package/src/HMRouterAnalyzer.ts +0 -253
- package/src/HMRouterHvigorPlugin.ts +0 -246
- package/src/HMRouterPluginConfig.ts +0 -44
- package/src/Index.ts +0 -218
- package/src/PluginModel.ts +0 -50
- package/tsconfig.json +0 -14
- package/viewBuilder.tpl +0 -97
package/src/HMRouterAnalyzer.ts
DELETED
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
3
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License.
|
|
5
|
-
* You may obtain a copy of the License at
|
|
6
|
-
*
|
|
7
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
*
|
|
9
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
* See the License for the specific language governing permissions and
|
|
13
|
-
* limitations under the License.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import ts from 'typescript'
|
|
17
|
-
import fs from 'fs'
|
|
18
|
-
import { HMRouterPluginConfig } from './HMRouterPluginConfig'
|
|
19
|
-
import {
|
|
20
|
-
AnalyzerResultLike,
|
|
21
|
-
HMAnimatorResult,
|
|
22
|
-
HMInterceptorResult,
|
|
23
|
-
HMLifecycleResult,
|
|
24
|
-
HMRouterResult
|
|
25
|
-
} from './PluginModel'
|
|
26
|
-
import { HvigorLogger } from '@ohos/hvigor'
|
|
27
|
-
import { deleteGeneratorFile } from './Index'
|
|
28
|
-
|
|
29
|
-
class NodeInfo {
|
|
30
|
-
value?: any
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const Logger = HvigorLogger.getLogger()
|
|
34
|
-
|
|
35
|
-
export class Analyzer {
|
|
36
|
-
customAnnotationExisted: boolean = false
|
|
37
|
-
analyzeResultMap: Map<string, AnalyzerResultLike> = new Map()
|
|
38
|
-
private sourcePath: string
|
|
39
|
-
private pluginConfig: HMRouterPluginConfig
|
|
40
|
-
private analyzeResult: AnalyzerResultLike = {}
|
|
41
|
-
private keywordPos: number = 0
|
|
42
|
-
|
|
43
|
-
constructor(sourcePath: string, pluginConfig: HMRouterPluginConfig) {
|
|
44
|
-
this.sourcePath = sourcePath
|
|
45
|
-
this.pluginConfig = pluginConfig
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
start() {
|
|
49
|
-
const sourceCode = fs.readFileSync(this.sourcePath, 'utf-8')
|
|
50
|
-
const sourceFile = ts.createSourceFile(
|
|
51
|
-
this.sourcePath,
|
|
52
|
-
sourceCode,
|
|
53
|
-
ts.ScriptTarget.ES2021,
|
|
54
|
-
false
|
|
55
|
-
)
|
|
56
|
-
ts.forEachChild(sourceFile, node => {
|
|
57
|
-
this.resolveNode(node)
|
|
58
|
-
// 解析完成后赋值存进Map
|
|
59
|
-
switch (this.analyzeResult.annotation) {
|
|
60
|
-
case 'HMRouter':
|
|
61
|
-
this.analyzeResultMap.set(
|
|
62
|
-
(this.analyzeResult as HMRouterResult).pageUrl!,
|
|
63
|
-
this.analyzeResult
|
|
64
|
-
)
|
|
65
|
-
break
|
|
66
|
-
case 'HMAnimator':
|
|
67
|
-
this.analyzeResultMap.set(
|
|
68
|
-
(this.analyzeResult as HMAnimatorResult).animatorName!,
|
|
69
|
-
this.analyzeResult
|
|
70
|
-
)
|
|
71
|
-
break
|
|
72
|
-
case 'HMInterceptor':
|
|
73
|
-
this.analyzeResultMap.set(
|
|
74
|
-
(this.analyzeResult as HMInterceptorResult).interceptorName!,
|
|
75
|
-
this.analyzeResult
|
|
76
|
-
)
|
|
77
|
-
break
|
|
78
|
-
case 'HMLifecycle':
|
|
79
|
-
this.analyzeResultMap.set(
|
|
80
|
-
(this.analyzeResult as HMLifecycleResult).lifecycleName!,
|
|
81
|
-
this.analyzeResult
|
|
82
|
-
)
|
|
83
|
-
break
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private resolveNode(node: ts.Node) {
|
|
89
|
-
if (ts.isMissingDeclaration(node)) {
|
|
90
|
-
this.resolveMissingDeclaration(node)
|
|
91
|
-
} else if (ts.isClassDeclaration(node)) {
|
|
92
|
-
this.resolveClass(node)
|
|
93
|
-
} else if (ts.isDecorator(node)) {
|
|
94
|
-
this.resolveDecorator(node)
|
|
95
|
-
} else if (ts.isCallExpression(node)) {
|
|
96
|
-
this.resolveCallExpression(node)
|
|
97
|
-
} else if (ts.isExpressionStatement(node)) {
|
|
98
|
-
this.resolveExpression(node)
|
|
99
|
-
} else if (ts.isBlock(node)) {
|
|
100
|
-
this.resolveBlock(node)
|
|
101
|
-
} else if (ts.isPropertyAssignment(node)) {
|
|
102
|
-
return this.resolvePropertyAccess(node)
|
|
103
|
-
} else if (ts.isIdentifier(node)) {
|
|
104
|
-
return this.resolveIdentifier(node)
|
|
105
|
-
} else if (ts.isStringLiteral(node)) {
|
|
106
|
-
return this.resolveStringLiteral(node)
|
|
107
|
-
} else if (node.kind === ts.SyntaxKind.TrueKeyword) {
|
|
108
|
-
let info = new NodeInfo()
|
|
109
|
-
info.value = true
|
|
110
|
-
return info
|
|
111
|
-
} else if (node.kind === ts.SyntaxKind.FalseKeyword) {
|
|
112
|
-
let info = new NodeInfo()
|
|
113
|
-
info.value = false
|
|
114
|
-
return info
|
|
115
|
-
} else if (ts.isNumericLiteral(node)) {
|
|
116
|
-
return this.resolveNumericLiteral(node)
|
|
117
|
-
} else if (ts.isArrayLiteralExpression(node)) {
|
|
118
|
-
let interceptors = this.resolveArrayLiteral(node)
|
|
119
|
-
let info = new NodeInfo()
|
|
120
|
-
info.value = interceptors
|
|
121
|
-
return info
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
private resolveMissingDeclaration(node: ts.MissingDeclaration) {
|
|
126
|
-
this.analyzeResult = {}
|
|
127
|
-
node.forEachChild(child => this.resolveNode(child))
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
private resolveClass(node: ts.ClassDeclaration) {
|
|
131
|
-
// 解析到类声明,先清空一次返回结果
|
|
132
|
-
this.analyzeResult = {}
|
|
133
|
-
node.modifiers?.forEach(modifier => {
|
|
134
|
-
// 遍历分析装饰器
|
|
135
|
-
this.resolveNode(modifier)
|
|
136
|
-
})
|
|
137
|
-
if (this.customAnnotationExisted) {
|
|
138
|
-
this.analyzeResult.name = node.name?.text
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private resolveDecorator(node: ts.Decorator) {
|
|
143
|
-
if (ts.isCallExpression(node.expression)) {
|
|
144
|
-
const callExpression = node.expression as ts.CallExpression
|
|
145
|
-
if (ts.isIdentifier(callExpression.expression)) {
|
|
146
|
-
this.switchIdentifier(callExpression)
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
private switchIdentifier(callExpression: ts.CallExpression) {
|
|
152
|
-
const identifier = callExpression.expression as ts.Identifier
|
|
153
|
-
if (this.pluginConfig.annotation.some(item => item === identifier.text)) {
|
|
154
|
-
this.customAnnotationExisted = true
|
|
155
|
-
// 区分是什么装饰器,构造不同的返回类
|
|
156
|
-
switch (identifier.text) {
|
|
157
|
-
case 'HMRouter':
|
|
158
|
-
this.analyzeResult = new HMRouterResult()
|
|
159
|
-
this.analyzeResult.annotation = 'HMRouter'
|
|
160
|
-
break
|
|
161
|
-
case 'HMAnimator':
|
|
162
|
-
this.analyzeResult = new HMAnimatorResult()
|
|
163
|
-
this.analyzeResult.annotation = 'HMAnimator'
|
|
164
|
-
break
|
|
165
|
-
case 'HMInterceptor':
|
|
166
|
-
this.analyzeResult = new HMInterceptorResult()
|
|
167
|
-
this.analyzeResult.annotation = 'HMInterceptor'
|
|
168
|
-
break
|
|
169
|
-
case 'HMLifecycle':
|
|
170
|
-
this.analyzeResult = new HMLifecycleResult()
|
|
171
|
-
this.analyzeResult.annotation = 'HMLifecycle'
|
|
172
|
-
break
|
|
173
|
-
}
|
|
174
|
-
if (callExpression.arguments.length > 0) {
|
|
175
|
-
this.resolveCallExpression(callExpression)
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
private resolveCallExpression(node: ts.CallExpression) {
|
|
181
|
-
let identifier = this.resolveNode(node.expression)
|
|
182
|
-
this.parseAnnotation(node.arguments, identifier)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
private resolveExpression(node: ts.ExpressionStatement) {
|
|
186
|
-
let identifier = this.resolveNode(node.expression)
|
|
187
|
-
if (identifier?.value === 'struct') {
|
|
188
|
-
this.keywordPos = node.end
|
|
189
|
-
}
|
|
190
|
-
if (this.analyzeResult.annotation === 'HMRouter' && this.keywordPos === node.pos) {
|
|
191
|
-
this.analyzeResult.name = identifier?.value
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
private resolveBlock(node: ts.Block) {
|
|
196
|
-
node.statements.forEach(statement => {
|
|
197
|
-
this.resolveNode(statement)
|
|
198
|
-
})
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
private parseAnnotation(args: ts.NodeArray<ts.Expression>, nodeInfo?: NodeInfo) {
|
|
202
|
-
if (this.pluginConfig.annotation.some(item => nodeInfo?.value === item)) {
|
|
203
|
-
args
|
|
204
|
-
.flatMap((e: ts.Expression) => (e as ts.ObjectLiteralExpression).properties)
|
|
205
|
-
.forEach((e: ts.ObjectLiteralElementLike) => {
|
|
206
|
-
this.parseConfig(e, this.analyzeResult)
|
|
207
|
-
})
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
private parseConfig(node: ts.ObjectLiteralElementLike, result: AnalyzerResultLike) {
|
|
212
|
-
let info = this.resolveNode(node)
|
|
213
|
-
Reflect.set(result, info?.value['key'], info?.value['value'])
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
private resolveArrayLiteral(node: ts.ArrayLiteralExpression) {
|
|
217
|
-
return node.elements.map(e => this.resolveNode(e)?.value as string)
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
private resolvePropertyAccess(node: ts.PropertyAssignment) {
|
|
221
|
-
let propertyName = this.resolveNode(node.name)?.value
|
|
222
|
-
let propertyValue = this.resolveNode(node.initializer)?.value
|
|
223
|
-
let info = new NodeInfo()
|
|
224
|
-
info.value = { key: propertyName, value: propertyValue }
|
|
225
|
-
return info
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
private resolveNumericLiteral(node: ts.NumericLiteral) {
|
|
229
|
-
let info = new NodeInfo()
|
|
230
|
-
info.value = Number(node.text)
|
|
231
|
-
return info
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
private resolveStringLiteral(node: ts.StringLiteral) {
|
|
235
|
-
let info = new NodeInfo()
|
|
236
|
-
info.value = node.text
|
|
237
|
-
return info
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
private resolveIdentifier(node: ts.Identifier) {
|
|
241
|
-
if (node.escapedText === 'NavDestination' && this.analyzeResult.annotation === 'HMRouter') {
|
|
242
|
-
Logger.error(
|
|
243
|
-
'errorCode: 40000003, errorMsg: @HMRouter 修饰的组件不能包含 NavDestination in' +
|
|
244
|
-
this.analyzeResult.name
|
|
245
|
-
)
|
|
246
|
-
deleteGeneratorFile(this.pluginConfig)
|
|
247
|
-
throw new Error('NavDestination is not allowed in HMRouter' + this.sourcePath)
|
|
248
|
-
}
|
|
249
|
-
let info = new NodeInfo()
|
|
250
|
-
info.value = node.escapedText.toString()
|
|
251
|
-
return info
|
|
252
|
-
}
|
|
253
|
-
}
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
3
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License.
|
|
5
|
-
* You may obtain a copy of the License at
|
|
6
|
-
*
|
|
7
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
*
|
|
9
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
* See the License for the specific language governing permissions and
|
|
13
|
-
* limitations under the License.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { HvigorLogger } from '@ohos/hvigor'
|
|
17
|
-
import { HMRouterPluginConfig } from './HMRouterPluginConfig'
|
|
18
|
-
import {
|
|
19
|
-
AnalyzerResultLike,
|
|
20
|
-
HMAnimatorResult,
|
|
21
|
-
HMInterceptorResult,
|
|
22
|
-
HMLifecycleResult,
|
|
23
|
-
HMRouterResult
|
|
24
|
-
} from './PluginModel'
|
|
25
|
-
import path from 'path'
|
|
26
|
-
import fs from 'fs'
|
|
27
|
-
import { Analyzer } from './HMRouterAnalyzer'
|
|
28
|
-
import Handlebars from 'handlebars'
|
|
29
|
-
import { deleteGeneratorFile } from './Index'
|
|
30
|
-
|
|
31
|
-
const Logger = HvigorLogger.getLogger()
|
|
32
|
-
|
|
33
|
-
interface templateModel {
|
|
34
|
-
pageUrl: string
|
|
35
|
-
importPath: string
|
|
36
|
-
componentName: string
|
|
37
|
-
dialog: boolean
|
|
38
|
-
generatorViewName: string
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export class RouterInfo {
|
|
42
|
-
name: string
|
|
43
|
-
pageSourceFile: string
|
|
44
|
-
buildFunction: string
|
|
45
|
-
data: AnalyzerResultLike
|
|
46
|
-
|
|
47
|
-
constructor(
|
|
48
|
-
name: string,
|
|
49
|
-
pageSourceFile: string,
|
|
50
|
-
buildFunction: string,
|
|
51
|
-
data: AnalyzerResultLike = {}
|
|
52
|
-
) {
|
|
53
|
-
this.name = name
|
|
54
|
-
this.pageSourceFile = pageSourceFile
|
|
55
|
-
this.buildFunction = buildFunction
|
|
56
|
-
this.data = data
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export class HMRouterHvigorPlugin {
|
|
61
|
-
config: HMRouterPluginConfig
|
|
62
|
-
routerMap: RouterInfo[] = []
|
|
63
|
-
private scanFiles: string[] = []
|
|
64
|
-
HMRouterNum: number = 0
|
|
65
|
-
|
|
66
|
-
constructor(config: HMRouterPluginConfig) {
|
|
67
|
-
this.config = config
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
analyzeAnnotation() {
|
|
71
|
-
const templateModel = {
|
|
72
|
-
pageUrl: '',
|
|
73
|
-
importPath: '',
|
|
74
|
-
componentName: '',
|
|
75
|
-
dialog: false,
|
|
76
|
-
generatorViewName: ''
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
this.config.scanDir.forEach(scanDir => {
|
|
80
|
-
const scanPath = `${this.config.modulePath}/${scanDir}`
|
|
81
|
-
this.deepScan(scanPath, '')
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
Logger.info(`扫描到${this.scanFiles.length}个文件`, this.scanFiles)
|
|
85
|
-
|
|
86
|
-
this.scanFiles.forEach(filePath => {
|
|
87
|
-
if (filePath.endsWith('.ets')) {
|
|
88
|
-
const importPath = path
|
|
89
|
-
.relative(`${this.config.modulePath}/${this.config.builderDir}`, filePath)
|
|
90
|
-
.replaceAll('\\', '/')
|
|
91
|
-
.replaceAll('.ets', '')
|
|
92
|
-
|
|
93
|
-
const analyzer = new Analyzer(filePath, this.config)
|
|
94
|
-
analyzer.start()
|
|
95
|
-
for (let [key, value] of analyzer.analyzeResultMap) {
|
|
96
|
-
value.module = this.config.moduleName
|
|
97
|
-
let pageSourceFile = path.relative(this.config.modulePath, filePath).replaceAll('\\', '/')
|
|
98
|
-
this.pushRouterInfo(value, pageSourceFile, importPath, templateModel)
|
|
99
|
-
}
|
|
100
|
-
this.HMRouterNum = 0
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
private stringToHashCode(str: string) {
|
|
106
|
-
let hash = 0
|
|
107
|
-
if (str.length === 0) return hash
|
|
108
|
-
for (let i = 0; i < str.length; i++) {
|
|
109
|
-
const char = str.charCodeAt(i)
|
|
110
|
-
hash = (hash << 5) - hash + char
|
|
111
|
-
hash |= 0 // 转换为32位整数
|
|
112
|
-
}
|
|
113
|
-
return hash
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
private pushHMRouter(
|
|
117
|
-
value: AnalyzerResultLike,
|
|
118
|
-
importPath: string,
|
|
119
|
-
templateModel: templateModel
|
|
120
|
-
) {
|
|
121
|
-
let analyzeResult = value as HMRouterResult
|
|
122
|
-
templateModel.pageUrl = analyzeResult.pageUrl as string
|
|
123
|
-
templateModel.importPath = importPath
|
|
124
|
-
templateModel.componentName = analyzeResult.name as string
|
|
125
|
-
templateModel.dialog = !!analyzeResult.dialog
|
|
126
|
-
templateModel.generatorViewName = 'HM' + analyzeResult.name + this.stringToHashCode(analyzeResult.pageUrl!)
|
|
127
|
-
|
|
128
|
-
this.routerMap.push(
|
|
129
|
-
new RouterInfo(
|
|
130
|
-
analyzeResult.pageUrl as string,
|
|
131
|
-
`${this.config.builderDir}/${templateModel.generatorViewName}.ets`,
|
|
132
|
-
`${templateModel.componentName}Builder`,
|
|
133
|
-
value
|
|
134
|
-
)
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
this.generateBuilder(templateModel)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
private pushRouterInfo(
|
|
141
|
-
value: AnalyzerResultLike,
|
|
142
|
-
pageSourceFile: string,
|
|
143
|
-
importPath: string,
|
|
144
|
-
templateModel: templateModel
|
|
145
|
-
) {
|
|
146
|
-
switch (value.annotation) {
|
|
147
|
-
case 'HMRouter':
|
|
148
|
-
this.HMRouterNum++
|
|
149
|
-
if (this.HMRouterNum > 1) {
|
|
150
|
-
Logger.error(`errorCode: 40000004, errorMsg: 文件${pageSourceFile}中存在多个HMRouter注解`)
|
|
151
|
-
deleteGeneratorFile(this.config)
|
|
152
|
-
throw new Error(`文件${pageSourceFile}中存在多个HMRouter注解`)
|
|
153
|
-
}
|
|
154
|
-
this.pushHMRouter(value, importPath, templateModel)
|
|
155
|
-
break
|
|
156
|
-
case 'HMAnimator':
|
|
157
|
-
this.routerMap.push(
|
|
158
|
-
new RouterInfo(
|
|
159
|
-
`__animator__${(value as HMAnimatorResult).animatorName}`,
|
|
160
|
-
pageSourceFile,
|
|
161
|
-
'',
|
|
162
|
-
value
|
|
163
|
-
)
|
|
164
|
-
)
|
|
165
|
-
break
|
|
166
|
-
case 'HMInterceptor':
|
|
167
|
-
this.routerMap.push(
|
|
168
|
-
new RouterInfo(
|
|
169
|
-
`__interceptor__${(value as HMInterceptorResult).interceptorName}`,
|
|
170
|
-
pageSourceFile,
|
|
171
|
-
'',
|
|
172
|
-
value
|
|
173
|
-
)
|
|
174
|
-
)
|
|
175
|
-
break
|
|
176
|
-
case 'HMLifecycle':
|
|
177
|
-
this.routerMap.push(
|
|
178
|
-
new RouterInfo(
|
|
179
|
-
`__lifecycle__${(value as HMLifecycleResult).lifecycleName}`,
|
|
180
|
-
pageSourceFile,
|
|
181
|
-
'',
|
|
182
|
-
value
|
|
183
|
-
)
|
|
184
|
-
)
|
|
185
|
-
break
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
generateBuilder(templateModel: templateModel) {
|
|
190
|
-
const builderPath = path.resolve(__dirname, '../' + this.config.builderTpl)
|
|
191
|
-
const tpl = fs.readFileSync(builderPath, { encoding: 'utf-8' })
|
|
192
|
-
const template = Handlebars.compile(tpl)
|
|
193
|
-
const output = template(templateModel)
|
|
194
|
-
const routerBuilderDir = `${this.config.modulePath}/${this.config.builderDir}`
|
|
195
|
-
if (!fs.existsSync(routerBuilderDir)) {
|
|
196
|
-
fs.mkdirSync(routerBuilderDir)
|
|
197
|
-
}
|
|
198
|
-
fs.writeFileSync(`${routerBuilderDir}/${templateModel.generatorViewName}.ets`, output, {
|
|
199
|
-
encoding: 'utf-8'
|
|
200
|
-
})
|
|
201
|
-
Logger.info(`Builder ${templateModel.generatorViewName}.ets has been generated in ${routerBuilderDir}`)
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
generateRouterMap() {
|
|
205
|
-
let set = new Set<string>()
|
|
206
|
-
this.routerMap.forEach(item => {
|
|
207
|
-
if(set.has(item.name)) {
|
|
208
|
-
Logger.error(`errorCode: 40000001, errorMsg: 重复的pageUrl、拦截器、生命周期、动画--${item.name}`)
|
|
209
|
-
deleteGeneratorFile(this.config)
|
|
210
|
-
throw new Error(`路由${item.name}重复`)
|
|
211
|
-
} else {
|
|
212
|
-
set.add(item.name)
|
|
213
|
-
}
|
|
214
|
-
})
|
|
215
|
-
let routerMap = {
|
|
216
|
-
routerMap: this.routerMap.map(item => {
|
|
217
|
-
if (item.data && item.data.annotation) {
|
|
218
|
-
delete item.data.annotation
|
|
219
|
-
// @ts-ignore
|
|
220
|
-
item.data = { data: JSON.stringify(item.data) }
|
|
221
|
-
}
|
|
222
|
-
return item
|
|
223
|
-
})
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const jsonOutput = JSON.stringify(routerMap, null, 2)
|
|
227
|
-
const routerMapDir = `${this.config.modulePath}/${this.config.routerMapDir}`
|
|
228
|
-
if (!fs.existsSync(routerMapDir)) {
|
|
229
|
-
fs.mkdirSync(routerMapDir, { recursive: true })
|
|
230
|
-
}
|
|
231
|
-
fs.writeFileSync(`${routerMapDir}/hm_router_map.json`, jsonOutput, { encoding: 'utf-8' })
|
|
232
|
-
Logger.info(`hm_router_map.json has been generated in ${routerMapDir}`)
|
|
233
|
-
return this.routerMap
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
private deepScan(scanPath: string, filePath: string) {
|
|
237
|
-
if (fs.lstatSync(`${scanPath + filePath}`).isDirectory()) {
|
|
238
|
-
const files: string[] = fs.readdirSync(`${scanPath}${filePath}`)
|
|
239
|
-
files.forEach(file => {
|
|
240
|
-
this.deepScan(`${scanPath}${filePath}/`, file)
|
|
241
|
-
})
|
|
242
|
-
} else {
|
|
243
|
-
this.scanFiles.push(`${scanPath}${filePath}`)
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
3
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
* you may not use this file except in compliance with the License.
|
|
5
|
-
* You may obtain a copy of the License at
|
|
6
|
-
*
|
|
7
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
*
|
|
9
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
* See the License for the specific language governing permissions and
|
|
13
|
-
* limitations under the License.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
export class HMRouterPluginConfig {
|
|
17
|
-
moduleName: string
|
|
18
|
-
modulePath: string
|
|
19
|
-
scanDir: string[]
|
|
20
|
-
routerMapDir: string
|
|
21
|
-
builderDir: string
|
|
22
|
-
annotation: string[]
|
|
23
|
-
builderTpl: string
|
|
24
|
-
saveGeneratedFile: boolean
|
|
25
|
-
|
|
26
|
-
constructor(moduleName: string, modulePath: string, param: HMRouterPluginConfigParam) {
|
|
27
|
-
this.moduleName = moduleName
|
|
28
|
-
this.modulePath = modulePath
|
|
29
|
-
this.scanDir = param.scanDir ? param.scanDir : ['src/main/ets']
|
|
30
|
-
this.routerMapDir = param.routerMapDir ? param.routerMapDir : 'src/main/resources/base/profile'
|
|
31
|
-
this.builderDir = param.builderDir ? param.builderDir : 'src/main/ets/generated'
|
|
32
|
-
this.annotation = ['HMRouter', 'HMAnimator', 'HMInterceptor', 'HMLifecycle']
|
|
33
|
-
this.builderTpl = param.builderTpl ? param.builderTpl : 'viewBuilder.tpl'
|
|
34
|
-
this.saveGeneratedFile = !!param.saveGeneratedFile
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface HMRouterPluginConfigParam {
|
|
39
|
-
scanDir?: string[]
|
|
40
|
-
routerMapDir?: string
|
|
41
|
-
builderDir?: string
|
|
42
|
-
saveGeneratedFile?: boolean // 隐藏字段仅用于调试
|
|
43
|
-
builderTpl?: string // 隐藏字段仅用于调试
|
|
44
|
-
}
|