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

Support parse method result #2485

Merged
merged 8 commits into from
Jan 6, 2025

Conversation

zhuxudong
Copy link
Member

@zhuxudong zhuxudong commented Jan 2, 2025

engine don't support add class and parse callback props in loader, and only support add class as parameter such as colliderShape:

"methods": {
"addShape": [
[
{
"class": "BoxColliderShape",
"props": {
"isTrigger": false,
"size": {
"x": 10,
"y": 10,
"z": 10
},
"position": {
"x": 0,
"y": 0,
"z": 0
},
"rotation": {
"x": 0,
"y": 0,
"z": 0
}
}
}
]
]
}

now i need just add Class in engine parser, add parse some props on returned instance:

const effect = component.addEffect(BloomEffect);
effect.intensity.value = 1;

onSerialize data:
image

Summary by CodeRabbit

  • New Features

    • Enhanced type system to support more complex class-like objects.
    • Introduced a new method to identify real class objects.
  • Improvements

    • Refined parsing logic for method callbacks.
    • Updated type definitions to accommodate advanced class representations.
    • Improved handling of method parameters with new type definitions.
    • Updated type references in the SceneLoader for consistency with new class structures.
    • Removed unused imports from the SceneLoader for cleaner code.

Copy link

coderabbitai bot commented Jan 2, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

The changes enhance the resource deserialization process in the loader package by modifying the ReflectionParser and BasicSchema. The updates introduce four new types, IClass, IClassType, IMethod, and IMethodParams, while removing IClassObject and IComponentRef. Method signatures in ReflectionParser have been updated to improve type handling, particularly in parseClassObject, parsePropsAndMethods, and parseMethod. Additionally, the SceneLoader class has been updated to reflect these type changes, ensuring consistency across the parsing logic.

Changes

File Change Summary
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts - Added types IClass, IClassType, IMethod, and IMethodParams
- Updated method signatures for parseClassObject, parsePropsAndMethods, and parseMethod
- Renamed _isClass to _isClassType and added _isMethodObject
packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts - Updated IMethodParams to allow IMethod
- Renamed IClassObject to IClass
- Modified constructParams in IClass
- Introduced IInstance interface and IClassType type
- Updated IBasicType to include IClass and IClassType
packages/loader/src/SceneLoader.ts - Updated import statement to use IClass instead of IClassObject
- Updated method signature in ReflectionParser.registerCustomParseComponent

Possibly related PRs

  • Support parse method result #2485: This PR directly modifies the ReflectionParser class in ReflectionParser.ts, making similar changes to type imports and method signatures, particularly around IClass, IMethod, and IMethodParams, which are also central to the main PR.

Suggested reviewers

  • luzhuang

Poem

🐰 In the land of code where bunnies play,
New types hop in, brightening the day!
Methods and params, a dance so neat,
Reflection's magic, a coder's treat!
With each little change, we leap and cheer,
Parsing delights, our vision is clear! 🌟


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c2c29f and ff700c5.

📒 Files selected for processing (1)
  • packages/loader/src/SceneLoader.ts (2 hunks)

Finishing Touches

  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Jan 2, 2025

Codecov Report

Attention: Patch coverage is 76.92308% with 9 lines in your changes missing coverage. Please review.

Project coverage is 68.40%. Comparing base (42d0927) to head (ff700c5).
Report is 34 commits behind head on dev/1.4.

Files with missing lines Patch % Lines
packages/loader/src/SceneLoader.ts 33.33% 6 Missing ⚠️
...e-deserialize/resources/parser/ReflectionParser.ts 90.00% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           dev/1.4    #2485      +/-   ##
===========================================
- Coverage    68.42%   68.40%   -0.02%     
===========================================
  Files          923      923              
  Lines        95904    96047     +143     
  Branches      8138     8136       -2     
===========================================
+ Hits         65621    65704      +83     
- Misses       30029    30089      +60     
  Partials       254      254              
Flag Coverage Δ
unittests 68.40% <76.92%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (1)

181-183: Recommendation for stronger type enforcement
Currently, _isRealClass checks that classReal is not undefined. For more robust type checking, consider also verifying that classReal is a string.

