Match-id-0dfbd7fa96536fa2974eadfdad81039cf02f279a

This commit is contained in:
* 2022-08-03 14:46:06 +08:00 committed by *
parent bdd2ad3cce
commit e31ed399de
7 changed files with 68 additions and 45 deletions

View File

@ -2,7 +2,7 @@ module.exports = {
presets: [ presets: [
'@babel/react', '@babel/react',
'@babel/preset-typescript', '@babel/preset-typescript',
['@babel/preset-env', { targets: { node: 'current' } }] ['@babel/preset-env', { targets: { node: 'current' } }],
], ],
plugins: [ plugins: [
['@babel/plugin-proposal-class-properties', { loose: true }], ['@babel/plugin-proposal-class-properties', { loose: true }],
@ -34,5 +34,6 @@ module.exports = {
pragma: 'Horizon.createElement', pragma: 'Horizon.createElement',
pragmaFrag: 'Horizon.Fragment' pragmaFrag: 'Horizon.Fragment'
}], }],
['@babel/plugin-transform-react-jsx-source'],
], ],
}; };

View File

@ -9,10 +9,11 @@ import { getProcessingClassVNode } from '../renderer/GlobalVar';
* ref ref属性 * ref ref属性
* props * props
*/ */
export function JSXElement(type, key, ref, vNode, props) { export function JSXElement(type, key, ref, vNode, props, source) {
return { return {
// 元素标识符 // 元素标识符
vtype: TYPE_COMMON_ELEMENT, vtype: TYPE_COMMON_ELEMENT,
source: source,
// 属于元素的内置属性 // 属于元素的内置属性
type: type, type: type,
@ -26,7 +27,13 @@ export function JSXElement(type, key, ref, vNode, props) {
} }
function isValidKey(key) { function isValidKey(key) {
return key !== 'key' && key !== 'ref' && key !== '__source'; const keyArray = [
'key',
'ref',
'__source',
'__self'
];
return !keyArray.includes(key);
} }
function mergeDefault(sourceObj, defaultObj) { function mergeDefault(sourceObj, defaultObj) {
@ -67,7 +74,9 @@ function buildElement(isClone, type, setting, children) {
mergeDefault(props, element.defaultProps); mergeDefault(props, element.defaultProps);
} }
return JSXElement(element, key, ref, vNode, props); const source = setting?.__source === undefined ? null : setting.__source;
return JSXElement(element, key, ref, vNode, props, source);
} }
// 创建Element结构体供JSX编译时调用 // 创建Element结构体供JSX编译时调用

View File

@ -1,12 +1,5 @@
import { travelVNodeTree } from '../renderer/vnode/VNodeUtils'; import { travelVNodeTree } from '../renderer/vnode/VNodeUtils';
import { import { Hook, Reducer, Ref, Effect, CallBack, Memo } from '../renderer/hooks/HookType';
Hook,
Reducer,
Ref,
Effect,
CallBack,
Memo
} from '../renderer/hooks/HookType';
import { VNode } from '../renderer/vnode/VNode'; import { VNode } from '../renderer/vnode/VNode';
import { launchUpdateFromVNode } from '../renderer/TreeBuilder'; import { launchUpdateFromVNode } from '../renderer/TreeBuilder';
import { DomComponent } from '../renderer/vnode/VNodeTags'; import { DomComponent } from '../renderer/vnode/VNodeTags';
@ -26,7 +19,7 @@ const HookName = {
MemoHook: 'Memo', MemoHook: 'Memo',
RefHook: 'Ref', RefHook: 'Ref',
ReducerHook: 'Reducer', ReducerHook: 'Reducer',
CallbackHook: 'Callback' CallbackHook: 'Callback',
}; };
export const helper = { export const helper = {
@ -45,7 +38,8 @@ export const helper = {
} else if (isRefHook(state)) { } else if (isRefHook(state)) {
return { name: HookName.RefHook, hIndex, value: (state as Ref<any>).current }; return { name: HookName.RefHook, hIndex, value: (state as Ref<any>).current };
} else if (isEffectHook(state)) { } else if (isEffectHook(state)) {
const name = state.effectConstant == EffectConstant.LayoutEffect ? HookName.LayoutEffectHook : HookName.EffectHook; const name =
state.effectConstant == EffectConstant.LayoutEffect ? HookName.LayoutEffectHook : HookName.EffectHook;
return { name, hIndex, value: (state as Effect).effect }; return { name, hIndex, value: (state as Effect).effect };
} else if (isCallbackHook(state)) { } else if (isCallbackHook(state)) {
return { name: HookName.CallbackHook, hIndex, value: (state as CallBack<any>).func }; return { name: HookName.CallbackHook, hIndex, value: (state as CallBack<any>).func };
@ -86,7 +80,7 @@ export const helper = {
} }
if (hooks && hooks.length !== 0) { if (hooks && hooks.length !== 0) {
const logHookInfo: any[] = []; const logHookInfo: any[] = [];
hooks.forEach((hook) => { hooks.forEach(hook => {
const state = hook.state as Reducer<any, any>; const state = hook.state as Reducer<any, any>;
if (state.trigger && state.isUseState) { if (state.trigger && state.isUseState) {
logHookInfo.push(state.stateValue); logHookInfo.push(state.stateValue);
@ -94,20 +88,26 @@ export const helper = {
}); });
info['Hooks'] = logHookInfo; info['Hooks'] = logHookInfo;
} }
travelVNodeTree(vNode, (node: VNode) => { travelVNodeTree(
if (node.tag === DomComponent) { vNode,
// 找到组件的第一个dom元素返回它所在父节点的全部子节点 (node: VNode) => {
const dom = node.realNode; if (node.tag === DomComponent) {
info['Nodes'] = dom?.parentNode?.childNodes; // 找到组件的第一个dom元素返回它所在父节点的全部子节点
return true; const dom = node.realNode;
} info['Nodes'] = dom?.parentNode?.childNodes;
return false; return true;
}, null, vNode, null); }
return false;
},
null,
vNode,
null
);
return info; return info;
}, },
getElementTag: (element: JSXElement) => { getElementTag: (element: JSXElement) => {
return getElementTag(element); return getElementTag(element);
} },
}; };
export function injectUpdater() { export function injectUpdater() {

View File

@ -3,20 +3,16 @@ export { VNode } from './vnode/VNode';
type Trigger<A> = (A) => void; type Trigger<A> = (A) => void;
export type UseStateHookType = { export type UseStateHookType = {
useState<S>( useState<S>(initialState: (() => S) | S): [S, Trigger<((S) => S) | S>];
initialState: (() => S) | S
): [S, Trigger<((S) => S) | S>];
}; };
export type UseReducerHookType = { export type UseReducerHookType = {
useReducer<S, P, A>( useReducer<S, P, A>(reducer: (S, A) => S, initArg: P, init?: (P) => S): [S, Trigger<A>];
reducer: (S, A) => S,
initArg: P, init?: (P) => S,
): [S, Trigger<A>];
}; };
export type UseContextHookType = { useContext<T>(context: ContextType<T>,): T }; export type UseContextHookType = { useContext<T>(context: ContextType<T>): T };
export type JSXElement = { export type JSXElement = {
vtype: any; vtype: any;
source: any;
type: any; type: any;
key: any; key: any;
ref: any; ref: any;
@ -50,7 +46,7 @@ export type RefType = {
export interface PromiseType<R> { export interface PromiseType<R> {
then<U>( then<U>(
onFulfill: (value: R) => void | PromiseType<U> | U, onFulfill: (value: R) => void | PromiseType<U> | U,
onReject: (error: any) => void | PromiseType<U> | U, onReject: (error: any) => void | PromiseType<U> | U
): void | PromiseType<U>; ): void | PromiseType<U>;
} }
@ -61,3 +57,9 @@ export interface SuspenseState {
didCapture: boolean; // suspense是否捕获了异常 didCapture: boolean; // suspense是否捕获了异常
promiseResolved: boolean; // suspense的promise是否resolve promiseResolved: boolean; // suspense的promise是否resolve
} }
export type Source = {
columnNumber: number;
fileName: string;
lineNumber: number;
};

View File

@ -18,7 +18,7 @@ import {
MemoComponent, MemoComponent,
} from './VNodeTags'; } from './VNodeTags';
import type { VNodeTag } from './VNodeTags'; import type { VNodeTag } from './VNodeTags';
import type { RefType, ContextType, SuspenseState } from '../Types'; import type { RefType, ContextType, SuspenseState, Source } from '../Types';
import type { Hook } from '../hooks/HookType'; import type { Hook } from '../hooks/HookType';
import { InitFlag } from './VNodeFlags'; import { InitFlag } from './VNodeFlags';
@ -86,6 +86,7 @@ export class VNode {
isStoreChange: boolean; isStoreChange: boolean;
observers: Set<any> | null = null; // 记录这个函数组件/类组件依赖哪些Observer observers: Set<any> | null = null; // 记录这个函数组件/类组件依赖哪些Observer
classComponentWillUnmount: Function | null; // HorizonX会在classComponentWillUnmount中清除对VNode的引入用 classComponentWillUnmount: Function | null; // HorizonX会在classComponentWillUnmount中清除对VNode的引入用
source: Source | null; // 节点所在代码位置
constructor(tag: VNodeTag, props: any, key: null | string, realNode) { constructor(tag: VNodeTag, props: any, key: null | string, realNode) {
this.tag = tag; // 对应组件的类型比如ClassComponent等 this.tag = tag; // 对应组件的类型比如ClassComponent等
@ -116,6 +117,7 @@ export class VNode {
this.isStoreChange = false; this.isStoreChange = false;
this.observers = null; this.observers = null;
this.classComponentWillUnmount = null; this.classComponentWillUnmount = null;
this.source = null;
break; break;
case ClassComponent: case ClassComponent:
this.realNode = null; this.realNode = null;
@ -130,15 +132,18 @@ export class VNode {
this.isStoreChange = false; this.isStoreChange = false;
this.observers = null; this.observers = null;
this.classComponentWillUnmount = null; this.classComponentWillUnmount = null;
this.source = null;
break; break;
case DomPortal: case DomPortal:
this.realNode = null; this.realNode = null;
this.context = null; this.context = null;
this.source = null;
break; break;
case DomComponent: case DomComponent:
this.realNode = null; this.realNode = null;
this.changeList = null; this.changeList = null;
this.context = null; this.context = null;
this.source = null;
break; break;
case DomText: case DomText:
this.realNode = null; this.realNode = null;
@ -152,12 +157,15 @@ export class VNode {
oldChildStatus: '', oldChildStatus: '',
childStatus: '' childStatus: ''
}; };
this.source = null;
break; break;
case ContextProvider: case ContextProvider:
this.source = null;
this.context = null; this.context = null;
break; break;
case MemoComponent: case MemoComponent:
this.effectList = null; this.effectList = null;
this.source = null;
break; break;
case LazyComponent: case LazyComponent:
this.realNode = null; this.realNode = null;
@ -165,6 +173,7 @@ export class VNode {
this.isLazyComponent = true; this.isLazyComponent = true;
this.lazyType = null; this.lazyType = null;
this.updates = null; this.updates = null;
this.source = null;
break; break;
case Fragment: case Fragment:
break; break;

View File

@ -17,10 +17,13 @@ import {
} from './VNodeTags'; } from './VNodeTags';
import { import {
TYPE_CONTEXT, TYPE_CONTEXT,
TYPE_FORWARD_REF, TYPE_FRAGMENT, TYPE_FORWARD_REF,
TYPE_FRAGMENT,
TYPE_LAZY, TYPE_LAZY,
TYPE_MEMO, TYPE_PROFILER, TYPE_MEMO,
TYPE_PROVIDER, TYPE_STRICT_MODE, TYPE_PROFILER,
TYPE_PROVIDER,
TYPE_STRICT_MODE,
TYPE_SUSPENSE, TYPE_SUSPENSE,
} from '../../external/JSXElementType'; } from '../../external/JSXElementType';
import { VNode } from './VNode'; import { VNode } from './VNode';
@ -56,7 +59,7 @@ export function getLazyVNodeTag(lazyComp: any): string {
} else if (lazyComp !== undefined && lazyComp !== null && typeLazyMap[lazyComp.vtype]) { } else if (lazyComp !== undefined && lazyComp !== null && typeLazyMap[lazyComp.vtype]) {
return typeLazyMap[lazyComp.vtype]; return typeLazyMap[lazyComp.vtype];
} }
throw Error('Horizon can\'t resolve the content of lazy'); throw Error("Horizon can't resolve the content of lazy");
} }
// 创建processing // 创建processing
@ -102,7 +105,7 @@ export function createPortalVNode(portal) {
return vNode; return vNode;
} }
export function createUndeterminedVNode(type, key, props) { export function createUndeterminedVNode(type, key, props, source) {
let vNodeTag = FunctionComponent; let vNodeTag = FunctionComponent;
let isLazy = false; let isLazy = false;
const componentType = typeof type; const componentType = typeof type;
@ -129,6 +132,7 @@ export function createUndeterminedVNode(type, key, props) {
if (isLazy) { if (isLazy) {
vNode.lazyType = type; vNode.lazyType = type;
} }
vNode.source = source;
return vNode; return vNode;
} }
@ -181,14 +185,12 @@ export function createVNode(tag: VNodeTag | string, ...secondArg) {
} }
export function createVNodeFromElement(element: JSXElement): VNode { export function createVNodeFromElement(element: JSXElement): VNode {
const type = element.type; const { type, key, props, source } = element;
const key = element.key;
const props = element.props;
if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) { if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) {
return createFragmentVNode(key, props.children); return createFragmentVNode(key, props.children);
} else { } else {
return createUndeterminedVNode(type, key, props); return createUndeterminedVNode(type, key, props, source);
} }
} }
@ -241,4 +243,3 @@ export function onlyUpdateChildVNodes(processing: VNode): VNode | null {
// 子树无需工作 // 子树无需工作
return null; return null;
} }

View File

@ -37,6 +37,7 @@
"@babel/plugin-transform-shorthand-properties": "7.16.7", "@babel/plugin-transform-shorthand-properties": "7.16.7",
"@babel/plugin-transform-spread": "7.16.7", "@babel/plugin-transform-spread": "7.16.7",
"@babel/plugin-transform-template-literals": "7.16.7", "@babel/plugin-transform-template-literals": "7.16.7",
"@babel/plugin-transform-react-jsx-source": "^7.18.6",
"@babel/preset-env": "7.16.7", "@babel/preset-env": "7.16.7",
"@babel/preset-react": "7.16.7", "@babel/preset-react": "7.16.7",
"@babel/preset-typescript": "7.16.7", "@babel/preset-typescript": "7.16.7",