Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v3.8.6] Mark some properties as @dontmangle. #18160

Open
wants to merge 12 commits into
base: v3.8.6
Choose a base branch
from
13 changes: 11 additions & 2 deletions cocos/core/curves/keyframe-curve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@
if (values !== undefined) {
assertIsTrue(Array.isArray(times));
this.setKeyframes(
times.slice(),

Check failure on line 225 in cocos/core/curves/keyframe-curve.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any[]` assigned to a parameter of type `number[]`
values.slice(),
);
} else {
Expand Down Expand Up @@ -280,9 +280,18 @@
return iNext;
}

// Times are always sorted and 1-1 correspond to values.
/**
* Times are always sorted and 1-1 correspond to values.
* @dontmangle
* NOTE: _times is a serializable property set by `CCClass.fastDefine`,
* so it should not be mangled while `mangleProtected` is true in `<<ProjectRoot>>/engine-mangle-config.json`.
*/
protected _times: number[] = [];

/**
* @dontmangle
* NOTE: _values is a serializable property set by `CCClass.fastDefine`,
* so it should not be mangled while `mangleProtected` is true in `<<ProjectRoot>>/engine-mangle-config.json`.
*/
protected _values: TKeyframeValue[] = [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

protected member variable will be mangled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file engine-mangle-config.json supports to control whether to mangle protected properties globally, its default value is false which means protected properties will not be mangled. But if developers set it to true, then all protected properties will be mangled too. The file format is :

{
	"common": {
	    "mangleProtected": false, // <------- here
	    "mangleList": [
	    	"MyClass2",
	    	"MyClass.foo",
	    	"MyClass.getBar"
	    ],
	    "dontMangleList": [
	        "BaseFactory",
	        "Slot",
	        "MyClass.hello"
	    ]
	},
	"web-mobile": {
		"extends": "common",
		"mangleList": [
			"MyClass3",
			"MyClass4.haha",
			"MyClass4.w111uwu"
		],
		"dontMangleList": [
			"MyClass5.skldjfl"
		]
	}
}

So if developer set mangleProtected to true, some properties are set by cc.fastDefine to mark them as serializable, so they should not be mangled. In this case, we should make sure some properties in engine should not be mangled by jsdoc tag @dontmangle.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example:

CCClass.fastDefine('cc.AnimationCurve', AnimationCurve, {
    _curve: null, // <---- the protected property _curve should not be mangled.
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. If so, then how to determine if a protected variable can be mangled or not? What i mean is how to know if need to add @@dontmangle for protected variables?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to review the code to decide. So the mangleProtected is disabled (false) by default.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to review the code to decide.

Is there a simple rule to determine it? If not, then it will be hard to maintain the codes. And how to make sure it work or not, is there a CI to check it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, we haven't enable CI to run the feature of mangleProperties. I will discuss with QA team after editor is updated.

}

Expand Down
6 changes: 6 additions & 0 deletions cocos/core/data/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@
* @internal
*/
public _objFlags: number = 0;

/**
* @dontmangle
* NOTE: _name is a serializable property set by `CCClass.fastDefine`,
* so it should not be mangled while `mangleProtected` is true in `<<ProjectRoot>>/engine-mangle-config.json`.
*/
protected declare _name: string;

constructor (name = '') {
Expand Down Expand Up @@ -384,7 +390,7 @@

const prototype = CCObject.prototype;
if (EDITOR || TEST) {
js.get(prototype, 'isRealValid', function (this: CCObject) {

Check warning on line 393 in cocos/core/data/object.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
return !(this._objFlags & RealDestroyed);
});

Expand All @@ -396,10 +402,10 @@
js.getset(
prototype,
'objFlags',
function (this: CCObject) {

Check warning on line 405 in cocos/core/data/object.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
return this._objFlags;
},
function (this: CCObject, objFlags: CCObject.Flags) {

Check warning on line 408 in cocos/core/data/object.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
this._objFlags = objFlags;
},
);
Expand All @@ -416,7 +422,7 @@
* TODO: this is a dynamic inject method, should be define in class
* issue: https://github.com/cocos/cocos-engine/issues/14643
*/
(prototype as any).realDestroyInEditor = function (): void {

Check warning on line 425 in cocos/core/data/object.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
if (!(this._objFlags & Destroyed)) {
warnID(5001);
return;
Expand Down
7 changes: 7 additions & 0 deletions cocos/core/event/eventify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ export interface IEventified {
*/
export function Eventify<TBase> (base: Constructor<TBase>): Constructor<TBase & IEventified> {
class Eventified extends (base as unknown as any) {
/**
* @dontmangle
* NOTE: Eventified mixins all properties from CallbacksInvoker.prototype in the following code.
* After invoking `Eventify` for a class, CallbacksInvoker's constructor will not be called,
* but its functions may invoke `this._callbackTable` which is declared as `public` in CallbacksInvoker.
* Marking it as dontmangle is a workaround to avoid the issue that `this._callbackTable` is not defined.
*/
protected _callbackTable = createMap(true);

public once<Callback extends (...any) => void> (type: EventType, callback: Callback, target?: any): Callback {
Expand Down
5 changes: 5 additions & 0 deletions cocos/core/geometry/curve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@
* 描述一条曲线,其中每个相邻关键帧采用三次hermite插值计算。
*/
export class AnimationCurve {
/**
* @dontmangle
* NOTE: _curve is a serializable property set by `CCClass.fastDefine`,
* so it should not be mangled while `mangleProtected` is true in `<<ProjectRoot>>/engine-mangle-config.json`.
*/
private _curve!: RealCurve;

private static defaultKF: Keyframe[] = [{
Expand Down Expand Up @@ -336,7 +341,7 @@
let mid;
while (right - left > 1) {
mid = Math.floor((left + right) / 2);
if (curve.getKeyframeTime(mid) >= t) {

Check failure on line 344 in cocos/core/geometry/curve.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unsafe argument of type `any` assigned to a parameter of type `number`
right = mid;
} else {
left = mid;
Expand Down
27 changes: 15 additions & 12 deletions cocos/scene-graph/node-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

export function nodePolyfill (Node): void {
if ((EDITOR && !IS_PREVIEW) || TEST) {
Node.prototype._onPreDestroy = function (): boolean {

Check warning on line 37 in cocos/scene-graph/node-dev.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
const destroyByParent: boolean = this._onPreDestroyBase();
if (!destroyByParent) {
// ensure this node can reattach to scene by undo system
Expand All @@ -46,13 +46,13 @@
}

if (EDITOR || TEST) {
Node.prototype._checkMultipleComp = function (ctor): boolean {

Check warning on line 49 in cocos/scene-graph/node-dev.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
const existing = this.getComponent(ctor._disallowMultiple);
if (existing) {
if (existing.constructor === ctor) {
throw Error(getError(3805, js.getClassName(ctor), this._name));
throw Error(getError(3805, js.getClassName(ctor), this._name as string));
} else {
throw Error(getError(3806, js.getClassName(ctor), this._name, js.getClassName(existing)));
throw Error(getError(3806, js.getClassName(ctor), this._name as string, js.getClassName(existing)));
}
}
return true;
Expand All @@ -62,12 +62,12 @@
* @param {Component} depended
* @return {Component[]}
*/
Node.prototype._getDependComponent = function (depended): Component[] {

Check warning on line 65 in cocos/scene-graph/node-dev.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
const dependant: Component[] = [];
for (let i = 0; i < this._components.length; i++) {
const comp = this._components[i];
const comp: Component = this._components[i];
if (comp !== depended && comp.isValid && !legacyCC.Object._willDestroy(comp)) {
const reqComps = comp.constructor._requireComponent;
const reqComps = (comp.constructor as typeof Component)._requireComponent;
if (reqComps) {
if (Array.isArray(reqComps)) {
for (let i = 0; i < reqComps.length; i++) {
Expand All @@ -89,7 +89,7 @@
* @param {Component} comp
* @param {Number} index
*/
Node.prototype._addComponentAt = function (comp, index): void {
Node.prototype._addComponentAt = function (comp: Component, index: number): void {

Check warning on line 92 in cocos/scene-graph/node-dev.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
if (this._objFlags & Destroying) {
return error('isDestroying');
}
Expand All @@ -101,7 +101,7 @@
}

// recheck attributes because script may changed
const ctor = comp.constructor;
const ctor = comp.constructor as any;
if (ctor._disallowMultiple) {
if (!this._checkMultipleComp(ctor)) {
return undefined;
Expand All @@ -125,7 +125,7 @@
comp.node = this;
this._components.splice(index, 0, comp);
if (EDITOR && !IS_PREVIEW && EditorExtends.Node && EditorExtends.Component) {
const node = EditorExtends.Node.getNode(this._id);
const node = EditorExtends.Node.getNode(this._id as string);
if (node) {
EditorExtends.Component.add(comp._id, comp);
}
Expand All @@ -136,7 +136,7 @@
return undefined;
};

Node.prototype.onRestore = function (): void {

Check warning on line 139 in cocos/scene-graph/node-dev.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
// check activity state
const shouldActiveNow = this._active && !!(this._parent && this._parent._activeInHierarchy);
if (this._activeInHierarchy !== shouldActiveNow) {
Expand All @@ -145,34 +145,37 @@
};
Node.prototype._onRestoreBase = Node.prototype.onRestore;

Node.prototype._registerIfAttached = function (register): void {

Check warning on line 148 in cocos/scene-graph/node-dev.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected unnamed function
if (!this._id) {
// eslint-disable-next-line no-console
console.warn(`Node(${this && this.name}}) is invalid or its data is corrupted.`);
return;
}
if (EditorExtends.Node && EditorExtends.Component) {
if (register) {
EditorExtends.Node.add(this._id, this);
EditorExtends.Node.add(this._id as string, this);

for (let i = 0; i < this._components.length; i++) {
const comp = this._components[i];
if (!comp || !comp._id) {
// eslint-disable-next-line no-console
console.warn(`Component attached to node:${this.name} is corrupted`);
} else {
EditorExtends.Component.add(comp._id, comp);
EditorExtends.Component.add(comp._id as string, comp);
}
}
} else {
for (let i = 0; i < this._components.length; i++) {
const comp = this._components[i];
if (!comp || !comp._id) {
// eslint-disable-next-line no-console
console.warn(`Component attached to node:${this.name} is corrupted`);
} else {
EditorExtends.Component.remove(comp._id);
EditorExtends.Component.remove(comp._id as string);
}
}

EditorExtends.Node.remove(this._id);
EditorExtends.Node.remove(this._id as string);
}
}

Expand All @@ -186,7 +189,7 @@

if (DEV) {
// promote debug info
js.get(Node.prototype, ' INFO ', function (this: any) {
js.get(Node.prototype as Record<string, any>, ' INFO ', function (this: any) {
let path = '';
// eslint-disable-next-line @typescript-eslint/no-this-alias
let node: any = this;
Expand Down
8 changes: 8 additions & 0 deletions cocos/scene-graph/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,14 @@ export class Node extends CCObject implements ISchedulable, CustomSerializable {
this.emit(NodeEventType.CHILDREN_ORDER_CHANGED);
}

/**
* @dontmangle
* NOTE: the protected method `_instantiate` is invoked by dynamically without type information.
* See `instantiate` in cocos/serialization/instantiate.ts.
* ```ts
* clone = original._instantiate(null, true); // original is any, so _instantiate should not be mangled.
* ```
*/
protected _instantiate (cloned?: Node | null, isSyncedNode: boolean = false): Node {
if (!cloned) {
cloned = cclegacy.instantiate._clone(this, this) as Node;
Expand Down
8 changes: 8 additions & 0 deletions cocos/scene-graph/prefab/prefab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ export class Prefab extends Asset {
return this._createFunction!(rootToRedirect); // this.data._instantiate();
}

/**
* @dontmangle
* NOTE: the protected method `_instantiate` is invoked by dynamically without type information.
* See `instantiate` in cocos/serialization/instantiate.ts.
* ```ts
* clone = original._instantiate(null, true); // original is any, so _instantiate should not be mangled.
* ```
*/
protected _instantiate (): Node {
let node: Node;
let useJit = false;
Expand Down
Loading