- return value["classReal"] !== undefined;
+ return typeof value["classReal"] === "string";
packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (1)

81-85: Consider documenting callbackProps usage
The callbackProps field significantly impacts parsing logic. A short comment or docstring explaining the purpose and format of callbackProps would improve maintainability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42d0927 and 95c31f3.

📒 Files selected for processing (2)
  • packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (3 hunks)
  • packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (2 hunks)
🔇 Additional comments (3)
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (2)

101-103: Confirm return value for real class references
Here, returning Loader.getClass(value["classReal"]) only yields the constructor rather than an instantiated object. Verify that the calling code intends to handle the class constructor and not an instance. If you need an instance, consider calling new on the constructor.


6-7: Nice addition for type imports
The introduction of IClassRealObject is consistent with the new schema logic. Please verify that IComponentRef is indeed utilized in this file to avoid importing unused types.

✅ Verification successful

IComponentRef type is actively used in the codebase

The type IComponentRef is properly utilized within the ReflectionParser class through:

  • A type guard method _isComponentRef that checks if a value conforms to the IComponentRef interface
  • The type is used in the method's return type annotation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check references to "IComponentRef" in this file
rg "IComponentRef" packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts -A 5

Length of output: 355

packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (1)

94-94: Great addition to IBasicType
Extending the union with IClassRealObject is consistent with the updated parser logic.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (4)

80-81: Remove redundant optional chaining

The optional chaining on firstParam?.callbackProps is redundant since we've already validated firstParam in the if condition.

- const callbackProps = firstParam?.callbackProps;
+ const callbackProps = firstParam.callbackProps;

82-94: Simplify promise handling and add error handling

The promise chain could be simplified and should include error handling for invalid callback properties.

Consider this refactoring:

- const promises = [];
- for (let key in callbackProps) {
-   const value = callbackProps[key];
-   const promise = this.parseBasicType(value, methodCallback[key]).then((v) => {
-     if (methodCallback[key] !== v) {
-       methodCallback[key] = v;
-     }
-     return v;
-   });
-   promises.push(promise);
- }
- return Promise.all(promises);
+ return Promise.all(
+   Object.entries(callbackProps).map(([key, value]) => {
+     if (!(key in methodCallback)) {
+       console.warn(`Callback property "${key}" not found in method result`);
+       return Promise.resolve();
+     }
+     return this.parseBasicType(value, methodCallback[key])
+       .then(v => {
+         if (methodCallback[key] !== v) {
+           methodCallback[key] = v;
+         }
+       })
+       .catch(error => {
+         console.error(`Failed to parse callback property "${key}":`, error);
+       });
+   })
+ ).then(() => methodCallback);

105-107: Add validation for class resolution

The class resolution could fail if the class name is invalid. Consider adding validation.

 if (ReflectionParser._isRealClass(value)) {
-  return Promise.resolve(Loader.getClass(value["classReal"]));
+  const className = value["classReal"];
+  const Class = Loader.getClass(className);
+  if (!Class) {
+    return Promise.reject(new Error(`Failed to resolve class "${className}"`));
+  }
+  return Promise.resolve(Class);
 }

185-187: Strengthen type guard implementation

