From 1a9113a58816c4df1b2d4c773f28f5d7cdc56912 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Tue, 21 Mar 2023 12:13:17 +0800 Subject: [PATCH] wip(uts): runtime --- src/platforms/app-plus/service/api/index.js | 3 +- .../app-plus/service/api/plugin/uts.js | 66 +++++++++++++++---- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/platforms/app-plus/service/api/index.js b/src/platforms/app-plus/service/api/index.js index fc40c52f511..6120e6b2a93 100644 --- a/src/platforms/app-plus/service/api/index.js +++ b/src/platforms/app-plus/service/api/index.js @@ -71,7 +71,8 @@ export { initUTSClassName, initUTSPackageName, requireUTSPlugin, - registerUTSPlugin + registerUTSPlugin, + registerUTSInterface } from './plugin/uts' export * from './route/navigate-back' diff --git a/src/platforms/app-plus/service/api/plugin/uts.js b/src/platforms/app-plus/service/api/plugin/uts.js index 53eacb64bad..28d094f83d7 100644 --- a/src/platforms/app-plus/service/api/plugin/uts.js +++ b/src/platforms/app-plus/service/api/plugin/uts.js @@ -1,4 +1,4 @@ -import { isPlainObject, hasOwn, extend, capitalize } from 'uni-shared'; +import { isPlainObject, hasOwn, extend, capitalize, isString } from 'uni-shared'; let callbackId = 1; let proxy; @@ -18,8 +18,8 @@ function normalizeArg(arg) { } return arg; } -function initUTSInstanceMethod(async, opts, instanceId) { - return initProxyFunction(async, opts, instanceId); +function initUTSInstanceMethod(async, opts, instanceId, proxy) { + return initProxyFunction(async, opts, instanceId, proxy); } function getProxy() { if (!proxy) { @@ -27,13 +27,28 @@ function getProxy() { } return proxy; } -function resolveSyncResult(res) { +function resolveSyncResult(res, returnOptions, instanceId, proxy) { + // devtools 环境是字符串? + if (isString(res)) { + res = JSON.parse(res); + } if ((process.env.NODE_ENV !== 'production')) { - console.log('uts.invokeSync.result', res); + console.log('uts.invokeSync.result', res, returnOptions, instanceId, proxy); } if (res.errMsg) { throw new Error(res.errMsg); } + if (returnOptions) { + if (returnOptions.type === 'interface' && typeof res.params === 'number') { + if (res.params === instanceId && proxy) { + return proxy; + } + if (interfaceDefines[returnOptions.options]) { + const ProxyClass = initUTSProxyClass(extend({ instanceId: res.params }, interfaceDefines[returnOptions.options])); + return new ProxyClass(); + } + } + } return res.params; } function invokePropGetter(args) { @@ -46,7 +61,7 @@ function invokePropGetter(args) { } return resolveSyncResult(getProxy().invokeSync(args, () => { })); } -function initProxyFunction(async, { moduleName, moduleType, package: pkg, class: cls, name: propOrMethod, method, companion, params: methodParams, errMsg, }, instanceId) { +function initProxyFunction(async, { moduleName, moduleType, package: pkg, class: cls, name: propOrMethod, method, companion, params: methodParams, return: returnOptions, errMsg, }, instanceId, proxy) { const invokeCallback = ({ id, name, params, keepAlive, }) => { const callback = callbacks[id]; if (callback) { @@ -109,7 +124,7 @@ function initProxyFunction(async, { moduleName, moduleType, package: pkg, class: if ((process.env.NODE_ENV !== 'production')) { console.log('uts.invokeSync.args', invokeArgs); } - return resolveSyncResult(getProxy().invokeSync(invokeArgs, invokeCallback)); + return resolveSyncResult(getProxy().invokeSync(invokeArgs, invokeCallback), returnOptions, instanceId, proxy); }; } function initUTSStaticMethod(async, opts) { @@ -127,7 +142,14 @@ function parseClassMethodName(name, methods) { } return name; } -function initUTSProxyClass({ moduleName, moduleType, package: pkg, class: cls, constructor: { params: constructorParams }, methods, props, staticProps, staticMethods, errMsg, }) { +function isUndefined(value) { + return typeof value === 'undefined'; +} +function isProxyInterfaceOptions(options) { + return !isUndefined(options.instanceId); +} +function initUTSProxyClass(options) { + const { moduleName, moduleType, package: pkg, class: cls, methods, props, errMsg, } = options; const baseOptions = { moduleName, moduleType, @@ -135,6 +157,18 @@ function initUTSProxyClass({ moduleName, moduleType, package: pkg, class: cls, c class: cls, errMsg, }; + let instanceId; + let constructorParams = []; + let staticMethods = {}; + let staticProps = []; + if (isProxyInterfaceOptions(options)) { + instanceId = options.instanceId; + } + else { + constructorParams = options.constructor.params; + staticMethods = options.staticMethods; + staticProps = options.staticProps; + } // iOS 需要为 ByJs 的 class 构造函数(如果包含JSONObject或UTSCallback类型)补充最后一个参数 if (typeof plus !== 'undefined' && plus.os.name === 'iOS') { if (constructorParams.find((p) => p.type === 'UTSCallback' || p.type.indexOf('JSONObject') > 0)) { @@ -148,11 +182,14 @@ function initUTSProxyClass({ moduleName, moduleType, package: pkg, class: cls, c } const target = {}; // 初始化实例 ID - const instanceId = initProxyFunction(false, extend({ name: 'constructor', params: constructorParams }, baseOptions), 0).apply(null, params); + if (isUndefined(instanceId)) { + // 未指定instanceId + instanceId = initProxyFunction(false, extend({ name: 'constructor', params: constructorParams }, baseOptions), 0).apply(null, params); + } if (!instanceId) { throw new Error(`new ${cls} is failed`); } - return new Proxy(this, { + const proxy = new Proxy(this, { get(_, name) { if (!target[name]) { //实例方法 @@ -162,7 +199,7 @@ function initUTSProxyClass({ moduleName, moduleType, package: pkg, class: cls, c target[name] = initUTSInstanceMethod(!!async, extend({ name, params, - }, baseOptions), instanceId); + }, baseOptions), instanceId, proxy); } else if (props.includes(name)) { // 实例属性 @@ -178,6 +215,7 @@ function initUTSProxyClass({ moduleName, moduleType, package: pkg, class: cls, c return target[name]; }, }); + return proxy; } }; const staticMethodCache = {}; @@ -227,6 +265,10 @@ function initUTSClassName(moduleName, className, is_uni_modules) { } return ''; } +const interfaceDefines = {}; +function registerUTSInterface(name, define) { + interfaceDefines[name] = define; +} const pluginDefines = {}; function registerUTSPlugin(name, define) { pluginDefines[name] = define; @@ -239,4 +281,4 @@ function requireUTSPlugin(name) { return define; } -export { initUTSClassName, initUTSIndexClassName, initUTSPackageName, initUTSProxyClass, initUTSProxyFunction, normalizeArg, registerUTSPlugin, requireUTSPlugin }; +export { initUTSClassName, initUTSIndexClassName, initUTSPackageName, initUTSProxyClass, initUTSProxyFunction, normalizeArg, registerUTSInterface, registerUTSPlugin, requireUTSPlugin };