216 lines
5.3 KiB
JavaScript
216 lines
5.3 KiB
JavaScript
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__ };
|