function formatMessage(type, args) { try { return { type, args: formatArgs(args), }; } catch (e) { // originalConsole.error(e) } return { type, args: [], }; } function formatArgs(args) { return args.map((arg) => formatArg(arg)); } function formatArg(arg, depth = 0) { if (depth >= 7) { return { type: 'object', value: '[Maximum depth reached]', }; } const type = typeof arg; switch (type) { case 'string': return formatString(arg); case 'number': return formatNumber(arg); case 'boolean': return formatBoolean(arg); case 'object': try { // 鸿蒙里边 object 可能包含 nativePtr 指针,该指针 typeof 是 object // 但是又不能访问上边的任意属性,否则会报:TypeError: Can not get Prototype on non ECMA Object // 所以这里需要捕获异常,防止报错 return formatObject(arg, depth); } catch (e) { return { type: 'object', value: { properties: [], }, }; } case 'undefined': return formatUndefined(); case 'function': return formatFunction(arg); case 'symbol': { return formatUnknown('symbol', arg); } case 'bigint': return formatBigInt(arg); } } function formatFunction(value) { return { type: 'function', value: `function ${value.name}() {}`, }; } function formatUndefined() { return { type: 'undefined', }; } function formatBoolean(value) { return { type: 'boolean', value: String(value), }; } function formatNumber(value) { return { type: 'number', value: String(value), }; } function formatBigInt(value) { return { type: 'bigint', value: String(value), }; } function formatString(value) { return { type: 'string', value, }; } function formatUnknown(type, value) { return { type, value: String(value), }; } function formatObject(value, depth) { if (value === null) { return { type: 'null', }; } if (Array.isArray(value)) { return { type: 'object', subType: 'array', value: { properties: value.map((v, i) => formatArrayElement(v, i, depth + 1)), }, }; } if (value instanceof Set) { return { type: 'object', subType: 'set', className: 'Set', description: `Set(${value.size})`, value: { entries: Array.from(value).map((v) => formatSetEntry(v, depth + 1)), }, }; } if (value instanceof Map) { return { type: 'object', subType: 'map', className: 'Map', description: `Map(${value.size})`, value: { entries: Array.from(value.entries()).map((v) => formatMapEntry(v, depth + 1)), }, }; } if (value instanceof Promise) { return { type: 'object', subType: 'promise', value: { properties: [], }, }; } if (value instanceof RegExp) { return { type: 'object', subType: 'regexp', value: String(value), className: 'Regexp', }; } if (value instanceof Date) { return { type: 'object', subType: 'date', value: String(value), className: 'Date', }; } if (value instanceof Error) { return { type: 'object', subType: 'error', value: value.message || String(value), className: value.name || 'Error', }; } let className = undefined; let entries = Object.entries(value); if (isHarmonyBuilderParams(value)) { entries = entries.filter(([key]) => key !== 'modifier' && key !== 'nodeContent'); } return { type: 'object', className, value: { properties: entries.map((entry) => formatObjectProperty(entry[0], entry[1], depth + 1)), }, }; } function isHarmonyBuilderParams(value) { return value.modifier && value.modifier._attribute && value.nodeContent; } function formatObjectProperty(name, value, depth) { const result = formatArg(value, depth); result.name = name; return result; } function formatArrayElement(value, index, depth) { const result = formatArg(value, depth); result.name = `${index}`; return result; } function formatSetEntry(value, depth) { return { value: formatArg(value, depth), }; } function formatMapEntry(value, depth) { return { key: formatArg(value[0], depth), value: formatArg(value[1], depth), }; } function __f__(type, filename, ...args) { const message = formatMessage(type, [...args, filename]); return message; } export { __f__ };