The type guard could be more robust by checking the type of the "classReal" property.

 private static _isRealClass(value: any): value is IClassObject {
-  return value["classReal"] !== undefined;
+  return value && typeof value === "object" && typeof value["classReal"] === "string";
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95c31f3 and 45fe351.

📒 Files selected for processing (1)
  • packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (3 hunks)
🔇 Additional comments (2)
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (2)

6-7: LGTM! Type imports align with the new functionality.

The addition of IClassRealObject and IComponentRef types supports the new callback properties parsing feature.


76-97: Verify callback props usage and backwards compatibility

Let's verify the usage of callback props and ensure backwards compatibility.

✅ Verification successful

Let me gather more information about the callback props implementation to ensure there are no breaking changes.


Let me do one final check to understand the usage pattern and potential impact.


Callback props implementation appears safe and isolated

Based on the verification results, the callback props feature is a new addition that:

  1. Is properly defined in the schema (BasicSchema.ts) as an optional property
  2. Is only used within the ReflectionParser class for method parameter processing
  3. Has minimal integration points (only SceneLoader uses ReflectionParser)
  4. Maintains backward compatibility since:
    • callbackProps is optional in the schema
    • The implementation preserves existing behavior when callbackProps is not present
    • No existing code patterns were found that would be affected by this change
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for existing method calls that might be affected
echo "Searching for method calls that might need updates..."
rg -l "addEffect|addShape" --type ts

# Search for potential callback props usage
echo "Searching for callback props usage..."
ast-grep --pattern 'callbackProps: { $$$' --lang ts

# Search for tests covering this functionality
echo "Searching for related tests..."
fd -e test.ts -e spec.ts | xargs rg "callbackProps|addEffect|addShape"

Length of output: 9832


Script:

#!/bin/bash
# Search for the ReflectionParser class implementation and usage
echo "Searching for ReflectionParser implementation..."
rg -A 5 "class ReflectionParser" --type ts

# Search for method parameters with callback properties
echo "Searching for method parameters with callback properties..."
ast-grep --pattern 'interface $_Props {
  $$$
  callbackProps?: {
    $$$
  }
  $$$
}' --lang ts

# Search for files importing ReflectionParser
echo "Searching for ReflectionParser usage..."
rg "import.*ReflectionParser" --type ts

Length of output: 1501


Script:

#!/bin/bash
# Check SceneLoader implementation for ReflectionParser usage
echo "Checking SceneLoader implementation..."
rg -A 10 "ReflectionParser" packages/loader/src/SceneLoader.ts

# Look for any existing callbackProps usage in the codebase
echo "Searching for callbackProps usage in the codebase..."
rg "callbackProps" --type ts -A 3

# Check for any related tests
echo "Looking for related parser tests..."
fd "parser|reflection" -e test.ts -e spec.ts | xargs cat

Length of output: 2664

Comment on lines 78 to 79
const firstParam = methodParams?.[0] as IClassRealObject;
if (ReflectionParser._isRealClass(firstParam)) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Unsafe type assertion needs validation

The type assertion as IClassRealObject is unsafe. Consider validating the type before the assertion.

Apply this diff to add proper type validation:

- const firstParam = methodParams?.[0] as IClassRealObject;
- if (ReflectionParser._isRealClass(firstParam)) {
+ const firstParam = methodParams?.[0];
+ if (firstParam && typeof firstParam === 'object' && ReflectionParser._isRealClass(firstParam)) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const firstParam = methodParams?.[0] as IClassRealObject;
if (ReflectionParser._isRealClass(firstParam)) {
const firstParam = methodParams?.[0];
if (firstParam && typeof firstParam === 'object' && ReflectionParser._isRealClass(firstParam)) {

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (1)

78-81: ⚠️ Potential issue

Unsafe type assertion needs validation.

The type assertion as IClassRealObject is unsafe. Consider validating the type before the assertion.

Apply this diff to add proper type validation:

- const firstParam = methodParams?.[0] as IClassRealObject;
- const callbackProps = firstParam?.callbackProps;
- if (firstParam && ReflectionParser._isRealClass(firstParam) && callbackProps) {
+ const firstParam = methodParams?.[0];
+ if (firstParam && typeof firstParam === 'object' && ReflectionParser._isRealClass(firstParam)) {
+   const callbackProps = firstParam.callbackProps;
+   if (callbackProps) {
🧹 Nitpick comments (2)
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (2)

104-106: Add error handling for class loading.

The class loading logic should handle cases where the class is not found.

Apply this diff to add error handling:

 if (ReflectionParser._isRealClass(value)) {
-  return Promise.resolve(Loader.getClass(value["classReal"]));
+  const className = value["classReal"];
+  try {
+    const LoadedClass = Loader.getClass(className);
+    if (!LoadedClass) {
+      throw new Error(`Class "${className}" not found`);
+    }
+    return Promise.resolve(LoadedClass);
+  } catch (error) {
+    return Promise.reject(new Error(`Failed to load class "${className}": ${error.message}`));
+  }
 }

184-186: Strengthen type guard implementation.

The current implementation only checks for property existence. Consider adding stronger type checking.

Apply this diff to improve type safety:

 private static _isRealClass(value: any): value is IClassObject {
-  return value["classReal"] !== undefined;
+  return (
+    value !== null &&
+    typeof value === "object" &&
+    typeof value["classReal"] === "string" &&
+    value["classReal"].length > 0
+  );
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45fe351 and 8813081.

📒 Files selected for processing (1)
  • packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (3 hunks)
🔇 Additional comments (2)
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (2)

6-7: LGTM! Import statements align with new functionality.

The addition of IClassRealObject and IComponentRef types supports the new callback properties feature.


77-78: TODO comment needs clarification or removal.

The TODO comment about parsing only the first parameter needs to be either addressed or documented with a clear explanation of why this limitation exists.

Would you like me to help document this limitation or explore supporting multiple parameters?

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (1)

31-37: LGTM! Consider adding JSDoc comments.

The ICanCallbackMethodObject type definition is well-structured and provides good type safety for callback scenarios. Consider adding JSDoc comments to document the purpose and usage of this type.

+/**
+ * Represents a method object that can have callback functionality.
+ * @property params - Array of parameters for the initial method call
+ * @property callback - Optional callback configuration for method chaining
+ */
 export type ICanCallbackMethodObject = {
   params: Array<IBasicType>;
   callback?: {
     methods?: { [methodName: string]: Array<IMethodParams> };
     props?: { [key: string]: IBasicType | IMethodParams };
   };
 };
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (1)

189-191: Strengthen type guard implementation.

The current implementation only checks if params exists and is an array. Consider adding more thorough validation.

Apply this diff to strengthen the type guard:

   private static _isCanCallbackMethodObject(value: any): value is ICanCallbackMethodObject {
-    return Array.isArray(value?.params);
+    if (!value || typeof value !== 'object') return false;
+    if (!Array.isArray(value.params)) return false;
+    if (value.callback !== undefined && typeof value.callback !== 'object') return false;
+    return true;
   }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8813081 and 4397241.

📒 Files selected for processing (2)
  • packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (4 hunks)
  • packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (3 hunks)
🔇 Additional comments (4)
packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (3)

84-84: LGTM! Type restriction improves clarity.

The change from IMethodParams to Array<IBasicType> for constructParams is a good improvement. It simplifies the type definition and better reflects that constructor parameters should be basic values rather than complex callback objects.


89-91: LGTM! Clean type system extension.

The addition of IClassTypeObject and its integration into IBasicType is well-designed. It provides a clean way to reference class types directly.

Also applies to: 101-101


39-39: Verify type inference with circular reference.

The type definition creates a circular reference: IMethodParams includes ICanCallbackMethodObject which includes IMethodParams. While TypeScript can handle this, it might cause issues with type inference in complex scenarios.

✅ Verification successful

No type inference issues found with the circular reference

Based on the code analysis, while there is indeed a circular reference between IMethodParams and ICanCallbackMethodObject, it's a well-structured and valid TypeScript pattern:

  1. IMethodParams is a union type: Array<IBasicType> | ICanCallbackMethodObject
  2. ICanCallbackMethodObject uses IMethodParams only within optional nested properties (callback.methods and callback.props)
  3. The usage in ReflectionParser.ts shows proper type handling with type guards (_isCanCallbackMethodObject)

This is a common pattern in TypeScript for handling recursive structures (like ASTs or nested configurations), and TypeScript is designed to handle such cases. The circular reference is not problematic because:

  • It's properly guarded by optional properties
  • The base case (Array<IBasicType>) provides a termination point
  • The actual usage shows proper type discrimination
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for potential type inference issues
ast-grep --pattern 'IMethodParams' | grep -B2 -A2 'IMethodParams'

Length of output: 161


Script:

#!/bin/bash
# Let's check the definition and usage of ICanCallbackMethodObject
ast-grep --pattern 'interface ICanCallbackMethodObject'

# Also check where IMethodParams is used
rg 'IMethodParams' -A 3 -B 3

Length of output: 5185


Script:

#!/bin/bash
# Let's check for IBasicType definition to complete our understanding
ast-grep --pattern 'type IBasicType'

# Also check if there are any actual usages that might show type inference issues
rg -B2 -A2 '\bIMethodParams\b.*=.*ICanCallbackMethodObject'

Length of output: 576

packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (1)

93-95: LGTM! Clean implementation of class type handling.

The addition of _isClassType check and the handling of class type references is well-implemented. The order of checks is logical, checking for class types before class instances.

methods?: { [methodName: string]: Array<IMethodParams> };
props?: { [key: string]: IBasicType | IMethodParams };
};

export type IClassTypeObject = {
Copy link
Contributor

@luzhuang luzhuang Jan 3, 2025

Choose a reason for hiding this comment

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

Need discuss: merge to IClassObject use needInstance to distinguish?

@gz65555
Copy link
Collaborator

gz65555 commented Jan 3, 2025

Why not use a second parameter of addEffect instead of callback? Just like addComponent of Entity. Using callback inside the schema is really wired.

@zhuxudong zhuxudong changed the title feat: support callback props in parser feat: support parse method result Jan 6, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (8)
packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (3)

31-37: Ensure that ICanParseResultObject is well-documented.
This new interface is a crucial addition for parsing and handling callback results. Consider adding inline JSDoc comments describing the purpose of params and result for enhanced maintainability.


84-84: Consider deprecating the constructParams property in the future.
Since constructParams differs from IMethodParams, you might consider deprecating or merging them if usage converges. This can simplify code and type definitions.


89-91: Address potential overlap with IClassObject.
We have IClassTypeObject representing a “classType” and IClassObject representing a “class” string. Consider consolidating them or clarifying their differences if they serve overlapping roles.

packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (5)

5-8: Add usage context for the newly imported types.
The new imports (ICanParseResultObject, IClassTypeObject, IMethodParams) are critical to the parsing process. Adding a brief comment or docstring indicating how these types fit into the parser’s workflow may improve clarity for other contributors.


12-12: Consider renaming the import
IRefEntity might be more intuitively named for better context, e.g., IPrefabRefEntity, if that reflects its usage more accurately. Evaluate if the rename reduces confusion.


94-96: Document the purpose of _isClassType.
The _isClassType method ensures that objects with classType properties are recognized correctly. Documenting the difference from _isClass helps avoid confusion among maintainers.


174-176: Use consistent naming for _isClassType.
We have _isClass and _isClassType. While they serve different roles, consider standardizing function names for clarity, e.g., _isClassByName vs. _isClassByType.


190-192: Improve null checks in _isCanParseResultObject.
Strictly check for value?.params in a type-safe manner. The current check is fine, but you might add an explicit typeof value === "object" guard for safety.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 68bc369 and bf1733e.

📒 Files selected for processing (2)
  • packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (4 hunks)
  • packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: e2e (22.x)
  • GitHub Check: codecov
🔇 Additional comments (3)
packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (2)

39-39: Highlight the reasoning behind updating IMethodParams.
Expanding IMethodParams to accept ICanParseResultObject can introduce more flexible parsing logic. It’s recommended to add explanatory comments or usage examples to clarify when to use an array vs. the ICanParseResultObject.


101-101: Confirm the union type ordering.
In some TypeScript versions, union type resolution might behave differently when IMethodParams references itself. Ensure there’s no circular reference or type confusion by verifying that IBasicType remains consistently distinguishable.

packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (1)

76-86: ⚠️ Potential issue

Validate callable methods before instance[methodName](...).
Even though this code is presumably safe, we should confirm that instance[methodName] is indeed callable (function). Otherwise, an unhelpful runtime error might occur.

A minimal fix could be:

+ if (typeof instance[methodName] !== 'function') {
+   throw new Error(\`Method \${methodName} is not callable.\`);
+ }
const methodResult = instance[methodName](...result);

Likely invalid or redundant comment.

@@ -28,7 +28,15 @@ export interface IHierarchyFile {
entities: Array<IEntity>;
}

export type IMethodParams = Array<IBasicType>;
export type ICanParseResultObject = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's a awful name 😂

Copy link
Contributor

Choose a reason for hiding this comment

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

yes i think so

Copy link
Contributor

@luzhuang luzhuang Jan 6, 2025

Choose a reason for hiding this comment

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

How about:

type IMethodParams = Array<IBasicType> ;

type INeedAssignInstance = {
  methods?: { [methodName: string]: Array<IMethodParams> };
  props?: { [key: string]: IBasicType | IMethodParams };
}

IMethodParamsAndRes = {
   params: IMethodParams;
   result?: INeedAssignInstance
}

type IMethodInfo = IMethodParams | IMethodParamsAndRes

Copy link
Collaborator

Choose a reason for hiding this comment

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

Use markdown and pay attention to format of typescript code.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, opted after discuss

export type IMethodParams = Array<IBasicType>;
export type ICanParseResultObject = {
params: Array<IBasicType>;
result?: {
Copy link
Collaborator

Choose a reason for hiding this comment

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

The problem is the addEffect method. Using a result to invoke functions or assign properties is not appropriate. You should follow the design of addComponent, which @cptbtptpbcptdtptp can understand.

Copy link
Contributor

Choose a reason for hiding this comment

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

addComponents is handled specifically,addEffect can't follow it

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you give a specific example?

Copy link
Contributor

Choose a reason for hiding this comment

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

我说的是HierarcyParser里的parseComponent,如果你指的是引擎代码里的addComponent可以加参数的形式的话,是不满足我们这次的需求的。addComponent只能传构造参数,且不能调用方法。这次需要addEffect调用之后拿到实例再去赋值和调用方法。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
packages/loader/src/SceneLoader.ts (1)

149-149: Code style: Replace line breaks per ESLint recommendation
ESLint/prettier suggests removing unnecessary line breaks around "TextRenderer". Consider updating the formatting to match the style guidelines.

Apply this diff:

-ReflectionParser.registerCustomParseComponent(
-  "TextRenderer",
-  async (instance: any, item: Omit<IClass, "class">) => {
+ReflectionParser.registerCustomParseComponent("TextRenderer", async (instance: any, item: Omit<IClass, "class">) => {
🧰 Tools
🪛 eslint

[error] 147-149: Replace ⏎··"TextRenderer",⏎· with "TextRenderer",

(prettier/prettier)

packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (1)

82-82: Add precaution about wide usage
IInstance.methods can become complex to manage in large-scale projects. Suggest providing helper utilities or strong validations to avoid misuse or confusion.

packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (2)

48-48: Extended property parsing
parsePropsAndMethods works well for dynamic property assignment, but do confirm that unknown or private fields do not create hidden side effects, especially in advanced user components that may use private symbols.


174-176: Simple & direct
_isClassType returning true if classType exists is straightforward. Consider checking for type of classType to guard against strings that might not be actual class references.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf1733e and 3c2c29f.

📒 Files selected for processing (3)
  • packages/loader/src/SceneLoader.ts (2 hunks)
  • packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (5 hunks)
  • packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (4 hunks)
🧰 Additional context used
🪛 eslint
packages/loader/src/SceneLoader.ts

[error] 147-149: Replace ⏎··"TextRenderer",⏎· with "TextRenderer",

(prettier/prettier)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build (22.x, windows-latest)
  • GitHub Check: e2e (22.x)
  • GitHub Check: codecov
🔇 Additional comments (17)
packages/loader/src/SceneLoader.ts (1)

17-17: Use updated type references consistently
The replacement of IClassObject with IClass aligns well with the new schema definitions. Make sure that any remaining references to IClassObject are removed and that new references to IClass are consistently applied across the codebase.

packages/loader/src/resource-deserialize/resources/schema/BasicSchema.ts (10)

31-35: Clarify method structure
The new IMethod interface (with params and optional result) is clear. Ensure that any code relying on the old structure (IMethodParams as an array) properly checks for the IMethod object shape now.


36-36: Good enhancement for method flexibility
Allowing IMethodParams to be either an array of basic types or a full IMethod object increases flexibility. This is an excellent improvement as long as its usage is well documented for maintainers.


57-59: Preserve clarity in prefab modifications
The new (IInstance & { target: IPrefabModifyTarget })[] type clarifies the modifications array. Verify that all overrides or expansions of these modifications are tested to prevent runtime errors.


75-75: Accurate pairing: IComponent & IClass
Combining IClass with the component definition (id and refId) is logical. This ensures every component is recognized as a class. Looks good.


77-77: Renamed type fosters clarity
Renaming IClassObject to IClass is consistent with the design. This minor improvement aids readability and better matches the conceptual usage of “class.”


79-80: Constructor parameter type
Changing constructParams to a plain Array<IBasicType> clarifies how constructor arguments are expected. Validate usage to ensure no code still expects the older IMethodParams.


85-85: Props usage
Allowing each prop to be either a single IBasicType or an IMethodParams fosters dynamic behavior but can obscure code clarity. Encourage thorough test coverage for complex scenarios.


86-86: Ensure no regressions
Although no immediate concerns are visible, keep an eye on performance when handling deeply nested props in large scenes.


87-88: Efficient handling of IClassType
The addition of IClassType with classType is straightforward. Checking for classType to identify specialized classes is helpful.


98-99: Expanded IBasicType
Adding IClass and IClassType to IBasicType can increase complexity. Both the parser and intermediate modules should strongly validate these expanded possibilities to avoid tricky bugs.

packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts (6)

5-7: Synchronize type usage
Importing IClass, IClassType, and IComponentRef is consistent with the new definitions in BasicSchema. Confirm that any references to removed types (IClassObject) are fully purged across the project.


11-12: Seamless method integration
Importing IMethod and IMethodParams aligns with the newly introduced method-parsing approach. The code will be more flexible as a result.


40-40: Check usage with specialized class constructors
The updated parseClassObject(item: IClass) might encounter classes with atypical constructors. Ensure you handle potential runtime issues if these constructors expect unusual argument counts.


94-96: Clean class type resolution
Using _isClassType to detect classType is a clean approach. The immediate resolution using Loader.getClass ensures you handle dynamic class references gracefully.


170-170: Consistent naming
Renaming _isClass from the old _isClassObject method is consistent. This subtle improvement helps avoid confusion.


190-192: Intuitive check for method objects
_isMethodObject verifying params is an array catches typical method param usage. If more shape checks are needed in future expansions, add them here for robust type safety.

Comment on lines +76 to +86
parseMethod(instance: any, methodName: string, methodParams: IMethodParams) {
const isMethodObject = ReflectionParser._isMethodObject(methodParams);
const params = isMethodObject ? methodParams.params : methodParams;

return Promise.all(params.map((param) => this.parseBasicType(param))).then((result) => {
const methodResult = instance[methodName](...result);
if (isMethodObject && methodParams.result) {
return this.parsePropsAndMethods(methodResult, methodParams.result);
} else {
return methodResult;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Modular method handling
This block properly handles both a simple param array and the new IMethod structure. Consider factoring out the isMethodObject logic into a separate helper function for clarity and to keep parseMethod minimal.

@luzhuang luzhuang changed the title feat: support parse method result Support parse method result Jan 6, 2025
@luzhuang luzhuang self-assigned this Jan 6, 2025
@luzhuang luzhuang added the resource Resource-related functions label Jan 6, 2025
@luzhuang luzhuang added this to the 1.4 milestone Jan 6, 2025
@luzhuang luzhuang merged commit 1337ddd into galacean:dev/1.4 Jan 6, 2025
7 of 9 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jan 7, 2025
3 tasks
singlecoder pushed a commit to singlecoder/engine that referenced this pull request Jan 8, 2025
* feat: support callback props in parser
@coderabbitai coderabbitai bot mentioned this pull request Jan 8, 2025
@GuoLei1990 GuoLei1990 added the ignore for release ignore for release label Jan 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ignore for release ignore for release resource Resource-related functions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants