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

Rfc: inner class2 #3

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open

Rfc: inner class2 #3

wants to merge 44 commits into from

Conversation

withinboredom
Copy link

@withinboredom withinboredom commented Mar 23, 2025

Summary by CodeRabbit

  • New Features

    • Introduced enhanced inner class support, enabling nested class declarations with refined access and scope restrictions.
    • Delivered new reflection methods (e.g., for checking if a class is inner, private, protected, or public) to improve class introspection.
  • Bug Fixes

    • Clarified error messages for invalid class declarations and improper instantiation from the global scope.
    • Improved enforcement of visibility rules and scope requirements during class instantiation.
  • Tests

    • Added extensive tests covering inner class declarations, inheritance, access modifiers, return types, autoloading, and reflection.

Copy link

coderabbitai bot commented Mar 23, 2025

Walkthrough

This pull request implements extensive modifications to support nested (inner) class declarations in PHP within the Zend Engine. It adds new members to class entry structures for managing scope, updates object initialization to enforce scope restrictions, introduces a new AST node for inner classes, and adjusts opcode handlers and definitions for proper inner class fetching. The parser grammar now supports inner class declarations and modifiers, and ReflectionClass is extended with new methods to inspect inner class visibility. A suite of new tests validates inner classes across access modifiers, autoloading, inheritance, return types, and visibility rules.

Changes

File(s) Change Summary
Zend/tests/errmsg/errmsg_027.phpt Updated expected error message for nested class declarations test.
Zend/zend.h Added new members (required_scope, lexical_scope, required_scope_absolute) to _zend_class_entry.
Zend/zend_API.c Enhanced _object_and_properties_init with additional scope restriction checks.
Zend/zend_ast.h Introduced new enum constant ZEND_AST_INNER_CLASS.
Zend/zend_compile.c Added support for inner classes (nested declarations, deferred compilation, renaming rules).
Zend/zend_compile.h Added constants: ZEND_MODIFIER_TARGET_INNER_CLASS, ZEND_FETCH_CLASS_OUTER, and ZEND_FETCH_CLASS_NO_INNER.
Zend/zend_execute.c Introduced zend_check_class_visibility and updated property type verification to include scope checks.
Zend/zend_execute_API.c Added zend_resolve_nested_class function for resolving nested class names.
Zend/zend_language_parser.y Updated grammar rules and types to support inner classes (new types and modifiers).
Zend/zend_object_handlers.c Added lexical scope checks in property and method access functions.
Zend/zend_opcode.c Added cleanup for the required_scope attribute in destroy_zend_class.
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_handlers.h
Zend/zend_vm_opcodes.c
Zend/zend_vm_opcodes.h
Introduced new opcode ZEND_FETCH_INNER_CLASS with corresponding handlers; reorganized opcode definitions and updated opcode arrays.
ext/opcache/zend_persist.c Added zend_update_required_scope to update class scope properties during persistence.
ext/reflection/php_reflection.c
ext/reflection/php_reflection.stub.php
ext/reflection/php_reflection_arginfo.h
ext/reflection/tests/ReflectionClass_toString_001.phpt
Added new ReflectionClass methods (isInnerClass, isPrivate, isProtected, isPublic).
ext/reflection/tests/bug74454.phpt Updated expected ParseError message to indicate "expecting 'class'" instead of "function".
tests/classes/inner_classes/* Added multiple new tests covering inner class declarations, access modifiers, autoloading, enum usage, error conditions, inheritance, return types, static variables, trait usage, and visibility rules.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant ObjInit as _object_and_properties_init
    participant ExecScope as zend_get_executed_scope
    participant Error as ErrorHandler

    Caller->>ObjInit: Instantiate class object
    ObjInit->>ExecScope: Retrieve current execution scope
    ExecScope-->>ObjInit: Return current scope
    alt Class has required_scope set
        ObjInit->>ObjInit: Check if current scope matches required/lexical scope
        alt Mismatch
            ObjInit->>Error: Raise instantiation error (private/protected violation)
        else Match
            ObjInit->>Caller: Complete instantiation
        end
    else
        ObjInit->>Caller: Complete instantiation
    end
Loading
sequenceDiagram
    participant Caller
    participant Lookup as zend_lookup_class_ex
    participant Resolver as zend_resolve_nested_class
    participant Outer as OuterClass

    Caller->>Lookup: Lookup nested class by name
    Lookup->>Resolver: Invoke nested class resolution
    Resolver->>Outer: Iterate through outer class scopes
    Outer-->>Resolver: Return matching class entry (or not found)
    Resolver-->>Lookup: Provide resolved class entry
    Lookup-->>Caller: Return resolved class or trigger error
Loading

Poem

I hop through scopes with nimble grace,
Discovering classes in a nested embrace.
New paths emerge, refined and clear,
With strict checks that guard what’s dear.
As a rabbit, I celebrate this innovative race,
Bouncing with joy in this inner class space! 🐇

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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

@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: 9

🧹 Nitpick comments (22)
tests/classes/inner_classes/autoload_001.phpt (1)

12-13: Verify inner class autoloading mechanism.

The test creates an instance of inner_classes\Point, but it's not clear whether this is demonstrating an inner class or just a namespaced class. Additional context or comments would help clarify the purpose of this test.

Consider adding a comment explaining how this test relates to inner class functionality, such as:

+ // This test verifies that autoloading works with inner classes
+ // which are accessed using namespace-like syntax
$point = new inner_classes\Point(1, 2);
tests/classes/inner_classes/readonly_001.phpt (2)

7-7: Consider separating readonly class modifier from property test

The test combines two different concepts: a readonly inner class and a readonly property. This makes it unclear which aspect is actually being tested.

Consider separating these concerns into two different tests, or renaming the test to clarify that you're testing readonly properties within inner classes rather than readonly class modifiers.

-    public readonly class Inner { public function __construct(public int $t) {} }
+    public class Inner { public function __construct(public readonly int $t) {} }

1-23: Test needs more precise description

The test description "readonly should work" is vague and doesn't specify whether it's testing readonly classes or readonly properties.

Consider updating the description to be more specific:

---TEST--
-readonly should work
+readonly properties in inner classes should work
---FILE--
tests/classes/inner_classes/visibility_006.phpt (1)

1-28: Improve test clarity with a better description

The test description "scope doesn't bypass scope" is unclear about the specific visibility rule being tested.

Consider updating the test description to be more specific about the visibility rules being tested:

---TEST--
-scope doesn't bypass scope
+inner class cannot access private methods of outer classes
---FILE--
Zend/zend_vm_def.h (2)

1801-1901: Validate null checks for lexical_scope and improve test coverage.

The new ZEND_FETCH_INNER_CLASS handler thoroughly covers outer-class references, private/protected checks, and scope checks. However, consider verifying whether scope->lexical_scope might be NULL (e.g., lines 1877–1894) to prevent potential null-pointer dereferences. It is best practice in the Zend Engine to consistently handle null checks for optional members like lexical_scope. In addition, ensure that you have robust test coverage to exercise all branches (e.g., calls with no parent, calls to private inner classes via self, etc.).

Below is an optional diff snippet illustrating how you could guard against a null lexical scope:

     } else {
       // for protected classes, we check if the scope is an instance of the required scope
-      if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) 
-            || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) {
+      if (scope != NULL 
+        && scope->lexical_scope != NULL
+        && (instanceof_function(scope, inner_ce->required_scope) 
+            || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) {
         // we are in the correct scope
       } else {
         zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name));
         HANDLE_EXCEPTION();
       }
     }

Would you like a script to identify any missing null-check scenarios and confirm no further references to scope->lexical_scope without null checks?


4532-4548: Extend testing for restricted-return scenarios.

The checks disallow returning private/protected classes from public/protected methods, aligning with the intended visibility rules. For completeness, consider adding thorough tests to confirm that:

  1. Private methods can return private classes without error.
  2. Protected methods can return protected classes in an allowed scope.

If these edge cases are untested or partially tested, expanding coverage avoids regressions and ensures consistent enforcement of scope rules.

Do you want help creating additional test cases to confirm correct handling of all private/protected/public return class scenarios?

tests/classes/inner_classes/return_types_003.phpt (1)

1-34: The test looks good but may benefit from additional assertions.

This test correctly verifies that a public method cannot return a protected inner class type. The expected output correctly asserts the TypeError when trying to violate visibility rules, which is an important constraint for inner classes.

Consider enhancing this test with additional cases:

  1. A test where both child and parent methods have matching visibility
  2. A test where the child method has more restrictive visibility (protected → private)

These would provide more comprehensive coverage of return type visibility rules for inner classes.

Zend/zend_compile.c (2)

1810-1840: Nested class name resolution.

zend_resolve_nested_class_name() recursively handles deeper nesting and appends ":>" between outer and inner names. Ensure that using multiple delimiters (":>", '|', "\\\\") in different parts of the code remains intentional and well-documented.


9169-9186: Deferred class declaration queue.

Introducing a global inner_class_queue for deferred compilation is workable, but be aware of re-entrancy or concurrency if the engine ever supports parallel compilation. The current approach looks correct for single-thread usage.

Zend/zend_object_handlers.c (5)

384-409: Repeated lexical scope fallback using labels and goto.
These lines introduce the check_lexical_scope label and re-check the scope->lexical_scope. While it aligns with the engine’s approach, consider whether repeated “goto check_lexical_scope;” could be refactored into a loop or helper function to reduce duplication and guard against potential cyclical lexical_scope references.

Could you confirm that no cyclical references exist in lexical_scope that might cause an infinite loop?


1823-1825: Lexical scope fallback for method accessibility checks.
Similar pattern of using a goto label to retry with scope->lexical_scope. The logic is consistent with the rest of the patch. Ensure that repeated usage of this pattern does not create hidden recursion or conflict in edge cases.

Also applies to: 1842-1845


1905-1906: Lexical scope fallback for static method checks.
Again, the new label-based approach is used. No immediate issues, but consider consolidating this repeated chunk of code into a shared helper to keep things DRY.

Also applies to: 1913-1914


1995-1995: Extended check_lexical_scope usage in static property access.
This block retries access checks by walking scope->lexical_scope. The approach is consistent. A single utility method might reduce duplication and maintain clarity.

Also applies to: 1999-2002


2083-2092: Lexical scope fallback added to constructor call checks.
The same pattern. Overall, the fallback logic appears correct, though factoring this repetition out into a well-documented helper could enhance maintainability.

tests/classes/inner_classes/visibility_003.phpt (1)

1-3: Test description doesn't match implementation.

The test description mentions "accessing outer protected vars" but the implementation actually tests accessing private variables.

---TEST--
-accessing outer protected vars
+accessing outer private vars
tests/classes/inner_classes/simple_declaration_004.phpt (1)

27-31: Consider removing the duplicated call to Outer2::testSelf()

Lines 29 and 30 contain identical calls to Outer2::testSelf(). This appears to be redundant and doesn't provide additional test coverage.

var_dump(Outer::testSelf());
var_dump(Outer2::testParent());
var_dump(Outer2::testSelf());
-var_dump(Outer2::testSelf());
Zend/zend_execute_API.c (1)

1299-1306: Nested class resolution integration looks good.

Your addition correctly checks if ZEND_FETCH_CLASS_NO_INNER is unset, then attempts a nested class lookup. This flow complements the normal lookup procedure.

Consider adding a short explanatory note in the docblock or commit message clarifying how “no inner” modifies class resolution, so future maintainers understand these branches.

Zend/zend_vm_execute.h (2)

68212-68212: Magic number introduced in spec table.
Line 68212 adds a raw value 3491. Consider using a symbolic constant or macro for clarity and maintainability if feasible.


68595-68611: New spec rule constants.
Values like 2590, 2615, 2640 are introduced here. Replacing these bare integers with named constants can improve maintainability and understanding.

Zend/zend_vm_handlers.h (3)

1389-1396: Assess overflow checks for long addition
These ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_* opcodes appear to handle addition where no overflow is expected. It would be beneficial to reconfirm edge-case handling for large integer operations, especially on platforms with differing integer sizes.


1413-1420: Add double specialization checks
By introducing ZEND_ADD_DOUBLE_SPEC_TMPVARCV_* opcodes, floating-point addition optimizations are expanded. Ensure that existing test coverage includes both small and large magnitudes to detect potential precision issues.


1428-1431: Extend safe subtraction logic to tmpvar references
These _NO_OVERFLOW_ variants must also consider negative intermediate results to prevent underflow or unexpected behavior. Testing with both positive and negative operands is recommended.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 076811a and 17fa07c.

📒 Files selected for processing (61)
  • Zend/tests/errmsg/errmsg_027.phpt (1 hunks)
  • Zend/zend.h (1 hunks)
  • Zend/zend_API.c (1 hunks)
  • Zend/zend_ast.h (1 hunks)
  • Zend/zend_compile.c (20 hunks)
  • Zend/zend_compile.h (2 hunks)
  • Zend/zend_execute.c (2 hunks)
  • Zend/zend_execute_API.c (2 hunks)
  • Zend/zend_language_parser.y (6 hunks)
  • Zend/zend_object_handlers.c (7 hunks)
  • Zend/zend_opcode.c (1 hunks)
  • Zend/zend_vm_def.h (3 hunks)
  • Zend/zend_vm_execute.h (24 hunks)
  • Zend/zend_vm_handlers.h (1 hunks)
  • Zend/zend_vm_opcodes.c (3 hunks)
  • Zend/zend_vm_opcodes.h (1 hunks)
  • ext/opcache/zend_persist.c (2 hunks)
  • ext/reflection/php_reflection.c (1 hunks)
  • ext/reflection/php_reflection.stub.php (1 hunks)
  • ext/reflection/php_reflection_arginfo.h (4 hunks)
  • ext/reflection/tests/ReflectionClass_toString_001.phpt (2 hunks)
  • ext/reflection/tests/bug74454.phpt (1 hunks)
  • tests/classes/inner_classes/access_modifiers_001.phpt (1 hunks)
  • tests/classes/inner_classes/access_modifiers_002.phpt (1 hunks)
  • tests/classes/inner_classes/access_modifiers_003.phpt (1 hunks)
  • tests/classes/inner_classes/access_modifiers_004.phpt (1 hunks)
  • tests/classes/inner_classes/access_modifiers_005.phpt (1 hunks)
  • tests/classes/inner_classes/access_modifiers_006.phpt (1 hunks)
  • tests/classes/inner_classes/access_modifiers_007.phpt (1 hunks)
  • tests/classes/inner_classes/autoload_001.phpt (1 hunks)
  • tests/classes/inner_classes/autoload_002.phpt (1 hunks)
  • tests/classes/inner_classes/enum_usage.phpt (1 hunks)
  • tests/classes/inner_classes/errors_001.phpt (1 hunks)
  • tests/classes/inner_classes/errors_002.phpt (1 hunks)
  • tests/classes/inner_classes/inheritance.phpt (1 hunks)
  • tests/classes/inner_classes/inner_classes.inc (1 hunks)
  • tests/classes/inner_classes/interface_usage.phpt (1 hunks)
  • tests/classes/inner_classes/readonly_001.phpt (1 hunks)
  • tests/classes/inner_classes/reflection_001.phpt (1 hunks)
  • tests/classes/inner_classes/return_types_001.phpt (1 hunks)
  • tests/classes/inner_classes/return_types_002.phpt (1 hunks)
  • tests/classes/inner_classes/return_types_003.phpt (1 hunks)
  • tests/classes/inner_classes/return_types_004.phpt (1 hunks)
  • tests/classes/inner_classes/return_types_005.phpt (1 hunks)
  • tests/classes/inner_classes/return_types_006.phpt (1 hunks)
  • tests/classes/inner_classes/simple_declaration_001.phpt (1 hunks)
  • tests/classes/inner_classes/simple_declaration_002.phpt (1 hunks)
  • tests/classes/inner_classes/simple_declaration_003.phpt (1 hunks)
  • tests/classes/inner_classes/simple_declaration_004.phpt (1 hunks)
  • tests/classes/inner_classes/static_variables.phpt (1 hunks)
  • tests/classes/inner_classes/trait_usage.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_001.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_002.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_003.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_004.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_005.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_006.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_007.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_008.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_009.phpt (1 hunks)
  • tests/classes/inner_classes/visibility_010.phpt (1 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
Zend/zend_vm_execute.h (1)
Zend/zend_vm_def.h (18)
  • SAVE_OPLINE (30-30)
  • SAVE_OPLINE (89-89)
  • SAVE_OPLINE (148-148)
  • SAVE_OPLINE (224-224)
  • SAVE_OPLINE (234-234)
  • SAVE_OPLINE (282-282)
  • SAVE_OPLINE (324-324)
  • SAVE_OPLINE (500-500)
  • SAVE_OPLINE (580-580)
  • SAVE_OPLINE (660-660)
  • SAVE_OPLINE (725-725)
  • SAVE_OPLINE (807-807)
  • SAVE_OPLINE (846-846)
  • SAVE_OPLINE (885-885)
  • SAVE_OPLINE (938-938)
  • SAVE_OPLINE (991-991)
  • ZEND_VM_NEXT_OPCODE (8149-8149)
  • ZEND_VM_NEXT_OPCODE (8156-8156)
ext/reflection/php_reflection.c (1)
ext/reflection/php_reflection.stub.php (14)
  • ReflectionClass (233-443)
  • isInnerClass (436-436)
  • isPrivate (191-191)
  • isPrivate (438-438)
  • isPrivate (516-516)
  • isPrivate (612-612)
  • isProtected (194-194)
  • isProtected (440-440)
  • isProtected (519-519)
  • isProtected (615-615)
  • isPublic (188-188)
  • isPublic (442-442)
  • isPublic (513-513)
  • isPublic (609-609)
Zend/zend_execute.c (5)
Zend/zend_compile.c (8)
  • bool (308-322)
  • bool (526-529)
  • bool (2062-2072)
  • bool (2075-2086)
  • bool (2449-2474)
  • bool (9900-9920)
  • bool (9922-9984)
  • bool (9999-10010)
Zend/zend_object_handlers.c (3)
  • bool (259-270)
  • bool (971-976)
  • bool (1591-1615)
Zend/zend_ast.h (2)
  • bool (351-353)
  • bool (355-357)
Zend/zend_object_handlers.h (2)
  • ce (249-249)
  • ce (313-313)
Zend/zend_execute.h (1)
  • zend_verify_property_type_error (528-528)
Zend/zend_vm_def.h (1)
Zend/zend_vm_execute.h (18)
  • SAVE_OPLINE (451-451)
  • SAVE_OPLINE (472-472)
  • SAVE_OPLINE (493-493)
  • SAVE_OPLINE (514-514)
  • SAVE_OPLINE (524-524)
  • SAVE_OPLINE (545-545)
  • SAVE_OPLINE (566-566)
  • SAVE_OPLINE (588-588)
  • SAVE_OPLINE (610-610)
  • SAVE_OPLINE (632-632)
  • SAVE_OPLINE (654-654)
  • SAVE_OPLINE (675-675)
  • SAVE_OPLINE (696-696)
  • SAVE_OPLINE (717-717)
  • SAVE_OPLINE (738-738)
  • SAVE_OPLINE (751-751)
  • ZEND_VM_NEXT_OPCODE (3166-3166)
  • ZEND_VM_NEXT_OPCODE (3173-3173)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: WINDOWS_X64_ZTS
  • GitHub Check: MACOS_ARM64_DEBUG_NTS
  • GitHub Check: LINUX_X64_DEBUG_ZTS_ASAN
  • GitHub Check: LINUX_X64_RELEASE_NTS
🔇 Additional comments (140)
tests/classes/inner_classes/errors_001.phpt (1)

1-12: LGTM: Well-structured test for inner class instantiation error

This test correctly verifies that attempting to instantiate an inner class without its outer class being defined triggers the appropriate fatal error. The test follows the standard PHPT format with clear sections for test description, code, and expected output.

tests/classes/inner_classes/access_modifiers_003.phpt (1)

1-13: LGTM: Valid test for static modifier restriction on inner classes

This test properly verifies that the static modifier cannot be used on inner classes. The test is well-structured with appropriate sections and correctly expects a fatal error when attempting to define a static inner class.

tests/classes/inner_classes/access_modifiers_005.phpt (1)

1-13: LGTM: Valid test for protected(set) modifier restriction on inner classes

This test correctly verifies that the protected(set) modifier cannot be applied to inner classes. The test structure is clean and follows the standard PHPT format with appropriate test description, code, and expected fatal error output.

tests/classes/inner_classes/simple_declaration_002.phpt (1)

1-13: LGTM: Proper test for class declaration inside function restriction

This test correctly verifies that inner classes follow the same rules as regular classes regarding declarations inside functions. The test structure is clean and follows the standard PHPT format with appropriate test description, code, and expected fatal error output.

tests/classes/inner_classes/errors_002.phpt (1)

1-15: Well-structured test for inner class not found scenario.

This test correctly verifies that attempting to instantiate a non-existent inner class triggers a "Class not found" fatal error. The test structure properly defines an outer class without any inner classes and then attempts to access a non-existent inner class, verifying the appropriate error message and stack trace.

Zend/tests/errmsg/errmsg_027.phpt (1)

16-16: Improved error message clarity.

The updated error message more accurately reflects that the restriction is specifically about declaring classes inside functions, not just any kind of nesting. This change aligns with the implementation of inner classes - classes can now be nested within other classes, but they still cannot be declared inside functions.

tests/classes/inner_classes/access_modifiers_004.phpt (1)

1-14: Correct test for invalid access modifier on inner class.

This test properly verifies that using the public(set) access modifier on an inner class results in a fatal error. Since this modifier is intended for properties and methods with specific getter/setter semantics, it's appropriate to disallow it for inner classes and validate this restriction.

tests/classes/inner_classes/access_modifiers_006.phpt (1)

1-14: Proper validation of invalid access modifier.

This test correctly verifies that the private(set) access modifier cannot be used on inner classes, which is consistent with the test for public(set). The test structure and expected output format are correct, ensuring that the PHP engine properly rejects this invalid modifier when applied to an inner class.

ext/reflection/tests/bug74454.phpt (1)

17-17: Updated error message aligns with inner class implementation.

The error message change from "expecting 'function'" to "expecting 'class'" reflects the updated parser expectations when encountering incorrect syntax, which is consistent with the inner class implementation.

tests/classes/inner_classes/return_types_001.phpt (2)

6-12: Well-structured test for inner class return types.

This test correctly validates that an inner class can be used as a return type within its own definition, demonstrating proper type resolution for inner classes.


14-14: Correct namespace reference for static inner class method.

The test properly accesses the inner class method using the namespace-like syntax Outer\Inner::test(), which is the expected way to reference static inner class methods.

tests/classes/inner_classes/access_modifiers_002.phpt (2)

6-9: Good test for invalid inner class syntax.

This test correctly validates that the parser rejects invalid syntax when declaring inner classes. The use of the int keyword before class is properly identified as a syntax error.


13-13: Error message correctly indicates syntax error expectation.

The expected output correctly specifies that the parser is expecting the "class" keyword, aligning with the inner class grammar implementation.

Zend/zend_ast.h (1)

136-136: LGTM: Appropriate addition of ZEND_AST_INNER_CLASS enum constant.

The new AST node type ZEND_AST_INNER_CLASS is correctly positioned in the "2 child nodes" section of the enum, indicating inner class declarations will use a 2-child AST node structure. This addition aligns with the pull request's objective of implementing support for nested class declarations.

tests/classes/inner_classes/access_modifiers_001.phpt (1)

1-14: LGTM: Good test case for multiple access modifiers.

This test correctly verifies that the PHP engine properly rejects inner classes with multiple access modifiers. The error message format in the EXPECTF section matches PHP's standard error formatting for this type of syntax error.

tests/classes/inner_classes/autoload_002.phpt (1)

1-17: LGTM: Comprehensive test for private inner class autoloading.

This test effectively verifies two important behaviors:

  1. The autoloading mechanism works with inner classes
  2. Private inner classes cannot be instantiated from the global scope

The test structure follows standard PHPT conventions with appropriate setup and expected output verification.

tests/classes/inner_classes/enum_usage.phpt (1)

1-17: LGTM: Good test for inner classes within enums.

This test correctly validates that inner classes can be defined within enums and accessed using the namespaced syntax. Both object instantiation and class existence checks are properly tested.

tests/classes/inner_classes/trait_usage.phpt (5)

6-8: Clean implementation of inner class within a trait.

The declaration of an inner class within a trait is correctly implemented. This test validates that inner classes can be defined within traits, which is a good extension of the inner class functionality.


10-10: Correct instantiation of inner class using namespace syntax.

The test properly instantiates the inner class using the namespace syntax Outer\Inner, which is intuitive and consistent with PHP's namespace handling.


12-14: Appropriate trait usage implementation.

The test correctly uses the trait within a class to verify how inner classes are scoped.


16-17: Good verification of class existence and scoping.

These assertions validate two important aspects:

  1. The inner class from the trait exists in the trait's namespace
  2. The inner class is NOT available in the namespace of a class using the trait

This confirms that inner classes are bound to their declaring scope rather than being imported through trait usage.


20-24: Expected output correctly represents the intended behavior.

The expected output correctly shows:

  1. An instance of Outer\Inner can be created
  2. Outer\Inner class exists
  3. Foo\Inner class does not exist

This establishes the proper scoping behavior for inner classes in traits.

tests/classes/inner_classes/simple_declaration_001.phpt (3)

6-10: Well-structured nested class implementation.

This test correctly implements a three-level nested class hierarchy (Outer → Middle → Inner), which properly tests the ability to have multiple levels of nesting in class declarations.


12-15: Comprehensive class existence checking.

The test thoroughly verifies class existence using both string-based class references and the ::class constant syntax. This ensures compatibility with both styles of class referencing commonly used in PHP.


18-21: Expected output confirms proper class resolution.

The expected output correctly confirms that all classes are accessible through their fully qualified names, validating that the inner class implementation properly handles class resolution at multiple nesting levels.

tests/classes/inner_classes/inner_classes.inc (2)

4-6: Good implementation of public inner class with constructor and properties.

The Point inner class demonstrates:

  1. Access modifier (public)
  2. Constructor with property promotion (a PHP 8.0+ feature)
  3. Type declarations for properties

This shows that inner classes properly support modern PHP features.


8-8: Private inner class declaration demonstrates visibility control.

The Line class demonstrates that inner classes can have different visibility modifiers, which is important for encapsulation and information hiding in OOP.

Zend/zend_opcode.c (1)

433-435: Added proper cleanup for required_scope in class destruction.

This change ensures that the required_scope reference is properly cleared during class destruction, preventing potential memory leaks or dangling references when destroying classes with inner classes.

The added code handles the cleanup of the new required_scope property, which is likely used to enforce scope restrictions for inner classes, ensuring that resources are properly released.

tests/classes/inner_classes/simple_declaration_003.phpt (1)

1-20: LGTM: Test case properly verifies basic nested class functionality

The test correctly validates the basic structure and behavior of nested classes with:

  1. An outer class
  2. A middle class inside the outer class
  3. An inner class inside the middle class

The test verifies that the fully qualified class name is correctly generated as Foo\Outer\Middle\Inner and that the inner class can be instantiated using the expected namespace path notation.

tests/classes/inner_classes/visibility_001.phpt (1)

1-25: LGTM: Test properly validates visibility restrictions for inner classes

This test correctly verifies that a private inner class cannot be assigned to a property with higher visibility. The expected fatal error is appropriate because assigning a private inner class to a public property would violate encapsulation rules.

The test also thoroughly verifies the error message includes the proper type information and demonstrates that the visibility checks are enforced at runtime when assignment occurs.

tests/classes/inner_classes/visibility_006.phpt (1)

15-17: Verify the intended test behavior

This test appears to be checking that an inner class cannot access private methods from its outer containing classes, but the test name "scope doesn't bypass scope" is somewhat ambiguous.

The inner class method testit() tries to call $this->test(), but there is no test() method defined in the Inner class - the private test methods are defined in Outer and Middle classes. The error is correctly thrown, but it would be clearer if the test made an explicit attempt to call the parent class's private method.

Consider either:

  1. Making it clear that you're testing method visibility by trying to explicitly call the parent's private method, or
  2. Adding a clearer comment explaining what's being tested
public function testit() {
-    $this->test();
+    // Explicitly try to call parent class's private method
+    $this->test(); // Should fail - can't access private method from parent
}
Zend/zend_vm_opcodes.h (1)

294-296: Good addition of opcode for inner class functionality

The new opcode ZEND_FETCH_INNER_CLASS is correctly defined with value 210, and the ZEND_VM_LAST_OPCODE value is properly updated to reflect this addition. This is necessary for supporting the inner class functionality being implemented in this PR.

tests/classes/inner_classes/inheritance.phpt (1)

1-13: Test class structure looks good, but the test case is incomplete

The inheritance relationships between the classes are defined correctly, demonstrating:

  1. An abstract Other class inside Outer
  2. Middle extending Other
  3. Inner classes with different inheritance patterns (Inner1 extends Other, Inner2 extends Middle)

However, this test file doesn't actually verify any behavior - it lacks code that exercises these classes and assertions to verify correct functionality.

Consider adding code that:

  • Instantiates these classes
  • Tests inheritance relationships using instanceof
  • Verifies expected behavior of inner class inheritance
  • Updates the --EXPECT-- section with the expected output
Zend/zend_vm_def.h (1)

8296-8297: Additions for ZEND_FETCH_INNER_CLASS appear consistent.

Defining the ZEND_FETCH_INNER_CLASS case here to return a zend_class_entry pointer aligns well with the newly introduced opcode. This addition maintains consistency with other opcodes that retrieve a class entry.

tests/classes/inner_classes/reflection_001.phpt (1)

1-32: LGTM! Test case validates inner class reflection capabilities correctly.

This test effectively validates the reflection capabilities on nested classes through multiple levels (Outer -> Middle -> Inner). It properly tests:

  • Full class name resolution with namespaces
  • Short name extraction
  • Inner class detection
  • Visibility modifier inspection

The expected output matches what we would expect from the implementation. This test will help ensure that reflection properly works with the new inner class feature.

Zend/zend.h (1)

167-170: Core struct modification for inner class scope management.

The addition of these three fields to the _zend_class_entry struct provides the necessary infrastructure to track scope information for inner classes:

  1. required_scope - Identifies the containing class scope
  2. lexical_scope - Tracks the lexical context where the class was defined
  3. required_scope_absolute - Flag to indicate absolute/relative scope resolution

This change is minimal and focused, only adding what's necessary to implement inner class functionality.

tests/classes/inner_classes/interface_usage.phpt (2)

6-8: Interface with inner class definition looks good.

The implementation allows defining inner classes within interfaces, which is a logical extension of the inner class concept.


10-15: Correctly tests inner class instantiation and class_exists behavior.

This test validates two important behaviors:

  1. Inner classes in interfaces can be instantiated directly using namespace-like syntax
  2. Classes implementing an interface don't automatically inherit inner classes from the interface

This effectively tests the boundary between inheritance and inner class scope resolution.

tests/classes/inner_classes/visibility_008.phpt (2)

6-15: Outer class with protected method and inner class.

This test case correctly defines a class hierarchy with protected members to test visibility rules. The Middle inner class is appropriately marked as protected, and its static method is made public for accessibility.


17-26: Tests inheritance and sibling class access correctly.

This segment effectively tests that:

  1. Inner classes can access static methods from sibling inner classes in parent contexts
  2. Inner classes can access protected methods from their outer class's parent

This is important for validating the scope resolution and visibility rules for inner classes.

Zend/zend_vm_opcodes.c (2)

25-237: Added opcode for inner class support.

The array size has been increased from 210 to 211 elements to accommodate the new "ZEND_FETCH_INNER_CLASS" opcode, ensuring proper support for inner classes in the Zend Engine.


239-451: Opcode flags array properly updated.

The flags array has been expanded to match the opcodes array size, with the new flag value 0x00040307 added for the ZEND_FETCH_INNER_CLASS opcode. This value appears to define the expected operand types and behavior of the opcode.

tests/classes/inner_classes/return_types_005.phpt (1)

1-27: Good test for protected return type visibility validation.

This test correctly verifies that a public method cannot return a protected inner class type. The test structure is clear and effectively demonstrates the visibility enforcement for inner classes in return types.

tests/classes/inner_classes/access_modifiers_007.phpt (1)

1-28: Good test for abstract inner class behavior.

This test adequately verifies multiple aspects of abstract inner classes:

  1. That they can be extended
  2. That they correctly report as abstract via Reflection
  3. That they cannot be instantiated directly

The test structure is concise and effectively covers the expected behavior.

tests/classes/inner_classes/visibility_009.phpt (1)

1-39: Good test for deeply nested class visibility.

This test effectively verifies that inner classes have access to private members of their containing classes, demonstrating proper scope handling in deeply nested class structures. The test covers both static and instance properties with appropriate visibility checks.

tests/classes/inner_classes/return_types_006.phpt (1)

1-22: Test correctly verifies inner class return type behavior.

This test appropriately validates that a private inner class can be instantiated and returned from within its own method and from the outer class's method. The expected output correctly shows an instance of Outer\PrivateInner being returned, demonstrating that visibility restrictions are properly enforced within their scope.

ext/opcache/zend_persist.c (2)

1124-1143: Implementation for updating class scope references during persistence.

The zend_update_required_scope function correctly handles translation of required_scope and lexical_scope pointers when persisting class definitions in OpCache. This is essential for maintaining proper inner class relationships during serialization/deserialization.


1318-1318: Added call to update inner class scope information.

Good addition of the call to zend_update_required_scope(ce) after updating the parent class entry in the zend_accel_persist_class_table function. This ensures that inner class scope relationships are properly maintained when classes are persisted in OpCache.

tests/classes/inner_classes/return_types_004.phpt (1)

1-27: Test correctly verifies visibility enforcement for return types.

This test properly validates that a public method cannot return a private inner class type. The error message correctly identifies the visibility conflict between the public method and its private return type.

tests/classes/inner_classes/visibility_004.phpt (1)

1-26: Test correctly verifies visibility enforcement for property types.

This test appropriately validates that a protected inner class cannot be assigned to a property with higher visibility (public). The error message correctly indicates the visibility mismatch between the protected class and the public property.

Zend/zend_compile.h (3)

897-897: Good addition to the modifier target enum.

Adding ZEND_MODIFIER_TARGET_INNER_CLASS to the existing enum follows the established pattern for other class components, making it consistent with the codebase.


1024-1024: Appropriate class fetch constant for outer classes.

The ZEND_FETCH_CLASS_OUTER constant follows the existing patterns for class fetch types (like SELF, PARENT, STATIC) and is placed at a logical position in the enum.


1031-1031: Good addition of the NO_INNER flag to control inner class fetching.

The ZEND_FETCH_CLASS_NO_INNER flag uses a bitwise flag pattern consistent with other fetch modifiers like ZEND_FETCH_CLASS_NO_AUTOLOAD.

ext/reflection/php_reflection.stub.php (1)

436-442:

❓ Verification inconclusive

Good additions to ReflectionClass for inner class support.

These four methods complete the reflection capabilities for inner classes:

  • isInnerClass() - Detects inner class status
  • isPrivate(), isProtected(), isPublic() - Check visibility modifiers for classes

The methods follow the same pattern as other boolean inspection methods in ReflectionClass, providing a consistent API.

Verify that these methods are properly implemented in the underlying C code:


🏁 Script executed:

#!/bin/bash
# Check the implementation of the new ReflectionClass methods
rg -A 10 "PHP_METHOD\(ReflectionClass, is(InnerClass|Private|Protected|Public)\)" ext/reflection/

Length of output: 99


Manual verification required: Confirm underlying C implementations for ReflectionClass methods

The updated stub file in ext/reflection/php_reflection.stub.php looks good, and the new methods (i.e. isInnerClass(), isPrivate(), isProtected(), and isPublic()) properly extend the Reflection API at the interface level. However, our automated search using

rg -A 10 "PHP_METHOD\(ReflectionClass, is(InnerClass|Private|Protected|Public)\)" ext/reflection/

did not return any output. This lack of evidence means we couldn’t automatically confirm that these methods are implemented in the underlying C code.

Action items:

  • Please manually verify that the corresponding implementations (using constructs like PHP_METHOD(ReflectionClass, isInnerClass), etc.) exist in the C source files under ext/reflection/.
  • If the implementations are missing or incomplete, ensure they’re added consistent with the pattern used for other boolean inspection methods in ReflectionClass.
ext/reflection/php_reflection.c (4)

4078-4091: Correctly implemented method for checking inner class status.

This method checks whether a class is an inner class by verifying if it has a lexical scope. The implementation is straightforward and follows the same pattern as other reflection methods.


4093-4103: Well-implemented private visibility check for classes.

This method correctly determines if a class is private by checking for both a required scope and that the scope is absolute. The implementation is clean and consistent with the overall codebase style.


4105-4114: Properly implemented protected visibility check for classes.

This method correctly identifies a protected class by verifying it has a required scope that is not absolute. The implementation follows the same pattern as the other visibility methods.


4116-4124: Public visibility check implemented correctly.

This method properly determines if a class is public by checking that it doesn't have a required scope. The implementation is simple and effective, consistent with the other visibility check methods.

ext/reflection/tests/ReflectionClass_toString_001.phpt (2)

33-33: Method count updated correctly for the ReflectionClass class.

The total count of methods has been updated from 64 to 68, reflecting the addition of four new methods for inner class support.


517-544: Four new methods added for inner class functionality.

These new methods enhance ReflectionClass to properly support inner classes in PHP:

  • isInnerClass(): Determines if the reflected class is an inner class
  • isPrivate(), isProtected(), isPublic(): Check the visibility modifiers of the class

All methods follow the consistent pattern of existing ReflectionClass methods with proper parameter and return type documentation.

ext/reflection/php_reflection_arginfo.h (4)

2-2: Stub hash correctly updated.

The stub hash has been updated to reflect the changes in the generated file.


369-375: Argument information for new ReflectionClass methods.

Added argument information typedefs for the four new methods that will expose inner class information. All methods are defined to return boolean values, consistent with other similar ReflectionClass methods.


858-861: Method declarations added for inner class functionality.

Properly declared the four new method implementations for ReflectionClass that will expose inner class functionality:

  • isInnerClass(): To check if class is an inner class
  • isPrivate(), isProtected(), isPublic(): To check class visibility modifiers

1154-1157: Method entries added to ReflectionClass function table.

The method entries are correctly added to the ReflectionClass function table with the proper argument information and access modifiers. All methods are correctly marked as public.

Zend/zend_compile.c (16)

896-910: Ensure consistency with other disallowed modifiers for inner classes.

You're allowing T_READONLY, T_ABSTRACT, and T_FINAL for ZEND_MODIFIER_TARGET_INNER_CLASS. This is fine if read-only, abstract, and final classes are indeed valid design choices for inner classes. However, confirm that the new flags and error checks later in the file (for static, public(set), etc.) do not inadvertently conflict with read-only, abstract, or final usage.


947-948: Defines the correct error string for the new target.

This addition of "inner class" to the member string is consistent with other targets (e.g., property hook). No concerns.


1056-1086: Validation rules for inner classes look correct.

These checks ensure that static, multiple access modifiers, and special “set” qualifiers are disallowed for inner classes. This is logically consistent and should prevent invalid constructs.


1248-1250: Prefixed naming approach is coherent.

If an active class entry exists, prefixing the name with the outer class via zend_prefix_with_outer_class() fits the design of nested references.


1879-1883: Constant expression resolution for inner classes.

Storing the nested class name in a zval with ZVAL_STR() is consistent with how other class names are handled.


2936-2961: New function for compiling inner class references.

zend_compile_inner_class_ref() calls out to compile the outer reference first, then compiles or duplicates the inner name. The approach aligns with how fetches are done for other class references. Ensure the engine’s memory manager frees temporary strings allocated by zend_string_dup.


3015-3021: Disallowing “static” for inner classes.

The error handling here is straightforward and consistent with the earlier check to prevent static inner classes.


7442-7444: Handling nested class references as valid type hints.

Extending zend_compile_single_typename logic to accept an inner class node is consistent with the new feature.


9109-9109: Helper function signature for interfaces.

zend_compile_implements(...) remains consistent in usage and scope. No immediate issues.


9274-9275: Resetting required_scope and lexical_scope.

Clearing these fields for non-nested class cases is unproblematic.


9317-9319: Compiling “implements” for an inner class.

Allowing inner classes to implement interfaces is consistent with the general design.


9364-9364: Early return to compile inner classes.

Jumping to compile_inner_classes upon early binding success is a clean approach to finalizing nested definitions.


9373-9373: Continue to compile inner classes.

Again, this goto pattern is consistent with the approach in earlier lines.


9443-9464: Compiling queued inner classes.

Processing the inner_class_queue after finalizing the outer class is a sound design. The memory cleanup (zend_hash_destroy) prevents leaks.


11732-11735: Defer class declaration within class.

If CG(active_class_entry) is set, you defer the nested class until the outer one is processed. This logic aligns with the approach used elsewhere.


11906-11909: Handling AST_INNER_CLASS in expression compilation.

Dispatching to zend_compile_inner_class_ref is consistent with how you handle other class references.

tests/classes/inner_classes/return_types_002.phpt (8)

1-2: No issues with test header.
The test name and description are clear and correctly describe the scenario being tested.


4-4: Standard PHP opening tag.
No functional or stylistic concerns.


6-7: Definition of a private inner class.
Declaring a private class Inner inside class Outer demonstrates the new inner-class functionality. This looks consistent with the surrounding test logic.


9-10: Private method returning an instance of the private inner class.
The function getInner() correctly returns new Inner(). Scope constraints look appropriate for a private method accessing a private inner class.


13-14: Public method delegating to a private inner-class instantiation.
getInner2() simply forwards to getInner(). The return typing and logic appear correct.


18-21: Subclass overrides the getInner() name with a public version.
Although the parent’s method is private (hence not inherited), the child defines its own getInner() returning Outer\Inner. The code intentionally triggers a fatal error due to private class instantiation outside the outer class. This is aligned with the test’s objective.


25-26: Test instantiation of subclass Foo.
Creating Foo and calling $outer->getInner() ensures the fatal error condition is exercised for private inner classes.


28-32: Expected output block for fatal error scenario.
The test output confirms that the newly created Outer\Inner object is dumped before the error is raised. This matches the intended coverage of private inner-class instantiation rules.

tests/classes/inner_classes/visibility_002.phpt (7)

1-2: Clear test header for outer class private variables accessibility.
No issues.


4-4: Standard PHP opening tag.
No additional concerns.


6-12: Definition of Outer class with a private inner class and private property.
The inner class Inner and property $illegal are declared private. The method Inner::test() sets the outer’s private property, showcasing that the inner class can access its outer’s private members. The structure is consistent with testing advanced visibility rules.


14-17: Public method in Outer instantiating its inner class and calling test().
This verifies that Inner can modify the private property $illegal. Logic is sound for verifying outer/inner class private member access.


19-20: Instantiation and method invocation on the Outer class.
Creating $x and calling $x->test() triggers the inner class assignment to a private property.


22-22: Checking the resulting object structure with var_dump.
This ensures $illegal is indeed set to an instance of Outer\Inner.


25-30: Expected output for verifying private property assigned to an inner class instance.
The script’s final var_dump is correct, highlighting that the private $illegal property references Outer\Inner.

tests/classes/inner_classes/static_variables.phpt (1)

1-31: LGTM! Test validates static variable and constant access in inner classes.

The test is well-structured to validate multiple important aspects:

  1. Class name resolution through the ::class mechanism
  2. Static constant access with the scope resolution operator
  3. Static variable access from nested classes
  4. Properly defined namespace-like structure for inner classes

The expected output correctly matches the implementation.

tests/classes/inner_classes/visibility_005.phpt (1)

1-28: LGTM! Test confirms inner classes can access private methods in outer classes.

This test successfully verifies an important visibility rule: inner classes should have access to private methods of their containing classes. The test demonstrates this by:

  1. An inner class accessing a private static method of its direct parent class
  2. An inner class instantiating and calling a private method of its grandparent class

The test confirms that inner class implementations maintain proper visibility rules for method access.

tests/classes/inner_classes/visibility_003.phpt (2)

6-17: LGTM! Test validates inner class access to private properties of outer class.

This test verifies that a private inner class can access private properties of its outer class, demonstrating the special visibility privileges inner classes have within their enclosing class.


19-23: LGTM! Test execution correctly validates inner/outer class relationship.

The test properly creates an instance, exercises the functionality, and dumps the object to verify the correct assignment of the inner class instance to the private property.

tests/classes/inner_classes/visibility_007.phpt (1)

1-28: LGTM! Test confirms inner classes can access protected methods in outer classes.

This test successfully verifies that inner classes can access protected methods of their containing classes. The test demonstrates:

  1. An inner class accessing a protected static method of its direct parent class
  2. An inner class instantiating and calling a protected method of its grandparent class

The expected output correctly confirms the behavior, showing the method calls work as expected and maintain proper qualifications in their method names.

tests/classes/inner_classes/simple_declaration_004.phpt (3)

6-12: LGTM: Clear demonstration of inner class declaration and instantiation

The code correctly demonstrates a simple inner class declaration within the Outer class and shows proper instantiation of the inner class. The testSelf() method demonstrates how to create an instance of the inner class from within the containing class.


14-25: LGTM: Good inheritance demonstration for inner classes

This code effectively demonstrates:

  1. How an outer class can extend another outer class
  2. How an inner class can extend an inner class from the parent outer class
  3. How to reference both the parent's inner class and its own inner class

The methods testParent() and testSelf() clearly show the different ways to instantiate each inner class variant.


33-41: LGTM: Expected output matches the test logic

The expected output correctly shows:

  1. Outer::testSelf() returns an Outer\Middle object
  2. Outer2::testParent() returns an Outer\Middle object
  3. Outer2::testSelf() returns an Outer2\Middle object
  4. The duplicate call returns the same object type

This confirms that scope resolution works as expected when dealing with inner classes across inheritance.

tests/classes/inner_classes/visibility_010.phpt (3)

6-14: Consider verifying external write-protection on private-set properties.

Your use of public private(set) string $name; and public private(set) string $email; suggests that external code should be restricted from mutating them. It would be beneficial to add negative or edge-case tests asserting that these properties cannot be overwritten from outside the class.

Would you like a follow-up test snippet showcasing attempts to change these properties externally and expecting a failure?


15-29: Builder pattern implemented correctly.

The Builder inner class neatly encapsulates property assignments before returning a fully constructed User instance, which aligns with typical builder patterns. This design nicely restricts direct instantiation of User.


32-33: LGTM on the final instantiation test.

The test scenario exercises the full builder flow (->withName()->withEmail()->build()) and verifies the object structure. Looks appropriate for confirming proper property assignments.

Zend/zend_execute.c (3)

1048-1078: Well-implemented visibility checking for inner classes.

This new function properly implements the visibility rules for inner classes, with clear separation of concerns for different visibility levels:

  1. Public classes (default) are always visible
  2. Protected classes are visible in related scopes with appropriate visibility
  3. Private classes are only visible in the same lexical scope with private visibility

The error messages are clear and informative, providing good context about why a visibility violation occurred.


1082-1085: Properly integrated class visibility check into property type verification.

This additional check ensures that object property assignments respect not just type compatibility but also the visibility constraints of inner classes. Adding this check before the regular type check follows the best practice of failing fast.


1237-1252: Correctly enforces type declaration visibility rules for inner classes.

This addition ensures that inner classes are properly checked when used as type declarations:

  1. Private inner classes can only be used within their exact defined scope
  2. Protected inner classes can only be used within their required scope or child scopes
  3. Both are prevented from being used in the global scope

This enforcement is essential for maintaining proper encapsulation in the type system.

Zend/zend_vm_execute.h (19)

3313-3313: New opcode case appears consistent.
The addition of ZEND_FETCH_INNER_CLASS to the switch statement aligns with the existing fetch-class cases. Future logic is located in the specialized handlers below.


10906-10921: Visibility-based return validation approved.
This block properly enforces that a public method cannot return a private or protected inner class. It may be worth verifying how private methods handle returning private classes, but otherwise the logic looks correct.


16251-16352: Repeated condition issue.
This handler exhibits the same pattern of always-true checks like (IS_TMP_VAR|IS_VAR) == IS_CONST. Please apply the fix suggested in the earlier comment for Hunk 2 to ensure accurate operand-type comparison and reduce code duplication.


21763-21778: Consistent return-scope checks.
This is the same visibility-based return validation logic introduced in Hunk 3. No additional issues found.


30257-30272: Return scope validation duplicated.
This mirrors the same safe-check logic as the previous segments for preventing returning restricted-scope classes.


34006-34107: Same operand-type check issue.
As with Hunk 2 and 4, the equality checks if (IS_UNUSED == IS_CONST) { ... } else if (IS_UNUSED == IS_UNUSED) { ... } are presumably incorrect. They should reference opline->op1_type to compare properly against IS_CONST or IS_UNUSED.


38167-38182: Visibility checks for return values.
Identical checks to the previous return-scope validations. No new concerns.


50986-51001: Reiterated return-scope validation.
This block follows the same structure for restricting return of private/protected classes from public/protected methods.


59919-59923: Hybrid VM case hooking.
This switch-case snippet correctly integrates the new ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST handler in the hybrid dispatcher.


61194-61198: Hybrid dispatcher extension looks correct.
This case properly registers ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST.


62787-62791: Unused const fetch hooking.
This snippet consistently introduces the new handler for ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST within the hybrid VM.


68246-68246: Repeated usage of 3491.
This reaffirms the same numeric constant. Refer to the previous comment for suggestions on using descriptive macros.


68377-68423: Large repetition of the same magic number.
Many consecutive lines repeat 3491. Verify if this is correct or if the logic-based dispatch should map to distinct spec codes. If correct, consider macros for clarity.


68622-68632: Continuing numeric spec codes.
These additions mirror the approach in the previous hunk. The same suggestion applies regarding named constants.


68643-68653: Further repeated spec codes.
Same pattern of numeric constants, presumably for specialized rules.


68664-68671: Spec codes for identical comparisons.
Again, these lines replicate the use of magic integers for the specification logic.


68682-68689: More numeric codes.
Identical pattern of bare integer constants for the dispatch logic.


68700-68705: Consistent approach to opcode specs.
These lines likewise follow the same numeric constants approach, with the same suggestion to introduce macros.


68716-68837: Extensive addition of numeric spec definitions.
The large block of repeated integers (e.g. 2965, 3040, 3125, etc.) suggests code generation or manual input. Ensure correctness of each mapped code, or consider macros for self-documentation.

Zend/zend_language_parser.y (6)

278-278: Confirm usage of newly introduced type
The grammar type inner_type_without_static doesn't appear to be referenced in this file. If it is intended for use in other files or future expansions, please confirm. Otherwise, consider removing it if it’s not needed.


287-287: No concerns about added grammar type reference
The addition of inner_class_statement to %type <ast> is logically consistent with the grammar’s handling of nested classes.


289-289: Looks good for new modifier type
Introducing inner_class_modifiers under %type <num> aligns with the existing pattern for other modifier groups.


629-636: Check default visibility for inner classes
When inner_class_modifiers is empty, it defaults to ZEND_ACC_PUBLIC. Verify that public is indeed the intended default for nested classes. If a different default was expected (e.g., private or protected), consider adjusting accordingly.


952-955: Reusing ZEND_AST_CLASS for inner_class_statement
This grammar rule creates an AST node with ZEND_AST_CLASS flags set to 0. Confirm that regular and nested classes should share the same AST type, or consider introducing a dedicated node (ZEND_AST_INNER_CLASS) if differentiation is needed.


975-976: New grammar production for inner classes
Allowing inner_class_modifiers inner_class_statement extends nested class support in the parser. Ensure your tests cover all modifier permutations to validate correct parsing and behavior.

Zend/zend_vm_handlers.h (6)

1375-1378: Introduce new opcodes for inner class fetch
These added opcodes (ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST, ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST, etc.) establish specialized handlers for retrieving an inner class from either a constant or temporary variable. This aligns well with the nested class functionality described in the PR summary.


1379-1379: Verify the new call offset spec usage
ZEND_INIT_FCALL_OFFSET_SPEC_CONST might require consistent adjustments to call offsets within the engine. Please ensure no collisions or misalignments occur with other opcodes.


1380-1380: Validate untyped parameter reception
ZEND_RECV_NOTYPE_SPEC implies relaxed type checks on function parameters. Confirm that calls expecting typed parameters in higher-level declarations remain unaffected.


1384-1384: Check forward jump specification
ZEND_JMP_FORWARD_SPEC likely optimizes particular branching scenarios. Confirm that jump targets are validated post-compilation, especially when certain opcodes are elided or reordered.


1401-1408: Evaluate fallback paths for standard long additions
ZEND_ADD_LONG_SPEC_TMPVARCV_* covers cases not specifically flagged as “no overflow.” Confirm that these do not duplicate the capabilities of the _NO_OVERFLOW_ variants and that unit tests cover boundary scenarios (e.g., adding large positive to large negative values).


1421-1423: No-overflow checks for long subtraction
ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV infers safe boundaries for certain subtractions. Validate that cases near integer limits (e.g., INT_MIN subtraction) are either properly warned about or correctly handled.

Comment on lines +5 to +10
spl_autoload_register(static function ($class_name) {
if (file_exists(__DIR__ . '/' . $class_name . '.inc')) {
require_once(__DIR__ . '/' . $class_name . '.inc');
}
echo 'autoload(' . $class_name . ")\n";
});
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Autoloader implementation looks correct but needs clarification.

The autoloader is properly registered and attempts to load files based on the requested class name. However, it's not immediately clear how this test specifically validates inner class autoloading.


🏁 Script executed:

#!/bin/bash
# Check if the inner_classes.inc file exists and what it contains
if [ -f "tests/classes/inner_classes/inner_classes.inc" ]; then
  echo "File exists. Contents:"
  cat "tests/classes/inner_classes/inner_classes.inc"
else
  echo "File not found. Searching for possible include files:"
  find tests/classes/inner_classes -name "*.inc" -type f | xargs ls -la
fi

Length of output: 323


Clarification and Additional Validation Needed for Inner Class Autoloading

The autoloader correctly loads the file from the inner classes directory (as confirmed by the existence and content of tests/classes/inner_classes/inner_classes.inc). However, it’s still unclear how the test validates the autoloading of the inner classes defined within that file. The current test case only triggers the autoloader based on the outer class name without explicitly verifying that inner classes (e.g., the public Point class) are available and functioning as intended.

  • Consider updating the test (or its comments/documentation) to clarify that inner class definitions are being validated.
  • It might be beneficial to add an assertion or instantiate an inner class (such as inner_classes::Point) to explicitly demonstrate that inner class autoloading is working correctly.

Comment on lines 1102 to 1109
static zend_string *zend_prefix_with_outer_class(zend_string *name) {
ZEND_ASSERT(CG(active_class_entry));

zend_string *ns = CG(active_class_entry)->name;

// encode the orginal scope
return zend_string_concat3(ZSTR_VAL(ns), ZSTR_LEN(ns), "|", 1, ZSTR_VAL(name), ZSTR_LEN(name));
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Check for naming delimiter collisions.

zend_prefix_with_outer_class() uses '|' as a delimiter between the outer and inner class names. Ensure there's no conflict with other code segments where ":>" or "\\\\" is also used as a delimiter.

Consider unifying the delimiters if possible, to avoid confusion.

Comment on lines 9213 to 9256
if (CG(active_class_entry) && CG(active_op_array)->function_name) {
zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be declared inside functions");
}

if (CG(active_class_entry)) {
// rename the inner class so we may reference it by name
name = zend_string_concat3(
ZSTR_VAL(CG(active_class_entry)->name), ZSTR_LEN(CG(active_class_entry)->name),
"\\", 1,
ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name)
);

// configure the current ce->flags for a nested class. This should only include:
// - final
// - readonly
// - abstract
decl->flags |= decl->attr & ZEND_ACC_FINAL;
if (decl->attr & ZEND_ACC_ABSTRACT) {
decl->flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
}
if (decl->attr & ZEND_ACC_READONLY) {
decl->flags |= ZEND_ACC_READONLY_CLASS | ZEND_ACC_NO_DYNAMIC_PROPERTIES;
}

// configure for a nested class. This should only include:
// - public
// - private
// - protected
int propFlags = decl->attr & (ZEND_ACC_PUBLIC|ZEND_ACC_PROTECTED|ZEND_ACC_PRIVATE);
// remove the flags from attrs
decl->attr &= ~(ZEND_ACC_PUBLIC|ZEND_ACC_PROTECTED|ZEND_ACC_PRIVATE|ZEND_ACC_FINAL|ZEND_ACC_ABSTRACT|ZEND_ACC_READONLY);

// if a class is private or protected, we need to require the correct scope
ce->required_scope = propFlags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED) ? CG(active_class_entry) : NULL;
ce->required_scope_absolute = propFlags & ZEND_ACC_PRIVATE ? true : false;
ce->lexical_scope = CG(active_class_entry);

// ensure the class is treated as a top-level class and not an anon class
toplevel = true;
} else {
name = zend_prefix_with_ns(unqualified_name);
ce->required_scope = NULL;
ce->lexical_scope = NULL;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Constructing the nested class name with “\” and adjusting flags.

While logically correct, you now have at least three delimiters ("|", ":>", "\\\\") for specifying nested classes in different contexts. This may introduce confusion or collisions. Consider unifying them, or at least documenting each delimiter’s purpose.

Comment on lines +67250 to +67254
ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_HANDLER,
ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER,
ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER,
ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_HANDLER,
ZEND_NULL_HANDLER,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Repeated TMPVAR handler.
Lines 67251 and 67252 both reference ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER. This duplication might indicate a missing specialized variant or a potential oversight. Double check.

Comment on lines +58043 to +58047
(void*)&&ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_LABEL,
(void*)&&ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL,
(void*)&&ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL,
(void*)&&ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_LABEL,
(void*)&&ZEND_NULL_LABEL,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential duplicate label reference.
Lines 58044 and 58045 both reference ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL. Confirm if this is intentional or a copy-paste error. Normally, each line would refer to a distinct specialized handler.

Comment on lines 6614 to 6715
USE_OPLINE
SAVE_OPLINE();

zend_string *inner_class_name, *full_class_name;
zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL;

scope = EX(func)->op_array.scope;

if (IS_CONST == IS_CONST) {
zval *outer_class_zv = RT_CONSTANT(opline, opline->op1);
outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv));
if (!outer_ce) {
zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
HANDLE_EXCEPTION();
}
} else if (IS_CONST == IS_UNUSED) {
uint32_t fetch_type;
zend_class_entry *called_scope;

fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK;
if (UNEXPECTED(scope == NULL)) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use \"%s\" in the global scope",
fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
if (fetch_type == ZEND_FETCH_CLASS_SELF) {
outer_ce = scope;
} else if (fetch_type == ZEND_FETCH_CLASS_PARENT) {
if (UNEXPECTED(scope->parent == NULL)) {
SAVE_OPLINE();
zend_throw_error(NULL,
"Cannot use \"parent\" when current class scope has no parent");
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
outer_ce = scope->parent;
} else if (fetch_type == ZEND_FETCH_CLASS_STATIC) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
called_scope = Z_OBJCE(EX(This));
} else {
called_scope = Z_CE(EX(This));
}
outer_ce = called_scope;
} else {
zend_throw_error(NULL, "Unknown scope resolution");
HANDLE_EXCEPTION();
}
} else {
outer_ce = Z_CE_P(EX_VAR(opline->op1.var));
}

inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));

if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) {
zend_error(E_ERROR, "Class name is too long");
HANDLE_EXCEPTION();
}

full_class_name = zend_string_concat3(
ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name),
":>", 2,
ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name)
);

inner_ce = zend_lookup_class(full_class_name);
if (!inner_ce) {
zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name));
HANDLE_EXCEPTION();
}

if (inner_ce->required_scope) {
if (inner_ce->required_scope_absolute) {
// for private classes, we check if the scope we are currently in has access
if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) {
// we are in the correct scope
} else {
zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name));
HANDLE_EXCEPTION();
}
} else {
// for protected classes, we check if the scope is an instance of the required scope
if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) {
// we are in the correct scope
} else {
zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name));
HANDLE_EXCEPTION();
}
}
}

Z_CE_P(EX_VAR(opline->result.var)) = inner_ce;

zend_string_release(full_class_name);

ZEND_VM_NEXT_OPCODE();
}

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Suspicious condition and duplicated logic.
The code includes an always-true check if (IS_CONST == IS_CONST) and an equally suspicious else if (IS_CONST == IS_UNUSED). This prevents the subsequent branches from ever executing. Likely it should compare opline->op1_type against IS_CONST and IS_UNUSED, as shown below. In addition, the specialized fetch logic appears largely duplicated across multiple handlers. Consider extracting common logic into a helper function to reduce duplication.

Example fix:

- if (IS_CONST == IS_CONST) {
-     zval *outer_class_zv = RT_CONSTANT(opline, opline->op1);
-     ...
- } else if (IS_CONST == IS_UNUSED) {
+ if (opline->op1_type == IS_CONST) {
+     zval *outer_class_zv = RT_CONSTANT(opline, opline->op1);
+     ...
+ } else if (opline->op1_type == IS_UNUSED) {
    ...
 }
📝 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
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
SAVE_OPLINE();
zend_string *inner_class_name, *full_class_name;
zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL;
scope = EX(func)->op_array.scope;
if (IS_CONST == IS_CONST) {
zval *outer_class_zv = RT_CONSTANT(opline, opline->op1);
outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv));
if (!outer_ce) {
zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)));
HANDLE_EXCEPTION();
}
} else if (IS_CONST == IS_UNUSED) {
uint32_t fetch_type;
zend_class_entry *called_scope;
fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK;
if (UNEXPECTED(scope == NULL)) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use \"%s\" in the global scope",
fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
if (fetch_type == ZEND_FETCH_CLASS_SELF) {
outer_ce = scope;
} else if (fetch_type == ZEND_FETCH_CLASS_PARENT) {
if (UNEXPECTED(scope->parent == NULL)) {
SAVE_OPLINE();
zend_throw_error(NULL,
"Cannot use \"parent\" when current class scope has no parent");
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
outer_ce = scope->parent;
} else if (fetch_type == ZEND_FETCH_CLASS_STATIC) {
if (Z_TYPE(EX(This)) == IS_OBJECT) {
called_scope = Z_OBJCE(EX(This));
} else {
called_scope = Z_CE(EX(This));
}
outer_ce = called_scope;
} else {
zend_throw_error(NULL, "Unknown scope resolution");
HANDLE_EXCEPTION();
}
} else {
outer_ce = Z_CE_P(EX_VAR(opline->op1.var));
}
inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) {
zend_error(E_ERROR, "Class name is too long");
HANDLE_EXCEPTION();
}
full_class_name = zend_string_concat3(
ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name),
":>", 2,
ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name)
);
inner_ce = zend_lookup_class(full_class_name);
if (!inner_ce) {
zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name));
HANDLE_EXCEPTION();
}
if (inner_ce->required_scope) {
if (inner_ce->required_scope_absolute) {
// for private classes, we check if the scope we are currently in has access
if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) {
// we are in the correct scope
} else {
zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name));
HANDLE_EXCEPTION();
}
} else {
// for protected classes, we check if the scope is an instance of the required scope
if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) {
// we are in the correct scope
} else {
zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name));
HANDLE_EXCEPTION();
}
}
}
Z_CE_P(EX_VAR(opline->result.var)) = inner_ce;
zend_string_release(full_class_name);
ZEND_VM_NEXT_OPCODE();
}
if (opline->op1_type == IS_CONST) {
zval *outer_class_zv = RT_CONSTANT(opline, opline->op1);
...
} else if (opline->op1_type == IS_UNUSED) {
...
}

Comment on lines +1381 to +1383
_(2585, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \
_(2586, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \
_(2588, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refine array counting specifications
The newly introduced ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED and ZEND_COUNT_ARRAY_SPEC_CV_UNUSED target array counting under different storage contexts. Verify that null inputs or non-array inputs behave correctly and throw consistent warnings/errors as intended.

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 (1)
Zend/zend_execute_API.c (1)

1186-1186: Consider using a safer method for modifying the scope_name string.

The comment indicates you're aware there might be a better approach. Directly modifying the null terminator of a zend_string could be risky if the implementation details change.

Instead of directly modifying the string, consider using zend_string APIs:

- scope_name = zend_string_init(ZSTR_VAL(requested_name), unqualified_name - ZSTR_VAL(requested_name) + 1, 0);
- scope_name->val[scope_name->len - 1] = '\\'; // todo: there is probably a better way
+ size_t namespace_len = unqualified_name - ZSTR_VAL(requested_name);
+ scope_name = zend_string_concat2(ZSTR_VAL(requested_name), namespace_len, "\\", 1);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 17fa07c and 71a7f6d.

📒 Files selected for processing (2)
  • Zend/zend_execute_API.c (2 hunks)
  • Zend/zend_inheritance.c (1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
Zend/zend_inheritance.c (1)
Zend/zend_execute_API.c (1)
  • zend_fetch_class (1794-1839)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: WINDOWS_X64_ZTS
  • GitHub Check: MACOS_ARM64_DEBUG_NTS
  • GitHub Check: LINUX_X64_DEBUG_ZTS_ASAN
  • GitHub Check: FREEBSD
  • GitHub Check: LINUX_X64_RELEASE_NTS
  • GitHub Check: LINUX_X32_DEBUG_ZTS
  • GitHub Check: BENCHMARKING
🔇 Additional comments (2)
Zend/zend_inheritance.c (1)

2638-2638: Improved code simplicity by using direct function call

The code now uses zend_fetch_class instead of a manual process of converting to lowercase and using hash lookup. This simplifies the code while maintaining the same functionality.

Zend/zend_execute_API.c (1)

1303-1313: Good integration of the nested class resolution logic.

The changes to zend_lookup_class_ex correctly integrate the nested class resolution function by:

  1. Adding a condition to check if we should skip inner class resolution
  2. Calling the new zend_resolve_nested_class function
  3. Proper early return with memory management
  4. Applying the NO_INNER flag in recursive calls to prevent infinite recursion

This is a well-structured modification to the existing function.

Comment on lines 1169 to 1242
static zend_class_entry *zend_resolve_nested_class(zend_string *requested_name, uint32_t flags) {
zend_class_entry *ce = NULL;
char *separator;
zend_string *scope_name = NULL;

const char *unqualified_name = strrchr(ZSTR_VAL(requested_name), '|');
if (unqualified_name == NULL) {
unqualified_name = strrchr(ZSTR_VAL(requested_name), '\\');
if (unqualified_name == NULL) {
// there is not a nested class here...
return NULL;
}
}

zend_string *inner_name = zend_string_init(unqualified_name + 1, ZSTR_LEN(requested_name) - (unqualified_name - ZSTR_VAL(requested_name) + 1), 0);

scope_name = zend_string_init(ZSTR_VAL(requested_name), unqualified_name - ZSTR_VAL(requested_name) + 1, 0);
scope_name->val[scope_name->len - 1] = '\\'; // todo: there is probably a better way

requested_name = zend_string_concat2(ZSTR_VAL(scope_name), ZSTR_LEN(scope_name), ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));

while ((separator = strrchr(ZSTR_VAL(scope_name), '\\'))) {
const size_t outer_len = separator - ZSTR_VAL(scope_name);

zend_string *outer_class_name = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
const zend_class_entry *outer_ce = zend_lookup_class_ex(outer_class_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);

if (outer_ce) {
// Outer class found; now explicitly check the requested class again
ce = zend_lookup_class_ex(requested_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
if (ce) {
zend_string_release(scope_name);
zend_string_release(outer_class_name);
zend_string_release(inner_name);
zend_string_release(requested_name);
return ce;
}
}

// Check if the class is in the outer scope
zend_string *outer_name = zend_string_concat3(ZSTR_VAL(outer_class_name), ZSTR_LEN(outer_class_name), "\\", 1, ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
ce = zend_lookup_class_ex(outer_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
zend_string_release(outer_name);
zend_string_release(outer_class_name);
if (ce) {
zend_string_release(scope_name);
zend_string_release(inner_name);
zend_string_release(requested_name);
return ce;
}

// Continue moving upwards (perhaps the inner class is further up)
zend_string *shorter_scope = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
zend_string_release(scope_name);
scope_name = shorter_scope;
}

// handle the edge case where the class is in the global scope
//if (separator == NULL) {
ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
zend_string_release(scope_name);
zend_string_release(inner_name);
zend_string_release(requested_name);
return ce;
//}

zend_string_release(scope_name);

// Final lookup directly at namespace/global scope
//ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
zend_string_release(inner_name);
zend_string_release(requested_name);
return NULL;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Implementation of a nested class resolution function with some areas for improvement.

This new function supports inner class resolution in PHP by walking up the namespace hierarchy, which is a significant addition. However, there are a few issues to address:

  1. Lines 1238-1241 are unreachable code since every path already returns at line 1232 or 1233
  2. There are commented-out if statements (lines 1226-1228 and 1237-1238) that should be either removed or uncommented if needed
  3. The final string release on line 1239 never executes

Here's a cleaner implementation:

static zend_class_entry *zend_resolve_nested_class(zend_string *requested_name, uint32_t flags) {
    zend_class_entry *ce = NULL;
    char *separator;
    zend_string *scope_name = NULL;

    const char *unqualified_name = strrchr(ZSTR_VAL(requested_name), '|');
    if (unqualified_name == NULL) {
        unqualified_name = strrchr(ZSTR_VAL(requested_name), '\\');
        if (unqualified_name == NULL) {
            // there is not a nested class here...
            return NULL;
        }
    }

    zend_string *inner_name = zend_string_init(unqualified_name + 1, ZSTR_LEN(requested_name) - (unqualified_name - ZSTR_VAL(requested_name) + 1), 0);

    scope_name = zend_string_init(ZSTR_VAL(requested_name), unqualified_name - ZSTR_VAL(requested_name) + 1, 0);
    scope_name->val[scope_name->len - 1] = '\\'; // todo: there is probably a better way

    requested_name = zend_string_concat2(ZSTR_VAL(scope_name), ZSTR_LEN(scope_name), ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));

    while ((separator = strrchr(ZSTR_VAL(scope_name), '\\'))) {
        const size_t outer_len = separator - ZSTR_VAL(scope_name);

        zend_string *outer_class_name = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
        const zend_class_entry *outer_ce = zend_lookup_class_ex(outer_class_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);

        if (outer_ce) {
            // Outer class found; now explicitly check the requested class again
            ce = zend_lookup_class_ex(requested_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
            if (ce) {
                zend_string_release(scope_name);
                zend_string_release(outer_class_name);
                zend_string_release(inner_name);
                zend_string_release(requested_name);
                return ce;
            }
        }

        // Check if the class is in the outer scope
        zend_string *outer_name = zend_string_concat3(ZSTR_VAL(outer_class_name), ZSTR_LEN(outer_class_name), "\\", 1, ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
        ce = zend_lookup_class_ex(outer_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
        zend_string_release(outer_name);
        zend_string_release(outer_class_name);
        if (ce) {
            zend_string_release(scope_name);
            zend_string_release(inner_name);
            zend_string_release(requested_name);
            return ce;
        }

        // Continue moving upwards (perhaps the inner class is further up)
        zend_string *shorter_scope = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
        zend_string_release(scope_name);
        scope_name = shorter_scope;
    }

    // Final check in global scope
    ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
    zend_string_release(scope_name);
    zend_string_release(inner_name);
    zend_string_release(requested_name);
    return ce;
}
📝 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
static zend_class_entry *zend_resolve_nested_class(zend_string *requested_name, uint32_t flags) {
zend_class_entry *ce = NULL;
char *separator;
zend_string *scope_name = NULL;
const char *unqualified_name = strrchr(ZSTR_VAL(requested_name), '|');
if (unqualified_name == NULL) {
unqualified_name = strrchr(ZSTR_VAL(requested_name), '\\');
if (unqualified_name == NULL) {
// there is not a nested class here...
return NULL;
}
}
zend_string *inner_name = zend_string_init(unqualified_name + 1, ZSTR_LEN(requested_name) - (unqualified_name - ZSTR_VAL(requested_name) + 1), 0);
scope_name = zend_string_init(ZSTR_VAL(requested_name), unqualified_name - ZSTR_VAL(requested_name) + 1, 0);
scope_name->val[scope_name->len - 1] = '\\'; // todo: there is probably a better way
requested_name = zend_string_concat2(ZSTR_VAL(scope_name), ZSTR_LEN(scope_name), ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
while ((separator = strrchr(ZSTR_VAL(scope_name), '\\'))) {
const size_t outer_len = separator - ZSTR_VAL(scope_name);
zend_string *outer_class_name = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
const zend_class_entry *outer_ce = zend_lookup_class_ex(outer_class_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
if (outer_ce) {
// Outer class found; now explicitly check the requested class again
ce = zend_lookup_class_ex(requested_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
if (ce) {
zend_string_release(scope_name);
zend_string_release(outer_class_name);
zend_string_release(inner_name);
zend_string_release(requested_name);
return ce;
}
}
// Check if the class is in the outer scope
zend_string *outer_name = zend_string_concat3(ZSTR_VAL(outer_class_name), ZSTR_LEN(outer_class_name), "\\", 1, ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
ce = zend_lookup_class_ex(outer_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
zend_string_release(outer_name);
zend_string_release(outer_class_name);
if (ce) {
zend_string_release(scope_name);
zend_string_release(inner_name);
zend_string_release(requested_name);
return ce;
}
// Continue moving upwards (perhaps the inner class is further up)
zend_string *shorter_scope = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
zend_string_release(scope_name);
scope_name = shorter_scope;
}
// handle the edge case where the class is in the global scope
//if (separator == NULL) {
ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
zend_string_release(scope_name);
zend_string_release(inner_name);
zend_string_release(requested_name);
return ce;
//}
zend_string_release(scope_name);
// Final lookup directly at namespace/global scope
//ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
zend_string_release(inner_name);
zend_string_release(requested_name);
return NULL;
}
static zend_class_entry *zend_resolve_nested_class(zend_string *requested_name, uint32_t flags) {
zend_class_entry *ce = NULL;
char *separator;
zend_string *scope_name = NULL;
const char *unqualified_name = strrchr(ZSTR_VAL(requested_name), '|');
if (unqualified_name == NULL) {
unqualified_name = strrchr(ZSTR_VAL(requested_name), '\\');
if (unqualified_name == NULL) {
// there is not a nested class here...
return NULL;
}
}
zend_string *inner_name = zend_string_init(unqualified_name + 1, ZSTR_LEN(requested_name) - (unqualified_name - ZSTR_VAL(requested_name) + 1), 0);
scope_name = zend_string_init(ZSTR_VAL(requested_name), unqualified_name - ZSTR_VAL(requested_name) + 1, 0);
scope_name->val[scope_name->len - 1] = '\\'; // todo: there is probably a better way
requested_name = zend_string_concat2(ZSTR_VAL(scope_name), ZSTR_LEN(scope_name), ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
while ((separator = strrchr(ZSTR_VAL(scope_name), '\\'))) {
const size_t outer_len = separator - ZSTR_VAL(scope_name);
zend_string *outer_class_name = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
const zend_class_entry *outer_ce = zend_lookup_class_ex(outer_class_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
if (outer_ce) {
// Outer class found; now explicitly check the requested class again
ce = zend_lookup_class_ex(requested_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
if (ce) {
zend_string_release(scope_name);
zend_string_release(outer_class_name);
zend_string_release(inner_name);
zend_string_release(requested_name);
return ce;
}
}
// Check if the class is in the outer scope
zend_string *outer_name = zend_string_concat3(ZSTR_VAL(outer_class_name), ZSTR_LEN(outer_class_name), "\\", 1, ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
ce = zend_lookup_class_ex(outer_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
zend_string_release(outer_name);
zend_string_release(outer_class_name);
if (ce) {
zend_string_release(scope_name);
zend_string_release(inner_name);
zend_string_release(requested_name);
return ce;
}
// Continue moving upwards (perhaps the inner class is further up)
zend_string *shorter_scope = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
zend_string_release(scope_name);
scope_name = shorter_scope;
}
// Final check in global scope
ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
zend_string_release(scope_name);
zend_string_release(inner_name);
zend_string_release(requested_name);
return ce;
}

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

♻️ Duplicate comments (1)
Zend/zend_execute_API.c (1)

1169-1246: 🛠️ Refactor suggestion

Simplify the nested class resolution function to fix unreachable code issues.

The implementation contains several issues:

  1. Lines 1238-1246 are unreachable code since the function unconditionally returns at line 1232
  2. There are commented-out if statements (lines 1231-1232 and 1237-1238) that should be removed
  3. Redundant string allocation happens at line 1242-1245

Here's a cleaner implementation:

static zend_class_entry *zend_resolve_nested_class(zend_string *requested_name, uint32_t flags) {
    zend_class_entry *ce = NULL;
    char *separator;
    zend_string *scope_name = NULL;

    const char *unqualified_name = strrchr(ZSTR_VAL(requested_name), '|');
    if (unqualified_name == NULL) {
        unqualified_name = strrchr(ZSTR_VAL(requested_name), '\\');
        if (unqualified_name == NULL) {
            // there is not a nested class here...
            return NULL;
        }
    }

    zend_string *inner_name = zend_string_init(unqualified_name + 1, ZSTR_LEN(requested_name) - (unqualified_name - ZSTR_VAL(requested_name) + 1), 0);

    scope_name = zend_string_init(ZSTR_VAL(requested_name), unqualified_name - ZSTR_VAL(requested_name) + 1, 0);
    scope_name->val[scope_name->len - 1] = '\\'; // todo: there is probably a better way

+   zend_string *final_requested_name;
    if (ZSTR_LEN(scope_name) == ZSTR_LEN(inner_name) + 1 && zend_string_starts_with_ci(scope_name, inner_name)) {
-       requested_name = zend_string_copy(inner_name);
+       final_requested_name = zend_string_copy(inner_name);
    } else {
-       requested_name = zend_string_concat2(ZSTR_VAL(scope_name), ZSTR_LEN(scope_name), ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
+       final_requested_name = zend_string_concat2(ZSTR_VAL(scope_name), ZSTR_LEN(scope_name), ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
    }

    while ((separator = strrchr(ZSTR_VAL(scope_name), '\\'))) {
        const size_t outer_len = separator - ZSTR_VAL(scope_name);

        zend_string *outer_class_name = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
        const zend_class_entry *outer_ce = zend_lookup_class_ex(outer_class_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);

        if (outer_ce) {
            // Outer class found; now explicitly check the requested class again
-           ce = zend_lookup_class_ex(requested_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
+           ce = zend_lookup_class_ex(final_requested_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
            if (ce) {
                zend_string_release(scope_name);
                zend_string_release(outer_class_name);
                zend_string_release(inner_name);
-               zend_string_release(requested_name);
+               zend_string_release(final_requested_name);
                return ce;
            }
        }

        // Check if the class is in the outer scope
        zend_string *outer_name = zend_string_concat3(ZSTR_VAL(outer_class_name), ZSTR_LEN(outer_class_name), "\\", 1, ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
        ce = zend_lookup_class_ex(outer_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
        zend_string_release(outer_name);
        zend_string_release(outer_class_name);
        if (ce) {
            zend_string_release(scope_name);
            zend_string_release(inner_name);
-           zend_string_release(requested_name);
+           zend_string_release(final_requested_name);
            return ce;
        }

        // Continue moving upwards (perhaps the inner class is further up)
        zend_string *shorter_scope = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
        zend_string_release(scope_name);
        scope_name = shorter_scope;
    }

-   // handle the edge case where the class is in the global scope
-   //if (separator == NULL) {
    ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
    zend_string_release(scope_name);
    zend_string_release(inner_name);
-   zend_string_release(requested_name);
+   zend_string_release(final_requested_name);
    return ce;
-   //}
-
-   zend_string_release(scope_name);
-
-   // Final lookup directly at namespace/global scope
-   //ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
-   zend_string_release(inner_name);
-   zend_string_release(requested_name);
-   return NULL;
}
🧹 Nitpick comments (1)
Zend/zend_execute_API.c (1)

1186-1186: Consider a safer approach for string manipulation.

The TODO comment accurately points out that directly manipulating the string value is not ideal.

Consider using a string concatenation function instead:

- scope_name = zend_string_init(ZSTR_VAL(requested_name), unqualified_name - ZSTR_VAL(requested_name) + 1, 0);
- scope_name->val[scope_name->len - 1] = '\\'; // todo: there is probably a better way
+ size_t prefix_len = unqualified_name - ZSTR_VAL(requested_name);
+ scope_name = zend_string_concat2(ZSTR_VAL(requested_name), prefix_len, "\\", 1);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 71a7f6d and 2767025.

📒 Files selected for processing (1)
  • Zend/zend_execute_API.c (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: WINDOWS_X64_ZTS
  • GitHub Check: MACOS_ARM64_DEBUG_NTS
  • GitHub Check: LINUX_X64_DEBUG_ZTS_ASAN
  • GitHub Check: LINUX_X64_RELEASE_NTS
  • GitHub Check: LINUX_X32_DEBUG_ZTS
  • GitHub Check: FREEBSD
  • GitHub Check: BENCHMARKING
🔇 Additional comments (3)
Zend/zend_execute_API.c (3)

1174-1181: Guard against NULL pointer dereference when extracting unqualified names.

If neither '|' nor '\' separator is found in the class name, the code correctly returns NULL. However, the early return protects subsequent operations that assume unqualified_name is valid.

This issue was correctly addressed in this version, based on a previous review comment. The function properly checks for NULL before proceeding with string operations.


1309-1317: Good implementation of inner class resolution into the lookup mechanism.

The implementation elegantly integrates the inner class resolution function into the existing class lookup mechanism. The check occurs after standard lookup fails but before autoloading, which is the correct position in the lookup sequence.


1188-1192:

❓ Verification inconclusive

Verify the case-insensitive string comparison for self-references.

The condition checks if the scope name is essentially the same as the inner name (plus a backslash), which could indicate a self-reference. The conditional branch appears to handle a special case where a class references itself, though it's not entirely clear.

Let's verify this logic by checking other PHP inner class test files:


🏁 Script executed:

#!/bin/bash
# Look for test cases with class references that might be self-references
rg -A 5 -B 5 "class.*{.*class" tests/classes/inner_classes/

Length of output: 167


Let's try a revised approach. The original regex in the verification command wasn’t properly escaped—specifically, the literal curly brace in the pattern needs escaping. I suggest re-running the search using an updated regex. For example:

This revised command should let us search through the PHP inner class test files without encountering regex errors. Please run this updated script to verify whether there are any test cases that cover self-references (i.e., where a class references itself via its scope name).

After reviewing the output, we can finalize whether the case-insensitive comparison logic truly needs additional adjustments.


🏁 Script executed:

#!/bin/bash
# Corrected regex: escaping the curly brace to avoid parse errors
rg -A 5 -B 5 'class.*\{.*class' tests/classes/inner_classes/

Length of output: 184


Manual Verification Required: Confirm Self-Reference Handling

The automated search for inner class scenarios did not return any matching test cases for self-references, using our revised regex approach. Please manually verify that the condition

if (ZSTR_LEN(scope_name) == ZSTR_LEN(inner_name) + 1 && zend_string_starts_with_ci(scope_name, inner_name)) {
	requested_name = zend_string_copy(inner_name);
} else {
	requested_name = zend_string_concat2(ZSTR_VAL(scope_name), ZSTR_LEN(scope_name), ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
}

correctly accounts for self-references (i.e., when a class references itself, as indicated by the scope name being exactly one character longer than the inner name and starting with it case-insensitively). Since no automatically detected test cases were found, please review the impacted behavior and consider adding explicit tests if needed.

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 (2)
Zend/zend_compile.c (2)

1816-1847: Adding a ':>' delimiter for nested class resolution.

Using ":>" for concatenating inner and outer class names introduces another delimiter. Consider unifying these delimiters ('|', ":>", "\\\\") or documenting their usage to maintain clarity.


9175-9191: Global inner_class_queue usage.

Relying on a static inner_class_queue HashTable allows deferred compilation for nested classes, but it may introduce coupling or concurrency concerns if used in complex scenarios. Consider encapsulating this logic or carefully documenting the intent.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2767025 and 7119f6c.

📒 Files selected for processing (2)
  • Zend/zend_attributes.c (1 hunks)
  • Zend/zend_compile.c (21 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: WINDOWS_X64_ZTS
  • GitHub Check: LINUX_X64_DEBUG_ZTS_ASAN
  • GitHub Check: MACOS_ARM64_DEBUG_NTS
  • GitHub Check: LINUX_X64_RELEASE_NTS
  • GitHub Check: LINUX_X32_DEBUG_ZTS
  • GitHub Check: FREEBSD
  • GitHub Check: BENCHMARKING
🔇 Additional comments (20)
Zend/zend_attributes.c (1)

487-497: Implementation looks good for supporting inner class attribute resolution.

The added logic elegantly handles attribute names containing pipe characters by extracting the substring after the last pipe and recursively calling the function. This approach maintains backward compatibility while adding support for nested class attribute lookups.

The memory management is handled correctly with proper string initialization and release. This change aligns well with the overall PR objective of supporting inner class declarations in PHP.

Zend/zend_compile.c (19)

896-909: Allowing additional modifiers for inner classes.

These conditions correctly permit the T_READONLY, T_ABSTRACT, and T_FINAL tokens for inner classes. Please ensure there is comprehensive test coverage validating each of these new modifiers on inner classes.


947-948: Introducing a new “inner class” member identifier.

This addition cleanly extends the existing logic to label a new ZEND_MODIFIER_TARGET_INNER_CLASS type. Looks good.


1056-1086: Disallowing specific modifiers for inner classes.

Preventing static, public(set), protected(set), and private(set) on inner classes appears consistent with the intended language design. The compile-time error messages are clear.


1102-1109: Check for naming delimiter collisions.

This code uses the '|' delimiter to encode the original scope. This reiterates a past comment about potential collisions with other delimiters ("\\\\", ":>"). Consider unifying or documenting them more explicitly to avoid confusion.


1248-1250: Prefixing name with outer class.

When an active class entry is detected, the code redirects to zend_prefix_with_outer_class() to encode the name. The flow is straightforward and seamlessly integrated.


1885-1888: Correctly resolving inner class names in constant expressions.

Storing the resolved name in zv via zend_resolve_nested_class_name() is consistent with the overall design for nested classes.


2942-2966: Inner class reference compilation.

This function implements ZEND_FETCH_INNER_CLASS with clear handling for both constant and dynamically computed names. The structure looks solid.


3021-3027: Preventing 'static' on inner classes.

The compile-time error is appropriately raised to disallow static for nested classes, matching the new language rules.


7448-7450: Type resolution for nested classes.

When an inner class is encountered in a type hint or union, the code properly initializes a class type using zend_resolve_nested_class_name().


9115-9115: Implementing interfaces for nested classes.

No issues spotted with the structure here. The function signature and usage remain consistent with the broader compilation logic.


9219-9262: Constructing the nested class name with “\”.

This continues the pattern of introducing multiple delimiters, echoing a prior suggestion to unify or clearly document them.


9280-9281: Clearing scope references.

Resetting required_scope and lexical_scope for classes declared as top-level or anonymous ensures consistent handling of new and existing scopes.


9323-9325: Support for 'implements' in inner classes.

Including zend_compile_implements() ensures that inner classes can implement interfaces as expected.


9370-9371: Early exit to compile inner classes.

The goto compile_inner_classes; flow is a practical shortcut once early binding has succeeded.


9379-9380: Link and compile nested classes.

The jump to compile_inner_classes after linking is coherent with the planned design.


9450-9468: Compiling queued inner classes.

Dequeueing subsequent inner classes ensures they are compiled in the correct context, addressing the dependency on outer classes being defined first.


11738-11741: Deferring class declarations when inside another class.

If CG(active_class_entry) is set, classes are enqueued for later compilation; otherwise, they proceed immediately. This design is logically consistent.


11912-11914: New AST node for inner classes.

Routing ZEND_AST_INNER_CLASS to zend_compile_inner_class_ref() completes the chain of nested-class handling logic. Nicely done.


1446-1450:

❓ Verification inconclusive

Potential collision with the '|' delimiter.

Stripping everything before the last '|' to retrieve the inner class name is clever, but please verify that '|' is disallowed in real-world class names to avoid accidental collisions.

Here is a script to check for any existing safeguards or usage of '|' in class name checks:


🏁 Script executed:

#!/bin/bash
# Searching for validation or error checks restricting '|' in class names
rg '\|' -A 10

Length of output: 75009


Action: Confirm that the '|' delimiter is safe for encoding inner class names.

The grep search did not reveal any explicit safeguards in the codebase that reject the '|' character in class names. Given that PHP class names are validated by its parser—which typically limits identifiers to letters, digits, and underscores—it's likely that a '|' cannot occur in legitimate class names. However, please verify that PHP’s lexical and parsing rules indeed prohibit the use of '|' in class names to avoid any accidental collisions.

  • Review the PHP parser/lexer logic for class name validation to confirm that the '|' character is disallowed.
  • Document the guarantee (or add additional checks) if there’s any concern that an inner class name might unexpectedly contain a '|' due to non-standard input.

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 (1)
Zend/zend_execute_API.c (1)

1169-1245: New function to resolve nested class names with opportunities for optimization.

The implementation of zend_resolve_nested_class is a key addition for supporting inner classes. The function correctly handles parsing and resolution of nested class names, but has several areas for optimization:

  1. The TODO comment on line 1186 indicates there's likely a better way to handle this character manipulation.
  2. The string manipulation logic in lines 1213-1221 is overly complex.
  3. There's commented-out code on line 1241 which appears to be a never-executed final lookup at the global scope.

Consider these optimizations:

static zend_class_entry *zend_resolve_nested_class(zend_string *requested_name, uint32_t flags) {
    zend_class_entry *ce = NULL;
    char *separator;
    zend_string *scope_name = NULL;

    const char *unqualified_name = strrchr(ZSTR_VAL(requested_name), '|');
    if (unqualified_name == NULL) {
        unqualified_name = strrchr(ZSTR_VAL(requested_name), '\\');
        if (unqualified_name == NULL) {
            // there is not a nested class here...
            return NULL;
        }
    }

    zend_string *inner_name = zend_string_init(unqualified_name + 1, ZSTR_LEN(requested_name) - (unqualified_name - ZSTR_VAL(requested_name) + 1), 0);

    scope_name = zend_string_init(ZSTR_VAL(requested_name), unqualified_name - ZSTR_VAL(requested_name), 0);
-   scope_name->val[scope_name->len - 1] = '\\'; // todo: there is probably a better way
+   scope_name = zend_string_extend(scope_name, ZSTR_LEN(scope_name) + 1, 0);
+   ZSTR_VAL(scope_name)[ZSTR_LEN(scope_name) - 1] = '\\';
+   ZSTR_VAL(scope_name)[ZSTR_LEN(scope_name)] = '\0';

    if (ZSTR_LEN(scope_name) == ZSTR_LEN(inner_name) + 1 && zend_string_starts_with_ci(scope_name, inner_name)) {
        requested_name = zend_string_copy(inner_name);
    } else {
        requested_name = zend_string_concat2(ZSTR_VAL(scope_name), ZSTR_LEN(scope_name), ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
    }

    while ((separator = strrchr(ZSTR_VAL(scope_name), '\\'))) {
        const size_t outer_len = separator - ZSTR_VAL(scope_name);

        zend_string *outer_class_name = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
        const zend_class_entry *outer_ce = zend_lookup_class_ex(outer_class_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);

        if (outer_ce) {
            // Outer class found; now explicitly check the requested class again
            ce = zend_lookup_class_ex(requested_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
            if (ce) {
                zend_string_release(scope_name);
                zend_string_release(outer_class_name);
                zend_string_release(inner_name);
                zend_string_release(requested_name);
                return ce;
            }
        }

        // Check if the class is in the outer scope
-       char *outer_name = strrchr(ZSTR_VAL(outer_class_name), '\\');
-       zend_string *outer_name_z;
-       if (!outer_name) {
-           outer_name_z = zend_string_copy(inner_name);
-       } else {
-           zend_string *tmp = zend_string_init(ZSTR_VAL(outer_class_name), outer_name - ZSTR_VAL(outer_class_name), 0);
-           outer_name_z = zend_string_concat3(ZSTR_VAL(tmp), ZSTR_LEN(tmp), "\\", 1, ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
-           zend_string_release(tmp);
-       }
+       // Simplified approach - either use the outer_class_name as-is or append inner_name with a separator
+       zend_string *outer_name_z;
+       char *last_separator = strrchr(ZSTR_VAL(outer_class_name), '\\');
+       if (!last_separator) {
+           outer_name_z = zend_string_copy(inner_name);
+       } else {
+           outer_name_z = zend_string_concat3(
+               ZSTR_VAL(outer_class_name), ZSTR_LEN(outer_class_name), 
+               "\\", 1, 
+               ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
+       }
        ce = zend_lookup_class_ex(outer_name_z, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
        zend_string_release(outer_name_z);
        zend_string_release(outer_class_name);
        if (ce) {
            zend_string_release(scope_name);
            zend_string_release(inner_name);
            zend_string_release(requested_name);
            return ce;
        }

        // Continue moving upwards (perhaps the inner class is further up)
        zend_string *shorter_scope = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
        zend_string_release(scope_name);
        scope_name = shorter_scope;
    }

    zend_string_release(scope_name);

-   // Final lookup directly at namespace/global scope
-   //ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
+   // Final fallback: global scope lookup for the inner name
+   // ce = zend_lookup_class_ex(inner_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
    zend_string_release(inner_name);
    zend_string_release(requested_name);
    return NULL;
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7119f6c and a05c5db.

📒 Files selected for processing (1)
  • Zend/zend_execute_API.c (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: WINDOWS_X64_ZTS
  • GitHub Check: MACOS_ARM64_DEBUG_NTS
  • GitHub Check: LINUX_X64_DEBUG_ZTS_ASAN
  • GitHub Check: LINUX_X32_DEBUG_ZTS
  • GitHub Check: LINUX_X64_RELEASE_NTS
  • GitHub Check: BENCHMARKING
  • GitHub Check: FREEBSD
🔇 Additional comments (1)
Zend/zend_execute_API.c (1)

1306-1316: Good implementation of inner class lookup within the class table.

This modification to the zend_lookup_class_ex function correctly integrates the inner class resolution mechanism into the regular class lookup workflow. It ensures inner classes are properly resolved when a standard lookup fails by checking if our current scope is an outer class.

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: 7

♻️ Duplicate comments (2)
Zend/zend_execute_API.c (1)

1169-1245: 🛠️ Refactor suggestion

Implementation of a new function to resolve nested classes.

This function carefully walks the namespace hierarchy to find nested classes, working its way upward through each parent scope until it finds the class. There are a few items to address:

  1. The commented-out code at line 1241 looks like an intended final fallback lookup but is disabled
  2. There's unused code at lines 1238-1243 that will never be reached as all code paths return earlier
  3. The string manipulation at line 1186 could be handled more elegantly

Here's a cleaner version of the function with the unreachable code removed and more clear error handling:

static zend_class_entry *zend_resolve_nested_class(zend_string *requested_name, uint32_t flags) {
    zend_class_entry *ce = NULL;
    char *separator;
    zend_string *scope_name = NULL;

    const char *unqualified_name = strrchr(ZSTR_VAL(requested_name), '|');
    if (unqualified_name == NULL) {
        unqualified_name = strrchr(ZSTR_VAL(requested_name), '\\');
        if (unqualified_name == NULL) {
            // there is not a nested class here...
            return NULL;
        }
    }

    zend_string *inner_name = zend_string_init(unqualified_name + 1, ZSTR_LEN(requested_name) - (unqualified_name - ZSTR_VAL(requested_name) + 1), 0);

    scope_name = zend_string_init(ZSTR_VAL(requested_name), unqualified_name - ZSTR_VAL(requested_name) + 1, 0);
    scope_name->val[scope_name->len - 1] = '\\'; // todo: there is probably a better way

    if (ZSTR_LEN(scope_name) == ZSTR_LEN(inner_name) + 1 && zend_string_starts_with_ci(scope_name, inner_name)) {
        requested_name = zend_string_copy(inner_name);
    } else {
        requested_name = zend_string_concat2(ZSTR_VAL(scope_name), ZSTR_LEN(scope_name), ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
    }

    while ((separator = strrchr(ZSTR_VAL(scope_name), '\\'))) {
        const size_t outer_len = separator - ZSTR_VAL(scope_name);

        zend_string *outer_class_name = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
        const zend_class_entry *outer_ce = zend_lookup_class_ex(outer_class_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);

        if (outer_ce) {
            // Outer class found; now explicitly check the requested class again
            ce = zend_lookup_class_ex(requested_name, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
            if (ce) {
                zend_string_release(scope_name);
                zend_string_release(outer_class_name);
                zend_string_release(inner_name);
                zend_string_release(requested_name);
                return ce;
            }
        }

        // Check if the class is in the outer scope
        char *outer_name = strrchr(ZSTR_VAL(outer_class_name), '\\');
        zend_string *outer_name_z;
        if (!outer_name) {
            outer_name_z = zend_string_copy(inner_name);
        } else {
            zend_string *tmp = zend_string_init(ZSTR_VAL(outer_class_name), outer_name - ZSTR_VAL(outer_class_name), 0);
            outer_name_z = zend_string_concat3(ZSTR_VAL(tmp), ZSTR_LEN(tmp), "\\", 1, ZSTR_VAL(inner_name), ZSTR_LEN(inner_name));
            zend_string_release(tmp);
        }
        ce = zend_lookup_class_ex(outer_name_z, NULL, flags | ZEND_FETCH_CLASS_NO_INNER);
        zend_string_release(outer_name_z);
        zend_string_release(outer_class_name);
        if (ce) {
            zend_string_release(scope_name);
            zend_string_release(inner_name);
            zend_string_release(requested_name);
            return ce;
        }

        // Continue moving upwards (perhaps the inner class is further up)
        zend_string *shorter_scope = zend_string_init(ZSTR_VAL(scope_name), outer_len, 0);
        zend_string_release(scope_name);
        scope_name = shorter_scope;
    }

    // Clean up remaining resources
    zend_string_release(scope_name);
    zend_string_release(inner_name);
    zend_string_release(requested_name);
    return NULL;
}
Zend/zend_API.c (1)

1819-1832: ⚠️ Potential issue

Prevent possible segfault when scope->lexical_scope is NULL

The call to instanceof_function(scope->lexical_scope, ...) can segfault if scope->lexical_scope happens to be NULL. Short-circuit the check or handle the NULL case before calling instanceof_function to avoid dereferencing a null pointer.

🧹 Nitpick comments (6)
Zend/zend_vm_def.h (1)

1801-1901: Consider unifying error handling and validating scope->lexical_scope.
Overall, the logic for ZEND_FETCH_INNER_CLASS is solid, but you are mixing zend_error(E_ERROR, ...) and zend_throw_error(...) for fatal conditions. For consistency with other newly introduced code paths (e.g., zend_throw_error(NULL, ...) calls), consider using zend_throw_error exclusively and ensure that any references to scope->lexical_scope account for the possibility of scope->lexical_scope being NULL.

Zend/zend_API.h (1)

282-299: Consider reducing repeated calls to strlen().
In INIT_CLASS_NAME_EX, ns_len is already provided, but the code also calls strlen(ns) at runtime. You might save time by using the supplied ns_len instead of calling strlen(ns) repeatedly, especially if namespace strings become non-trivial. Overall, the macro logic itself appears correct.

ext/zend_test/test_arginfo.h (1)

584-1276: Consider adding documentation for the new namespaced name handling

While the implementation is consistent and complete, future maintainers would benefit from documentation explaining the purpose of the zend_namespaced_name type and the two-step initialization process (first with INIT_CLASS_NAME/INIT_CLASS_NAME_NS and then with INIT_CLASS_ENTRY).

Zend/zend_compile.c (1)

8688-8705: Grammar fix: “must accept exactly one parameter.”
The message currently reads “one parameters.”

Use this patch:

- "must accept exactly one parameters"
+ "must accept exactly one parameter"
Zend/zend_execute.c (2)

1237-1252: Visibility enforcement for inner classes used as type declarations.

This code correctly enforces that inner classes can only be used as type declarations in appropriate scopes. However, consider using exceptions instead of E_ERROR to be consistent with PHP's other visibility violations which are typically catchable.

- zend_error(E_ERROR, "Private inner class %s cannot be used as a type declaration in the global scope", ZSTR_VAL(ce->namespaced_name.name));
+ zend_throw_error(NULL, "Private inner class %s cannot be used as a type declaration in the global scope", ZSTR_VAL(ce->namespaced_name.name));

Additionally, consider refactoring the error message logic to reduce duplication between private and protected class error cases.


1064-1065: Consider enhancing error message with parent scope information.

The protected class visibility error doesn't indicate the parent scope that the class requires to be visible, which might make debugging harder.

zend_type_error("Cannot assign protected %s to higher visibile property %s::%s",
    ZSTR_VAL(ce->namespaced_name.name),
    ZSTR_VAL(info->ce->namespaced_name.name),
-    zend_get_unmangled_property_name(info->name));
+    zend_get_unmangled_property_name(info->name),
+    ZSTR_VAL(ce->required_scope->namespaced_name.name));
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a05c5db and 141995f.

📒 Files selected for processing (171)
  • Zend/Optimizer/ssa_integrity.c (1 hunks)
  • Zend/Optimizer/zend_dump.c (3 hunks)
  • Zend/Optimizer/zend_optimizer.c (1 hunks)
  • Zend/zend.h (4 hunks)
  • Zend/zend_API.c (39 hunks)
  • Zend/zend_API.h (5 hunks)
  • Zend/zend_ast.c (3 hunks)
  • Zend/zend_attributes.c (3 hunks)
  • Zend/zend_attributes_arginfo.h (7 hunks)
  • Zend/zend_builtin_functions.c (7 hunks)
  • Zend/zend_builtin_functions_arginfo.h (1 hunks)
  • Zend/zend_closures.c (3 hunks)
  • Zend/zend_closures_arginfo.h (1 hunks)
  • Zend/zend_compile.c (53 hunks)
  • Zend/zend_compile.h (3 hunks)
  • Zend/zend_enum.c (12 hunks)
  • Zend/zend_enum_arginfo.h (2 hunks)
  • Zend/zend_exceptions.c (7 hunks)
  • Zend/zend_exceptions_arginfo.h (13 hunks)
  • Zend/zend_execute.c (33 hunks)
  • Zend/zend_execute_API.c (5 hunks)
  • Zend/zend_fibers.c (1 hunks)
  • Zend/zend_fibers_arginfo.h (2 hunks)
  • Zend/zend_generators.c (1 hunks)
  • Zend/zend_generators_arginfo.h (2 hunks)
  • Zend/zend_inheritance.c (50 hunks)
  • Zend/zend_interfaces.c (7 hunks)
  • Zend/zend_interfaces_arginfo.h (8 hunks)
  • Zend/zend_iterators.c (1 hunks)
  • Zend/zend_lazy_objects.c (3 hunks)
  • Zend/zend_object_handlers.c (36 hunks)
  • Zend/zend_objects.c (2 hunks)
  • Zend/zend_opcode.c (5 hunks)
  • Zend/zend_operators.c (4 hunks)
  • Zend/zend_property_hooks.c (2 hunks)
  • Zend/zend_smart_str.c (3 hunks)
  • Zend/zend_string.h (1 hunks)
  • Zend/zend_vm_def.h (22 hunks)
  • Zend/zend_vm_execute.h (86 hunks)
  • Zend/zend_weakrefs.c (1 hunks)
  • Zend/zend_weakrefs_arginfo.h (2 hunks)
  • build/gen_stub.php (1 hunks)
  • ext/bcmath/bcmath_arginfo.h (1 hunks)
  • ext/com_dotnet/com_extension_arginfo.h (5 hunks)
  • ext/com_dotnet/com_persist_arginfo.h (1 hunks)
  • ext/curl/curl_arginfo.h (4 hunks)
  • ext/curl/curl_file_arginfo.h (2 hunks)
  • ext/date/php_date.c (2 hunks)
  • ext/date/php_date_arginfo.h (15 hunks)
  • ext/dba/dba_arginfo.h (1 hunks)
  • ext/dl_test/dl_test_arginfo.h (4 hunks)
  • ext/dom/document.c (1 hunks)
  • ext/dom/html_collection.c (2 hunks)
  • ext/dom/node.c (1 hunks)
  • ext/dom/nodelist.c (2 hunks)
  • ext/dom/parentnode/tree.c (2 hunks)
  • ext/dom/php_dom.c (39 hunks)
  • ext/dom/php_dom.h (1 hunks)
  • ext/dom/php_dom_arginfo.h (49 hunks)
  • ext/dom/token_list.c (2 hunks)
  • ext/enchant/enchant_arginfo.h (2 hunks)
  • ext/ffi/ffi_arginfo.h (5 hunks)
  • ext/fileinfo/fileinfo_arginfo.h (1 hunks)
  • ext/ftp/ftp_arginfo.h (1 hunks)
  • ext/gd/gd_arginfo.h (2 hunks)
  • ext/gmp/gmp_arginfo.h (1 hunks)
  • ext/hash/hash_arginfo.h (1 hunks)
  • ext/intl/breakiterator/breakiterator_arginfo.h (3 hunks)
  • ext/intl/breakiterator/breakiterator_iterators_arginfo.h (1 hunks)
  • ext/intl/calendar/calendar_arginfo.h (2 hunks)
  • ext/intl/collator/collator_arginfo.h (1 hunks)
  • ext/intl/common/common_arginfo.h (1 hunks)
  • ext/intl/common/common_date.cpp (2 hunks)
  • ext/intl/converter/converter_arginfo.h (1 hunks)
  • ext/intl/dateformat/dateformat_arginfo.h (1 hunks)
  • ext/intl/dateformat/datepatterngenerator_arginfo.h (1 hunks)
  • ext/intl/formatter/formatter_arginfo.h (1 hunks)
  • ext/intl/locale/locale_arginfo.h (1 hunks)
  • ext/intl/msgformat/msgformat_arginfo.h (1 hunks)
  • ext/intl/normalizer/normalizer_arginfo.h (1 hunks)
  • ext/intl/php_intl_arginfo.h (1 hunks)
  • ext/intl/resourcebundle/resourcebundle_arginfo.h (1 hunks)
  • ext/intl/resourcebundle/resourcebundle_class.c (1 hunks)
  • ext/intl/spoofchecker/spoofchecker_arginfo.h (1 hunks)
  • ext/intl/timezone/timezone_arginfo.h (1 hunks)
  • ext/intl/transliterator/transliterator_arginfo.h (1 hunks)
  • ext/intl/uchar/uchar_arginfo.h (1 hunks)
  • ext/json/json_arginfo.h (2 hunks)
  • ext/ldap/ldap_arginfo.h (3 hunks)
  • ext/libxml/libxml.c (2 hunks)
  • ext/libxml/libxml_arginfo.h (1 hunks)
  • ext/mysqli/mysqli.c (6 hunks)
  • ext/mysqli/mysqli_arginfo.h (6 hunks)
  • ext/mysqli/mysqli_nonapi.c (2 hunks)
  • ext/mysqli/mysqli_prop.c (3 hunks)
  • ext/mysqli/mysqli_warning.c (3 hunks)
  • ext/mysqli/php_mysqli_structs.h (3 hunks)
  • ext/odbc/odbc_arginfo.h (2 hunks)
  • ext/openssl/openssl_arginfo.h (3 hunks)
  • ext/pdo/pdo_arginfo.h (1 hunks)
  • ext/pdo/pdo_dbh.c (4 hunks)
  • ext/pdo/pdo_dbh_arginfo.h (1 hunks)
  • ext/pdo/pdo_stmt.c (2 hunks)
  • ext/pdo/pdo_stmt_arginfo.h (2 hunks)
  • ext/pdo/php_pdo.h (1 hunks)
  • ext/pdo_dblib/pdo_dblib_arginfo.h (1 hunks)
  • ext/pdo_firebird/pdo_firebird_arginfo.h (1 hunks)
  • ext/pdo_mysql/pdo_mysql_arginfo.h (1 hunks)
  • ext/pdo_odbc/pdo_odbc_arginfo.h (1 hunks)
  • ext/pdo_pgsql/pdo_pgsql_arginfo.h (1 hunks)
  • ext/pdo_sqlite/pdo_sqlite_arginfo.h (1 hunks)
  • ext/pgsql/pgsql_arginfo.h (3 hunks)
  • ext/phar/phar_object.c (10 hunks)
  • ext/phar/phar_object_arginfo.h (4 hunks)
  • ext/random/engine_mt19937.c (1 hunks)
  • ext/random/random_arginfo.h (10 hunks)
  • ext/readline/readline_cli.c (2 hunks)
  • ext/reflection/php_reflection.c (49 hunks)
  • ext/reflection/php_reflection_arginfo.h (29 hunks)
  • ext/session/session.c (1 hunks)
  • ext/session/session_arginfo.h (4 hunks)
  • ext/shmop/shmop_arginfo.h (1 hunks)
  • ext/simplexml/simplexml_arginfo.h (2 hunks)
  • ext/snmp/snmp_arginfo.h (2 hunks)
  • ext/soap/soap_arginfo.h (8 hunks)
  • ext/sockets/sockets_arginfo.h (2 hunks)
  • ext/sodium/libsodium_arginfo.h (1 hunks)
  • ext/spl/php_spl.c (1 hunks)
  • ext/spl/spl_array.c (10 hunks)
  • ext/spl/spl_array_arginfo.h (3 hunks)
  • ext/spl/spl_directory.c (2 hunks)
  • ext/spl/spl_directory_arginfo.h (7 hunks)
  • ext/spl/spl_dllist_arginfo.h (3 hunks)
  • ext/spl/spl_exceptions_arginfo.h (13 hunks)
  • ext/spl/spl_fixedarray.c (1 hunks)
  • ext/spl/spl_fixedarray_arginfo.h (1 hunks)
  • ext/spl/spl_functions.c (3 hunks)
  • ext/spl/spl_heap_arginfo.h (4 hunks)
  • ext/spl/spl_iterators.c (11 hunks)
  • ext/spl/spl_iterators_arginfo.h (20 hunks)
  • ext/spl/spl_observer.c (1 hunks)
  • ext/spl/spl_observer_arginfo.h (4 hunks)
  • ext/sqlite3/sqlite3_arginfo.h (4 hunks)
  • ext/standard/basic_functions_arginfo.h (2 hunks)
  • ext/standard/dir_arginfo.h (1 hunks)
  • ext/standard/http.c (1 hunks)
  • ext/standard/php_incomplete_class.h (1 hunks)
  • ext/standard/type.c (1 hunks)
  • ext/standard/user_filters_arginfo.h (2 hunks)
  • ext/standard/var.c (8 hunks)
  • ext/standard/var_unserializer.re (6 hunks)
  • ext/sysvmsg/sysvmsg_arginfo.h (1 hunks)
  • ext/sysvsem/sysvsem_arginfo.h (1 hunks)
  • ext/sysvshm/sysvshm_arginfo.h (1 hunks)
  • ext/tidy/tidy_arginfo.h (2 hunks)
  • ext/tokenizer/tokenizer.c (1 hunks)
  • ext/tokenizer/tokenizer_arginfo.h (1 hunks)
  • ext/xml/xml.c (2 hunks)
  • ext/xml/xml_arginfo.h (1 hunks)
  • ext/xmlreader/php_xmlreader.c (3 hunks)
  • ext/xmlreader/php_xmlreader_arginfo.h (1 hunks)
  • ext/xmlwriter/php_xmlwriter_arginfo.h (1 hunks)
  • ext/xsl/php_xsl_arginfo.h (1 hunks)
  • ext/zend_test/fiber_arginfo.h (1 hunks)
  • ext/zend_test/iterators_arginfo.h (1 hunks)
  • ext/zend_test/object_handlers_arginfo.h (5 hunks)
  • ext/zend_test/test_arginfo.h (21 hunks)
  • ext/zip/php_zip.c (1 hunks)
  • ext/zip/php_zip_arginfo.h (1 hunks)
  • ext/zlib/zlib_arginfo.h (2 hunks)
  • main/streams/userspace.c (22 hunks)
✅ Files skipped from review due to trivial changes (5)
  • ext/mysqli/mysqli_nonapi.c
  • ext/intl/dateformat/datepatterngenerator_arginfo.h
  • ext/intl/formatter/formatter_arginfo.h
  • Zend/zend_weakrefs_arginfo.h
  • ext/spl/spl_exceptions_arginfo.h
🚧 Files skipped from review as they are similar to previous changes (5)
  • Zend/zend_opcode.c
  • Zend/zend_attributes.c
  • Zend/zend_object_handlers.c
  • Zend/zend_inheritance.c
  • ext/reflection/php_reflection_arginfo.h
🧰 Additional context used
🧬 Code Definitions (62)
ext/intl/breakiterator/breakiterator_iterators_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/spl/spl_observer.c (1)
Zend/zend_API.h (1)
  • zend_zval_value_name (386-386)
ext/tokenizer/tokenizer_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/standard/http.c (1)
Zend/zend.h (1)
  • zend_value_error (415-415)
ext/intl/collator/collator_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/curl/curl_file_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/pdo_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_generators_arginfo.h (2)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/session/session_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/xml/xml_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/spl/spl_dllist_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_closures_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/dom/html_collection.c (2)
Zend/zend.h (2)
  • zend_illegal_container_offset (417-417)
  • type (264-264)
ext/dom/nodelist.c (1)
  • dom_modern_nodelist_get_index (253-279)
ext/pdo/pdo_stmt_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/dom/parentnode/tree.c (2)
Zend/zend_API.h (2)
  • zend_argument_type_error (1584-1584)
  • zend_zval_type_name (385-385)
Zend/zend_API.c (1)
  • zend_argument_type_error (423-430)
ext/intl/msgformat/msgformat_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/intl/common/common_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/standard/user_filters_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/gd/gd_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/tokenizer/tokenizer.c (1)
Zend/zend.h (1)
  • zend_throw_error (412-412)
ext/sysvsem/sysvsem_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_interfaces.c (4)
Zend/zend.h (7)
  • zend_error_noreturn (402-402)
  • ce (217-217)
  • ce (218-218)
  • object (221-221)
  • object (222-222)
  • class_type (214-214)
  • zend_error (401-401)
Zend/zend_exceptions.c (1)
  • zend_throw_exception_ex (862-873)
Zend/zend_API.h (8)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
  • class_type (467-467)
Zend/zend_vm_def.h (1)
  • EG (8088-8088)
ext/spl/spl_observer_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
Zend/zend_fibers_arginfo.h (2)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/snmp/snmp_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/spl/spl_array_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_builtin_functions_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/dom/node.c (2)
Zend/zend.h (1)
  • zend_throw_error (412-412)
Zend/zend_exceptions.c (1)
  • zend_throw_exception_ex (862-873)
ext/ldap/ldap_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_interfaces_arginfo.h (2)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/intl/php_intl_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/Optimizer/zend_dump.c (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
Zend/zend_compile.h (2)
  • op_array (875-875)
  • op_array (976-976)
Zend/zend_operators.c (1)
Zend/zend.h (2)
  • zend_throw_error (412-412)
  • zend_error (401-401)
Zend/zend_ast.c (2)
Zend/zend.h (2)
  • zend_throw_error (412-412)
  • zend_error (401-401)
Zend/zend_object_handlers.c (1)
  • zend_abstract_method_call (1781-1785)
ext/sqlite3/sqlite3_arginfo.h (2)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/pdo_sqlite/pdo_sqlite_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/fileinfo/fileinfo_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/gmp/gmp_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_execute_API.c (4)
Zend/zend.h (4)
  • ce (217-217)
  • ce (218-218)
  • name (269-269)
  • name (275-275)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_compile.h (1)
  • name (988-988)
ext/mysqli/mysqli_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_property_hooks.c (1)
Zend/zend_compile.h (1)
  • zend_get_unmangled_property_name (967-967)
ext/dba/dba_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/standard/basic_functions_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/enchant/enchant_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/sockets/sockets_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/mysqli/mysqli.c (1)
ext/mysqli/mysqli_arginfo.h (8)
  • register_class_mysqli (1228-1415)
  • register_class_mysqli (1228-1228)
  • register_class_mysqli_warning (1530-1556)
  • register_class_mysqli_warning (1530-1530)
  • register_class_mysqli_result (1417-1456)
  • register_class_mysqli_result (1417-1417)
  • register_class_mysqli_stmt (1458-1528)
  • register_class_mysqli_stmt (1458-1458)
ext/date/php_date.c (5)
Zend/zend.h (7)
  • zend_throw_error (412-412)
  • ce (217-217)
  • ce (218-218)
  • object (221-221)
  • object (222-222)
  • name (269-269)
  • name (275-275)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/standard/php_incomplete_class.h (1)
  • object (53-53)
Zend/zend_compile.h (1)
  • name (988-988)
ext/dl_test/dl_test_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pgsql/pgsql_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/openssl/openssl_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/phar/phar_object_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/intl/uchar/uchar_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_API.h (1)
Zend/zend_compile.h (1)
  • class_name (943-943)
ext/zend_test/object_handlers_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/dom/php_dom.c (2)
ext/dom/php_dom_arginfo.h (22)
  • register_class_Dom_HTMLDocument (3571-3581)
  • register_class_Dom_HTMLDocument (3571-3571)
  • register_class_Dom_NodeList (2939-2956)
  • register_class_Dom_NodeList (2939-2939)
  • register_class_Dom_NamedNodeMap (2958-2975)
  • register_class_Dom_NamedNodeMap (2958-2958)
  • register_class_Dom_DtdNamedNodeMap (2977-2994)
  • register_class_Dom_DtdNamedNodeMap (2977-2977)
  • register_class_Dom_HTMLCollection (2996-3013)
  • register_class_Dom_HTMLCollection (2996-2996)
  • register_class_Dom_HTMLElement (3157-3167)
  • register_class_Dom_HTMLElement (3157-3157)
  • register_class_DOMComment (1935-1945)
  • register_class_DOMComment (1935-1935)
  • register_class_Dom_Comment (3307-3317)
  • register_class_Dom_Comment (3307-3307)
  • register_class_DOMCdataSection (1923-1933)
  • register_class_DOMCdataSection (1923-1923)
  • register_class_Dom_CDATASection (3277-3287)
  • register_class_Dom_CDATASection (3277-3277)
  • register_class_Dom_XPath (3674-3697)
  • register_class_Dom_XPath (3674-3674)
ext/dom/php_dom.h (3)
  • dom_nnodemap_objects_new (130-130)
  • dom_objects_new (129-129)
  • dom_xpath_objects_new (132-132)
Zend/zend_vm_def.h (2)
Zend/zend.h (5)
  • zend_error (401-401)
  • zend_throw_error (412-412)
  • ce (217-217)
  • ce (218-218)
  • zend_type_error (413-413)
Zend/zend_compile.h (1)
  • zend_visibility_string (436-436)
ext/curl/curl_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
Zend/zend_compile.c (5)
Zend/zend_exceptions.c (1)
  • zend_throw_exception (851-859)
Zend/zend_compile.h (5)
  • name (988-988)
  • type (930-930)
  • type (1008-1008)
  • class_name (943-943)
  • zend_initialize_class_data (983-983)
Zend/zend_execute.h (7)
  • name (37-37)
  • name (51-51)
  • name (52-52)
  • name (421-421)
  • class_name (416-416)
  • class_name (417-417)
  • class_name (418-418)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
Zend/zend_inheritance.c (1)
  • zend_hooked_property_variance_error_ex (1775-1779)
ext/zip/php_zip_arginfo.h (3)
Zend/zend.h (2)
  • ce (217-217)
  • ce (218-218)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
ext/pdo/php_pdo.h (1)
  • ce (26-26)
ext/spl/spl_array.c (2)
Zend/zend.h (5)
  • object (221-221)
  • object (222-222)
  • type (264-264)
  • zend_illegal_container_offset (417-417)
  • zend_throw_error (412-412)
Zend/zend_exceptions.c (1)
  • zend_throw_exception_ex (862-873)
Zend/zend_execute.c (7)
Zend/zend_compile.h (2)
  • zend_get_unmangled_property_name (967-967)
  • name (988-988)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
Zend/zend_execute.h (8)
  • name (37-37)
  • name (51-51)
  • name (52-52)
  • name (421-421)
  • zend_verify_property_type_error (528-528)
  • func (394-402)
  • func (405-405)
  • zend_param_must_be_ref (67-67)
Zend/zend_object_handlers.h (16)
  • prop_info (331-333)
  • ce (249-249)
  • ce (313-313)
  • object (84-84)
  • object (87-87)
  • object (93-93)
  • object (96-96)
  • object (106-106)
  • object (114-114)
  • object (117-117)
  • object (120-120)
  • object (123-123)
  • object (126-126)
  • object (128-128)
  • object (150-150)
  • object (156-156)
Zend/zend_compile.c (17)
  • bool (308-322)
  • bool (526-529)
  • bool (2073-2083)
  • bool (2086-2097)
  • bool (2460-2485)
  • bool (9911-9931)
  • bool (9933-9995)
  • bool (10010-10021)
  • void (106-116)
  • void (145-148)
  • void (504-511)
  • void (532-535)
  • void (1308-1323)
  • void (1326-1344)
  • void (2115-2128)
  • void (2148-2214)
  • void (7064-7086)
Zend/zend_object_handlers.c (10)
  • bool (259-270)
  • bool (971-976)
  • bool (1591-1615)
  • void (456-462)
  • void (657-662)
  • void (700-705)
  • void (1286-1305)
  • void (1438-1549)
  • void (1552-1567)
  • void (1958-1980)
Zend/zend_exceptions.c (1)
  • zend_throw_exception_ex (862-873)
ext/zend_test/test_arginfo.h (1)
Zend/zend_API.h (7)
  • ce (444-444)
  • ce (455-455)
  • ce (456-456)
  • ce (469-481)
  • ce (469-469)
  • ce (503-511)
  • ce (503-503)
🪛 GitHub Actions: Push
Zend/zend_compile.c

[error] 1925-1925: error C2220: the following warning is treated as an error. warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 3000-3000: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 3018-3018: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 3025-3025: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 6825-6825: warning C4133: 'function': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 7125-7125: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 7540-7540: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 9025-9025: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 9045-9045: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 9095-9095: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 9130-9130: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 9148-9148: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 9151-9151: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 11088-11088: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 11371-11371: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 11463-11463: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


[error] 12288-12288: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'

🔇 Additional comments (642)
ext/xmlreader/php_xmlreader_arginfo.h (1)

177-180: XMLReader class registration updated to support inner class feature.

The class registration has been modified to use a two-step process with zend_namespaced_name. This change aligns with the broader architecture changes for inner class support in PHP.

ext/simplexml/simplexml_arginfo.h (2)

162-165: Looks good - Class registration updated for inner class support

The update properly implements the new class registration pattern using zend_namespaced_name and the two-step initialization process with INIT_CLASS_NAME and INIT_CLASS_ENTRY. This change supports the broader goal of enabling inner class declarations in PHP.


175-178: LGTM - Consistent implementation for SimpleXMLIterator

The same pattern is correctly applied to the SimpleXMLIterator class registration, maintaining consistency across the codebase. This two-step initialization prepares the class for the inner class support framework.

ext/ldap/ldap_arginfo.h (3)

833-836: Class registration updated to support inner classes

The code has been updated to use a two-step class registration process using INIT_CLASS_NAME_NS and INIT_CLASS_ENTRY with a namespaced name structure, which supports the inner class functionality being implemented in this PR.


845-848: Consistent implementation of namespaced class initialization

The implementation maintains consistency with the Connection class registration pattern, correctly separating the namespace name creation from the class entry initialization.


857-860: Consistent implementation for ResultEntry class

This change follows the same pattern as the other class registrations, ensuring a uniform approach across all LDAP classes.

ext/enchant/enchant_arginfo.h (2)

232-236: Implementation adapts class registration for inner class support

The addition of the zend_namespaced_name variable and the use of INIT_CLASS_NAME macro correctly modifies the class registration process to support the new inner class infrastructure. This change maintains compatibility while enabling the hierarchical class naming required for inner classes.


244-248: Consistent implementation of class registration pattern

This implementation follows the same pattern as the EnchantBroker class, ensuring consistency across the codebase. The changes properly integrate with the inner class support infrastructure while preserving the existing functionality.

ext/zend_test/object_handlers_arginfo.h (5)

46-49: Implementation looks good - support for inner classes

The addition of zend_namespaced_name and the split of class initialization into INIT_CLASS_NAME and INIT_CLASS_ENTRY properly supports the inner class feature being implemented in this PR. This change correctly separates class name handling from entry initialization.


64-67: Consistent implementation across class registrations

The changes here mirror those in the DoOperationNoCast class, maintaining consistency in how classes are registered with the new inner class support.


82-85: Implementation follows the same pattern correctly

The FloatCastableNoOperations class registration follows the same pattern as the previous classes, correctly implementing the new two-step initialization process for inner class support.


100-103: Consistent implementation of class registration

This follows the same pattern as the other class registrations, correctly implementing the two-step initialization process with INIT_CLASS_NAME and INIT_CLASS_ENTRY.


118-121: Correct implementation for a class with no methods

The implementation is consistent with the other classes, properly handling the NULL case for a class with no methods while still supporting inner class naming.

ext/phar/phar_object_arginfo.h (4)

610-613: Refactored class registration to support inner classes

The code now initializes class entries in a two-step process, first creating a namespaced name structure using INIT_CLASS_NAME, then passing it to INIT_CLASS_ENTRY. This change supports the inner class feature being implemented in this PR.


622-625: Consistent implementation of the namespaced class registration pattern

The same pattern of using zend_namespaced_name is correctly applied to the Phar class, maintaining consistency with the other class registrations in this file.


731-734: Properly updated PharData class registration

PharData class registration now follows the same pattern of using the namespaced name structure, ensuring consistency throughout the extension.


744-747: Properly updated PharFileInfo class registration

The PharFileInfo class registration has been updated to use the new namespaced class name approach, completing the changes needed for this file to support the inner class feature.

ext/reflection/php_reflection.c (4)

4079-4091: Implementation of isInnerClass() method looks good.

This method correctly determines if a class is an inner class by checking if the class entry has a lexical scope. This is a clean implementation that follows the existing pattern of reflection API methods.


4094-4103: Implementation of isPrivate() method correctly checks class visibility.

The logic appropriately determines if a class is private by verifying both that it has a required scope and that the required_scope_absolute flag is true. This follows the expected behavior for private inner classes.


4106-4114: Implementation of isProtected() method correctly checks class visibility.

The method correctly identifies protected classes by checking that required_scope is set but required_scope_absolute is false, which is the right distinction between protected and private visibility.


4117-4124: Implementation of isPublic() method correctly checks class visibility.

The method properly identifies public classes by verifying there's no required scope, indicating no visibility restrictions. This completes the set of visibility checks needed for inner classes.

ext/dom/php_dom.h (1)

224-224: Align error message with namespaced class name structure

The error message now correctly uses the namespaced name of the class, which is necessary for proper identification of classes in the new inner class implementation.

Zend/zend_weakrefs.c (1)

370-370: Update error message to display full namespaced class name

This change ensures that error messages properly display the full namespaced name of classes when an object is not found in a WeakMap, which is important for inner class support.

ext/pdo/php_pdo.h (1)

61-61: Use namespaced class name in uninitialized object error

The error message now correctly uses the namespaced name structure, improving error reporting for classes including inner classes.

ext/standard/php_incomplete_class.h (1)

35-35: Update class name access to use namespaced name structure

This change ensures that the PHP_SET_CLASS_ATTRIBUTES macro properly handles class names with the new namespaced structure, necessary for supporting inner classes.

ext/dom/token_list.c (2)

323-323: Update to use namespaced class name in error message.

This change updates the error handling to use the class's namespaced name instead of just the class name, ensuring more accurate error reporting, especially when dealing with inner classes.


336-336: Update to use namespaced class name in error message.

Similar to the previous change, this updates the error reporting to use the fully qualified namespaced class name for improved clarity in error messages.

ext/spl/spl_fixedarray.c (1)

355-355: Update to use namespaced class name in error reporting.

Changed to use namespaced_name.name instead of just name for the SplFixedArray class in error reporting, which provides more accurate error messages especially when dealing with potential inner classes.

ext/standard/http.c (1)

98-98: Use namespaced class name in error message for enums.

Updated the error message to use the fully qualified namespaced class name instead of just the class name when reporting errors for unbacked enums, which ensures proper error reporting especially in the context of inner classes.

ext/pdo_pgsql/pdo_pgsql_arginfo.h (1)

87-90: Update class registration to use namespaced name structure.

Modified the class registration process to:

  1. Create a zend_namespaced_name structure first
  2. Initialize it with namespace "Pdo" and class name "Pgsql" using INIT_CLASS_NAME_NS
  3. Use the namespaced structure to initialize the class entry

This change aligns with the inner class implementation by ensuring proper namespace handling for class registration.

Zend/Optimizer/zend_optimizer.c (1)

845-845: Correctly updated class name comparison to use the namespaced name

The change from op_array->scope->name to op_array->scope->namespaced_name.name is appropriate for inner class support. This ensures that when checking if a class scope matches the provided lowercase name, the fully qualified name is used.

ext/spl/php_spl.c (1)

633-633: Updated to use namespaced class name in autoloader function list

Good change - this ensures that when reporting autoload functions, the fully qualified class name is used rather than just the unqualified name. This is important for proper identification of class methods used as autoloaders when inner classes are involved.

ext/intl/common/common_date.cpp (2)

127-127: Updated error message to use namespaced class name

This change correctly updates the error message to use the fully qualified class name, ensuring more precise error reporting when dealing with datetime objects.


139-139: Updated object initialization error message to use namespaced class name

Properly updated to show the fully qualified class name in the error message, providing clearer context about which class instance failed initialization.

ext/dl_test/dl_test_arginfo.h (4)

44-47: Updated class registration to use namespaced name structure

This change properly implements the new class registration pattern using the zend_namespaced_name structure and INIT_CLASS_NAME macro before passing it to INIT_CLASS_ENTRY. This is consistent with the inner class support implementation.


56-59: Updated DlTestSuperClass registration to use namespaced name structure

The change consistently applies the new pattern for class registration with proper namespace name initialization.


74-77: Updated DlTestSubClass registration to use namespaced name structure

The implementation properly follows the new pattern for registering classes with support for qualified names.


86-89: Updated DlTestAliasedClass registration to use namespaced name structure

The change consistently implements the new class registration pattern across all class registrations in the file.

ext/com_dotnet/com_persist_arginfo.h (1)

57-60: Class registration code updated for namespaced support.

The introduction of zend_namespaced_name and the updated initialization pattern aligns with the PR's goal of supporting inner classes. This change modifies how class names are handled during registration, ensuring proper support for nested class declarations.

ext/pdo_firebird/pdo_firebird_arginfo.h (1)

17-20: Namespaced PDO class registration implementation looks good.

The implementation correctly uses INIT_CLASS_NAME_NS for namespace handling, which is appropriate since Pdo\Firebird is a namespaced class. This change is consistent with the PR's implementation of improved class name handling to support inner classes.

Zend/Optimizer/ssa_integrity.c (1)

100-100: Error reporting mechanism correctly updated to use namespaced name.

The change properly updates the error reporting in the FAIL macro to use the new namespaced name structure. This ensures that error messages will correctly display the fully qualified name of classes, which is especially important when dealing with inner classes.

ext/zend_test/fiber_arginfo.h (1)

40-43: Test fiber class registration correctly implements namespaced name support.

The implementation follows the same pattern as other class registrations in this PR, using INIT_CLASS_NAME followed by INIT_CLASS_ENTRY with the namespaced name structure. This maintains consistency across the codebase for handling class names, supporting the inner class functionality.

ext/pdo_mysql/pdo_mysql_arginfo.h (1)

17-20: Class Registration Updated for Namespaced Names Support

The code has been refactored to use the new zend_namespaced_name structure instead of the direct namespace and class name strings. This change is part of the inner class implementation, allowing for proper handling of nested class names in error messages and other places throughout the engine.

The two-step approach (INIT_CLASS_NAME_NS followed by INIT_CLASS_ENTRY) replaces the previous single-step approach with INIT_NS_CLASS_ENTRY.

ext/intl/resourcebundle/resourcebundle_class.c (1)

256-256: Updated Error Reporting to Use Namespaced Class Name

The error message for illegal container offset now references object->ce->namespaced_name.name instead of object->ce->name, ensuring the full namespaced class name appears in error messages. This provides more context to the developer when debugging.

ext/mysqli/mysqli_prop.c (3)

40-40: Updated Error Message to Use Namespaced Class Name

Error message for closed MySQL objects now references the namespaced class name, providing better context in error reports.


52-52: Updated Error Message to Use Namespaced Class Name

Error message for closed MySQL result objects now references the namespaced class name, providing better context in error reports.


64-64: Updated Error Message to Use Namespaced Class Name

Error message for closed MySQL statement objects now references the namespaced class name, providing better context in error reports.

ext/intl/collator/collator_arginfo.h (1)

100-103: Class Registration Updated for Namespaced Names Support

The code has been refactored to use the new zend_namespaced_name structure instead of direct class name strings. This allows for proper handling of nested class names throughout the engine.

The two-step approach (INIT_CLASS_NAME followed by INIT_CLASS_ENTRY) provides a more structured way to handle class registration, especially important for inner classes support.

ext/tokenizer/tokenizer.c (1)

106-106: Improved error message with fully qualified class name

The change replaces token_class->name with token_class->namespaced_name.name to ensure that error messages when attempting to instantiate abstract classes include the fully qualified class name (with namespace). This is a consistency improvement as part of the inner class implementation.

ext/session/session.c (1)

2065-2065: Improved class name storage with namespace information

The change updates the assignment to PS(mod_user_class_name) to use Z_OBJCE_P(obj)->namespaced_name.name instead of the previous Z_OBJCE_P(obj)->name. This modification ensures that the stored class name includes full namespace information, which is crucial for the proper functioning of the session handler with inner classes.

ext/xml/xml_arginfo.h (1)

182-185: Update to class registration to support inner classes.

The code has been updated to use the new zend_namespaced_name structure rather than passing the class name string directly. This change is part of the broader RFC implementation to support inner classes in PHP.

ext/spl/spl_observer.c (1)

94-94: Updated error message to use namespaced class name.

The error message now uses intern->std.ce->namespaced_name.name instead of intern->std.ce->name to correctly display class names, including for inner classes.

ext/pdo_dblib/pdo_dblib_arginfo.h (1)

7-10: Updated namespaced class registration to support inner classes.

The class registration has been updated to use a two-step process with zend_namespaced_name:

  1. First initializing the namespaced name structure with INIT_CLASS_NAME_NS
  2. Then using it in the class entry initialization

This change is consistent with the RFC implementation for inner classes and provides better support for class hierarchy.

ext/zend_test/iterators_arginfo.h (1)

22-25: Updated namespaced class registration in test code.

Similar to other changes in this PR, the class registration process has been split into two distinct steps using the new zend_namespaced_name structure:

  1. Initializing the namespaced name with namespace and class name
  2. Using this structure in the class entry initialization

This change ensures that test code is consistent with the new inner class implementation.

ext/mysqli/mysqli_warning.c (3)

147-147: Class name handling updated to support inner classes

The change from obj->zo.ce->name to obj->zo.ce->namespaced_name.name ensures proper display of class names in error messages, particularly for inner/nested classes introduced in this RFC implementation.


167-167: Updated class name reference in error message

Same change as in line 147, ensuring consistent use of namespaced class names in error messages.


187-187: Using namespaced name for error message

Consistent with the other changes in this file, this properly references the full class name including namespace information.

Zend/zend_vm_def.h (21)

3888-3888: Looks correct regarding private constructor checks.
This condition properly blocks access to private constructors outside their scope.


4533-4548: Visibility checks for returned private or protected classes appear correct.
This enforces the new rule that a public method cannot return a private/protected class, aligning with the intended restrictions.


4893-4893: DTrace integration looks good.
Casting to (char *) is typical in this macro usage.


5421-5421: Exception message for non-iterator objects is clear.
No issues found.


5480-5480: By-reference argument warning is appropriate.
This aligns with how unpacking is handled when passing arguments by value instead.


5506-5506: Same by-reference argument warning.
Consistent with the previous logic.


6103-6103: Uncloneable object error is correct.
Properly throws an error if clone_obj is undefined.


6200-6200: Assigning the class name for magic 'class' constant is fine.
The logic to copy ce->namespaced_name.name is straightforward.


6212-6212: Constant access visibility error is consistent.
Using zend_visibility_string for the message is a nice touch.


6257-6257: Error for undefined constant is appropriate.
No issues regarding format or approach.


6425-6425: Non-iterator exception message mirrors previous usage.
Consistently handles objects that fail to create an Iterator.


7407-7407: Readonly property reference error is correct.
Helps ensure that readonly properties are not modified or referenced incorrectly.


8296-8296: New case for ZEND_FETCH_INNER_CLASS in the switch
This simply bypasses further processing and returns the zend_class_entry. Looks good.


8607-8607: Consistent "did not create an Iterator" condition.
Matches identical logic in earlier segments.


8941-8941: Retrieving class name via Z_OBJCE_P(op).
Correctly stores the namespaced class name to the result.


8959-8959: Use of scope->namespaced_name.name for self is valid.
No issues found.


8969-8969: Fetching parent class name is aligned with existing logic.
Well-handled fallback for parent::class.


9588-9588: Deprecated fallback for get_class() without arguments.
Consistent with existing deprecation notices.


9601-9601: Z_OBJCE_P(op1)->namespaced_name.name usage is correct.
Properly returns the object's class name.


9624-9626: Handling EX(This) for get_class($this).
Storing Z_OBJCE(EX(This))->namespaced_name.name or Z_CE(EX(This))->namespaced_name.name is consistent with engine patterns.


9930-9935: Errors for undefined/private properties in parent classes.
Clearly indicates the property cannot be accessed.

ext/dom/nodelist.c (3)

284-284: Error message updated to use namespaced class name.

The error message now uses object->ce->namespaced_name.name instead of what was likely object->ce->name previously. This change improves error reporting by using the fully qualified class name, which provides better context in error messages, especially for classes within namespaces or inner classes.


290-290: Error message updated to use namespaced class name.

Similar to the previous change, this error message now uses the namespaced name for illegal container offset errors, providing more context in error messages by using the fully qualified class name.


305-305: Error message updated to use namespaced class name.

Updated zend_illegal_container_offset to use the namespaced name, maintaining consistency with the other error message changes in this file.

ext/intl/breakiterator/breakiterator_iterators_arginfo.h (1)

22-25: Updated class registration to use namespaced name structure.

The class registration process has been updated to use the zend_namespaced_name structure instead of directly using string literals. This change introduces a more structured approach to handling class names during registration, which is particularly important for supporting inner classes.

The previous approach likely used a direct string literal:

INIT_CLASS_ENTRY(ce, "IntlPartsIterator", class_IntlPartsIterator_methods);

The new approach separates the initialization of the namespaced name from the class entry:

  1. Creates a zend_namespaced_name structure
  2. Initializes it with INIT_CLASS_NAME
  3. Uses it in INIT_CLASS_ENTRY

This change is part of the broader effort to support inner class declarations in PHP.

ext/phar/phar_object.c (1)

1419-1419: Updated error messages to use namespaced_name structure.

The code now consistently references class names via the new namespaced_name.name structure instead of directly using name. This change is made consistently across all error messages in the phar_build function and aligns with the overall modifications to support nested class declarations.

Also applies to: 1430-1430, 1444-1444, 1454-1454, 1471-1471, 1511-1511, 1551-1551, 1571-1571, 1581-1581, 1587-1587, 1604-1604

ext/dom/html_collection.c (3)

104-104: Changed error message to use namespaced class name

The error message now uses the fully qualified class name (object->ce->namespaced_name.name) instead of the local name for better error reporting with inner classes.


110-110: Updated container offset error to use namespaced class name

Error reporting now includes the fully qualified class name, which improves clarity especially when inner classes are involved.


131-131: Updated dimension check error to use namespaced class name

Consistent with other error message changes, this now displays the namespaced class name in error messages for invalid collection offsets.

ext/standard/type.c (2)

64-65: Updated anonymous class name retrieval to use namespaced name

For anonymous classes, the debug type now returns the namespaced name instead of the local name, providing better context in error messages and debugging output.


67-67: Updated class name retrieval to use namespaced name

The get_debug_type function now returns the fully qualified class name, which correctly identifies classes in nested/inner class hierarchies.

ext/dom/parentnode/tree.c (2)

445-445: Updated type error message to use namespaced class name

Error messages for incorrect object types now display the fully qualified class name, improving clarity when inner classes are involved.


454-454: Updated type error message to use namespaced class name for non-object types

Similar to the previous change, this ensures consistent error reporting using fully qualified class names when a non-object type is provided where an object is expected.

ext/xml/xml.c (2)

1176-1176: Updated method existence error to use namespaced class name

The error message for non-existent methods now correctly includes the fully qualified class name, which is essential for identifying classes in a nested class hierarchy.


1201-1201: Updated handler swap error to use namespaced class name

This error message in the handler swap check now uses the namespaced class name, maintaining consistency with other error messages throughout the codebase.

ext/random/engine_mt19937.c (2)

354-354: Good update to error message using namespaced name

The error message has been updated to use engine->std.ce->namespaced_name.name instead of what was likely engine->std.ce->name before. This change properly supports the inner class implementation by ensuring error messages display the fully qualified class name, which will be more informative when inner classes are involved.


361-361: Consistent error message format updates

These changes consistently apply the same pattern across all exception messages in the unserialize method, updating them to use the namespaced class name. This ensures uniform error reporting throughout the code and properly handles inner classes in error messages.

Also applies to: 366-366, 373-373, 377-377

ext/xmlwriter/php_xmlwriter_arginfo.h (1)

485-489: Good implementation of namespaced class name initialization

The changes properly implement the new approach for class registration by:

  1. Adding a zend_namespaced_name namespaced_name variable
  2. Initializing it with INIT_CLASS_NAME(namespaced_name, "XMLWriter")
  3. Using it in INIT_CLASS_ENTRY(ce, namespaced_name, class_XMLWriter_methods)

This modification is necessary to support inner classes and provides a more structured way to handle class names in the registration process.

ext/tokenizer/tokenizer_arginfo.h (1)

68-71: Good implementation of namespaced class name initialization

The changes properly implement the new approach for class registration by:

  1. Adding a zend_namespaced_name namespaced_name variable
  2. Initializing it with INIT_CLASS_NAME(namespaced_name, "PhpToken")
  3. Using it in INIT_CLASS_ENTRY(ce, namespaced_name, class_PhpToken_methods)

This modification follows the same pattern seen in other files and is essential for supporting inner classes throughout the codebase.

ext/json/json_arginfo.h (2)

88-91: Good implementation of namespaced class name for JsonSerializable

The changes correctly implement the new approach for interface registration by:

  1. Adding a zend_namespaced_name namespaced_name variable
  2. Initializing it with INIT_CLASS_NAME(namespaced_name, "JsonSerializable")
  3. Using it in INIT_CLASS_ENTRY(ce, namespaced_name, class_JsonSerializable_methods)

This follows the consistent pattern applied throughout the codebase for supporting inner classes.


100-103: Good implementation of namespaced class name for JsonException

The changes correctly implement the new approach for exception class registration by:

  1. Adding a zend_namespaced_name namespaced_name variable
  2. Initializing it with INIT_CLASS_NAME(namespaced_name, "JsonException")
  3. Using it in INIT_CLASS_ENTRY(ce, namespaced_name, NULL)

This consistent implementation ensures that all class types (regular classes, interfaces, and exceptions) properly support inner classes.

ext/curl/curl_file_arginfo.h (2)

57-60: Updated class registration to support namespaced classes

The code now uses the new two-step registration process with INIT_CLASS_NAME followed by INIT_CLASS_ENTRY to properly handle namespaced class names. This change is part of the inner class implementation.


85-88: Updated class registration to support namespaced classes

Similar to the changes above, this properly sets up the namespaced name for the CURLStringFile class using the two-step initialization approach.

main/streams/userspace.c (23)

363-363: Updated error message to use namespaced class names

The error message now references the full namespaced name of the class instead of just the simple name, providing better context in error messages.


439-439: Updated error message to use namespaced class names

Consistently updated the error reporting to use the fully qualified namespaced class name.


595-595: Updated error message to use namespaced class names

Correctly updated the error reporting to use the fully qualified namespaced class name in the error message that reports issues with stream writing.

Also applies to: 602-603


638-638: Updated error message to use namespaced class names

Consistently updated the error messages for stream reading operations to use the fully qualified namespaced class name.

Also applies to: 654-656


680-681: Updated error message to use namespaced class names

Updated the EOF handling error message to use the namespaced class name for better clarity in error reporting.


788-789: Updated error message to use namespaced class names

Updated the stream_tell implementation error message to use the namespaced class name.


855-856: Updated error message to use namespaced class names

Updated the stream_stat implementation error message to use the namespaced class name.


884-885: Updated error message to use namespaced class names

Updated the stream_eof implementation error message to use the namespaced class name.


921-922: Updated error message to use namespaced class names

Updated the stream_lock implementation error message to use the namespaced class name.


954-955: Updated error message to use namespaced class names

Updated the stream_truncate return value error message to use the namespaced class name.


959-960: Updated error message to use namespaced class names

Updated the stream_truncate implementation error message to use the namespaced class name.


1010-1011: Updated error message to use namespaced class names

Updated the stream_set_option implementation error message to use the namespaced class name.


1057-1058: Updated error message to use namespaced class names

Updated the unlink implementation error message to use the namespaced class name.


1097-1098: Updated error message to use namespaced class names

Updated the rename implementation error message to use the namespaced class name.


1139-1140: Updated error message to use namespaced class names

Updated the mkdir implementation error message to use the namespaced class name.


1181-1182: Updated error message to use namespaced class names

Updated the rmdir implementation error message to use the namespaced class name.


1247-1248: Updated error message to use namespaced class names

Updated the metadata implementation error message to use the namespaced class name.


1294-1295: Updated error message to use namespaced class names

Updated the stat_url implementation error message to use the namespaced class name.


1335-1336: Updated error message to use namespaced class names

Updated the dir_read implementation error message to use the namespaced class name.


1412-1413: Updated error message to use namespaced class names

Updated the cast implementation error message to use the namespaced class name.


1423-1424: Updated error message to use namespaced class names

Updated the cast return value error message to use the namespaced class name.


1430-1431: Updated error message to use namespaced class names

Updated the self-cast error message to use the namespaced class name.


493-494: Updated error message to use namespaced class names

Updated the invalid protocol scheme error message to use the namespaced class name for better error reporting.

ext/readline/readline_cli.c (2)

490-491: Updated class name usage in readline completion

Modified the code to use the namespaced class name instead of the simple class name when generating completion suggestions, ensuring proper display of fully qualified class names.


578-582: Updated class name length calculation and formatting

The code now correctly calculates the buffer length based on the namespaced class name length and formats the suggestion string with the fully qualified class name, ensuring proper display of namespaced class names in tab completion.

ext/spl/spl_dllist_arginfo.h (3)

152-155: Updated SplDoublyLinkedList class registration

Modified the class registration to use the two-step process with namespaced names, allowing for proper handling of inner classes and namespaces.


189-193: Updated SplQueue class registration

Modified the SplQueue class registration to use the two-step process with namespaced names, consistent with the inner class implementation.


201-205: Updated SplStack class registration

Modified the SplStack class registration to use the two-step process with namespaced names, maintaining consistency with the implementation of inner classes throughout the codebase.

ext/dba/dba_arginfo.h (1)

111-114: Consistent implementation of namespaced class handling.

The code now uses a structured approach for class registration with zend_namespaced_name, which aligns with the inner class implementation. This change provides proper namespace support for the Dba\Connection class.

ext/pdo/pdo_arginfo.h (1)

17-20: Improved class name handling for PDOException.

The introduction of zend_namespaced_name for PDOException registration is consistent with the architecture changes for inner class support, providing a more structured approach to class registration.

ext/mysqli/php_mysqli_structs.h (5)

185-185: Updated error message to use namespaced class name.

Error reporting now properly uses the namespaced class name structure, which is consistent with the changes for inner class support.


190-190: Updated error message to use namespaced class name.

Error reporting now consistently uses the namespaced class name structure.


199-199: Updated error message to use namespaced class name.

The error message now correctly references the class name through the namespaced name structure.


204-204: Updated error message to use namespaced class name.

Consistent update to error reporting to use the namespaced class name structure.


213-213: Updated error message to use namespaced class name.

Error message for an uninitialized connection object now uses the namespaced class name structure.

ext/zlib/zlib_arginfo.h (2)

233-237: Consistent class name handling for InflateContext.

The implementation uses the zend_namespaced_name structure for class registration, consistent with other changes for inner class support.


245-249: Consistent class name handling for DeflateContext.

The implementation mirrors the changes to InflateContext, using the structured approach with zend_namespaced_name for class registration.

build/gen_stub.php (1)

3383-3394: Improved class name handling with standardized initialization

This change refactors how class names are initialized by introducing a two-step process using zend_namespaced_name. Rather than passing string literals directly to INIT_NS_CLASS_ENTRY or INIT_CLASS_ENTRY, the code now first initializes a namespaced name structure and then uses it for class entry initialization. This standardizes the handling of class names and supports the inner class implementation in the Zend Engine.

ext/sysvmsg/sysvmsg_arginfo.h (1)

77-80: Class registration updated to use namespaced name

The registration of SysvMessageQueue has been updated to use the new zend_namespaced_name structure instead of directly passing a string to INIT_CLASS_ENTRY. This change supports the broader modification for inner class declarations.

ext/session/session_arginfo.h (4)

237-240: Class registration updated for SessionHandlerInterface

Updated the initialization of SessionHandlerInterface to use the new namespaced name structure, supporting inner class functionality.


249-252: Class registration updated for SessionIdInterface

Updated the initialization of SessionIdInterface to use the new namespaced name structure, supporting inner class functionality.


261-264: Class registration updated for SessionUpdateTimestampHandlerInterface

Updated the initialization of SessionUpdateTimestampHandlerInterface to use the new namespaced name structure, supporting inner class functionality.


273-276: Class registration updated for SessionHandler

Updated the initialization of SessionHandler to use the new namespaced name structure, supporting inner class functionality.

ext/spl/spl_fixedarray_arginfo.h (1)

95-98: Class registration updated for SplFixedArray

Updated the initialization of SplFixedArray to use the new namespaced name structure, supporting inner class functionality.

ext/bcmath/bcmath_arginfo.h (1)

200-203: Class registration updated for BcMath\Number with namespace support

Updated the initialization of BcMath\Number to use the new namespaced name structure with INIT_CLASS_NAME_NS specifically for namespace support, which aligns with the broader changes for inner class functionality.

ext/com_dotnet/com_extension_arginfo.h (5)

293-296: LGTM - Support for namespaced class names

This change introduces the zend_namespaced_name variable and updates the class entry initialization to use the namespaced name structure. This is part of the PR's implementation of inner class support.


305-308: LGTM - Consistent pattern for class registration

The changes follow the same pattern as above, using the namespaced name structure for class registration.


318-321: LGTM - Consistent implementation for dotnet class

The pattern is consistently applied to the dotnet class as well.


331-334: LGTM - Consistent implementation for com_safearray_proxy class

Same pattern applied to the com_safearray_proxy class.


343-346: LGTM - Consistent implementation for com_exception class

The namespacing approach is consistently applied to the com_exception class as well.

Zend/zend_string.h (1)

120-120:

✅ Verification successful

Change in pointer handling for string allocation

This change modifies how the allocated memory is treated - instead of casting the result of do_alloca to a zend_string*, it's now dereferencing the pointer as a zend_string**. This suggests a change in the memory layout or pointer management for Zend strings.

Ensure this change doesn't introduce memory management issues or affect string reference counting.


🏁 Script executed:

#!/bin/bash
# Find other code that interacts with ZSTR_ALLOCA_ALLOC to ensure consistency
rg -A 2 -B 2 "ZSTR_ALLOCA_ALLOC" --type c --type h

Length of output: 3417


Attention: Pointer Handling Update Verified

The updated pointer handling in Zend/zend_string.h (line 120) has been confirmed to be consistent across the codebase. The change—from casting the allocation result to a zend_string* to dereferencing as a zend_string**—aligns with its usage in files like zend_API.c, zend_object_handlers.c, ext/standard/browscap.c, and ext/reflection/php_reflection.c. Additionally, the subsequent initialization with GC_SET_REFCOUNT indicates that reference counting is correctly maintained.

No memory management or reference counting issues were detected.

Zend/zend_smart_str.c (3)

40-40: Change in pointer handling for string reallocation

Similar to the change in zend_string.h, this modifies how the reallocated memory is treated for string objects. This is consistent with the other memory management changes.


54-54: LGTM - Consistent change for persistent reallocation

This change is consistent with the earlier change to erealloc2, now applied to perealloc for persistent memory.


231-231: Updated to use namespaced class names

Changed to use the new namespaced_name.name structure instead of just the class name. This ensures that class name output in string operations includes the full namespaced path, which is essential for inner classes.

ext/gmp/gmp_arginfo.h (1)

334-337: LGTM - Consistent implementation for GMP class

The changes follow the same pattern as other files, using the namespaced name structure for class registration. This ensures consistent handling of class names throughout the codebase.

ext/xmlreader/php_xmlreader.c (3)

204-204: Updated error message to use namespaced class name

The change uses object->ce->namespaced_name.name instead of object->ce->name in the error message when a readonly property modification is attempted. This ensures that the error message includes the fully namespaced class name, which is more accurate and helps users identify the exact class causing the error.


217-218: Updated error message to use namespaced class name

Similar to the previous change, this error message now uses the namespaced class name when reporting that a property cannot be unset. This provides more accurate error reporting, especially for classes within namespaces.


1302-1302: Updated error message to use namespaced class name

The error message in the expand method now uses the namespaced class name instead of just the class name, which improves error clarity when dealing with namespaced classes.

Zend/Optimizer/zend_dump.c (3)

224-227: Updated class name display in type information

Modified the output to display the class's namespaced name instead of just the name when showing instanceof relationships. This provides more accurate and complete type information in debug output.


359-362: Updated class name display in object type information

Similar to the previous change, this modification ensures the full namespaced class name is displayed when showing object type information, making debug output more accurate and complete.


934-936: Updated op_array name display to use namespaced class name

Modified the function to use the namespaced name when printing the scope of the function, ensuring that the full namespace context is represented in the output. This is particularly important for functions defined within namespaced classes.

ext/random/random_arginfo.h (10)

248-251: Added namespaced name support to Mt19937 class registration

The class registration has been updated to use a two-step process: first initializing the namespaced name structure, then using it to initialize the class entry. This change is part of the broader effort to properly support inner classes and namespaces.

Also applies to: 262-264


260-264: Added namespaced name support to PcgOneseq128XslRr64 class registration

Similar to the previous change, the class registration now properly handles namespaced names using the new approach.


273-277: Added namespaced name support to Xoshiro256StarStar class registration

Class registration updated to use the namespaced name structure for proper namespace handling.


286-290: Added namespaced name support to Secure class registration

Updated to use the namespaced name structure for improved namespace handling.


299-303: Added namespaced name support to Engine class registration

Updated the interface registration to use the namespaced name structure.


311-315: Added namespaced name support to CryptoSafeEngine class registration

Modified the interface registration to properly handle namespaced names.


324-328: Added namespaced name support to Randomizer class registration

Updated the class registration to use the namespaced name structure.


358-362: Added namespaced name support to RandomError class registration

Updated the error class registration to use the namespaced name structure.


370-374: Added namespaced name support to BrokenRandomEngineError class registration

Modified the error class registration to properly handle namespaced names.


382-386: Added namespaced name support to RandomException class registration

Updated the exception class registration to use the namespaced name structure.

ext/hash/hash_arginfo.h (1)

250-254: Added namespaced name support to HashContext class registration

The HashContext class registration has been updated to use the namespaced name structure. Unlike the Random classes, this uses INIT_CLASS_NAME instead of INIT_CLASS_NAME_NS since HashContext isn't in a namespace.

ext/libxml/libxml.c (2)

1278-1278: Use of namespaced_name.name appears correct.

This change replaces the previous usage of ce->name with ce->namespaced_name.name for registering export functions in the hash table. This is consistent with the broader refactoring to support inner classes across the codebase.


1292-1292: Consistent usage of namespaced_name.name for lookup.

The change from using ce->name to ce->namespaced_name.name for hash lookup ensures proper function handler retrieval, maintaining consistency with the registration change above.

ext/spl/spl_observer_arginfo.h (4)

236-240: Proper refactoring for inner class support.

The introduction of zend_namespaced_name and the two-step initialization process (first setting up the namespaced name, then the class entry) correctly implements the required changes for inner class support in the SplObserver class. The changes maintain the original functionality while enabling the new nested class capabilities.


248-252: Consistent approach for SplSubject registration.

The changes mirror those made for SplObserver, using the same two-step initialization process with the namespaced name structure. This ensures a consistent approach across all class registrations.


260-264: Appropriate modification for SplObjectStorage.

The registration for SplObjectStorage follows the same pattern as the other classes, correctly implementing the inner class support while preserving the existing functionality.


273-277: Consistent implementation for MultipleIterator class.

The registration for MultipleIterator uses the same pattern as the other classes, ensuring a consistent approach throughout the codebase for supporting inner classes.

ext/pdo_odbc/pdo_odbc_arginfo.h (1)

12-16: Proper handling of namespaced class in PDO.

The changes replace the direct namespace class entry initialization (INIT_NS_CLASS_ENTRY) with the new two-step process using INIT_CLASS_NAME_NS and INIT_CLASS_ENTRY. This maintains the original namespace functionality while enabling support for inner classes.

ext/sodium/libsodium_arginfo.h (1)

1147-1153: Good refactoring to support namespaced class registration.

The change replaces the direct string initialization with a two-step process using zend_namespaced_name, which aligns with the PR's objective of supporting inner class declarations in PHP. This structural change maintains the same functionality while providing a more flexible way to handle class names.

ext/dom/node.c (3)

2610-2610: Improved error message with namespaced class name.

The error message now includes the fully qualified class name including namespace, improving clarity when classes with the same name exist in different namespaces.


2617-2617: Enhanced serialization error message with full class name.

The error message now uses the namespaced class name rather than just the simple name, providing better context in the exception message.


2625-2625: Updated unserialization error message with namespaced name.

Similar to the serialization error message, this provides more specific context by using the full namespaced class name in the error message.

ext/sysvshm/sysvshm_arginfo.h (1)

56-60: Updated class registration to support namespaced names.

The class registration process has been modified to use the new zend_namespaced_name structure instead of directly passing a string name. This change is part of the broader support for inner classes in PHP.

The implementation:

  1. Adds a namespaced_name variable
  2. Uses INIT_CLASS_NAME to initialize it with "SysvSharedMemory"
  3. Passes this structure to INIT_CLASS_ENTRY instead of passing the string directly

This change ensures proper handling of the class name in the namespaced context.

ext/spl/spl_directory.c (1)

1372-1372: Update to use namespaced class name in error message

The error message now uses namespaced_name.name instead of just name for class entries, providing the fully qualified class name in error messages. This makes error messages more informative, especially in the context of inner/nested classes.

ext/pdo_sqlite/pdo_sqlite_arginfo.h (1)

59-62: Improve class registration with explicit namespace handling

The class registration now uses a two-step process with a dedicated zend_namespaced_name variable, making the namespace handling more explicit. This modification is part of a broader pattern to better support nested classes throughout the codebase.

ext/spl/spl_heap_arginfo.h (4)

162-165: Enhance class registration for SplPriorityQueue

The class registration now uses a dedicated zend_namespaced_name variable and separates name initialization from class entry initialization, improving structure and supporting the new nested class capabilities.


193-196: Enhance class registration for SplHeap

The class registration code follows the same pattern as SplPriorityQueue, separating namespace name initialization from class entry initialization, which is consistent with the RFC for inner classes.


206-209: Enhance class registration for SplMinHeap

Similar to the other classes, the registration code now uses a dedicated zend_namespaced_name variable, maintaining consistency across the codebase.


218-221: Enhance class registration for SplMaxHeap

The class registration follows the same pattern as the other classes, completing the consistent implementation of the new namespaced class name handling approach.

Zend/zend_attributes_arginfo.h (7)

82-85: Enhance class registration for Attribute class

The class registration code now explicitly uses a zend_namespaced_name variable, separating the name initialization from the class entry initialization. This approach better supports the inner classes feature.


155-158: Enhance class registration for ReturnTypeWillChange

The registration follows the same pattern as the Attribute class, using a dedicated namespaced name variable for more structured handling of class names.


174-177: Enhance class registration for AllowDynamicProperties

Consistent with other attribute classes, the registration now separates name initialization from class entry initialization to better support inner classes.


193-196: Enhance class registration for SensitiveParameter

The registration process continues the pattern established for all other attribute classes, maintaining consistency in the handling of namespaced class names.


212-215: Enhance class registration for SensitiveParameterValue

Like the other attribute classes, this uses the new structured approach to class name handling to support inner class capabilities.


228-231: Enhance class registration for Override

Follows the same pattern as other attribute classes, implementing the changes required for inner class support.


247-250: Enhance class registration for Deprecated

Completes the implementation of the new class registration approach across all attribute classes, ensuring consistent support for inner classes.

ext/sysvsem/sysvsem_arginfo.h (1)

38-41: LGTM - Enhanced class registration to support inner classes

The changes appropriately update the class registration mechanism to use the new namespaced class name structure, which is consistent with the PR's objective of implementing support for inner class declarations.

ext/standard/basic_functions_arginfo.h (2)

4050-4053: Good refactoring to support inner class functionality.

This change implements a two-step process for class name initialization using namespaced_name, which is a key component of the inner class support being added in this PR. The approach separates namespace handling from class entry setup, making the code more flexible.


4066-4069: Consistent implementation of class name handling.

The same pattern of using namespaced_name is applied here, ensuring consistency across class registrations. This modification is necessary to support the inner class feature described in the PR objectives.

ext/xsl/php_xsl_arginfo.h (1)

118-121: Class entry initialization refactored to use namespaced name structure.

The code now uses a two-step process for class entry initialization: first creating a zend_namespaced_name structure, then using it with INIT_CLASS_ENTRY. This change supports the inner class implementation by standardizing class name handling across the codebase.

Zend/zend_iterators.c (1)

59-61: Iterator wrapper class registration now uses namespaced name structure.

The initialization of the iterator wrapper class now follows the new pattern of using a zend_namespaced_name variable instead of a direct string literal. This change maintains consistency with the new class registration approach throughout the codebase to support inner classes.

ext/odbc/odbc_arginfo.h (2)

479-482: Updated class registration for Odbc\Connection to use namespaced name.

The ODBC Connection class registration now uses the zend_namespaced_name structure with INIT_CLASS_NAME_NS, properly separating the namespace ("Odbc") from the class name ("Connection"). This standardized approach will help with inner class support.


491-494: Updated class registration for Odbc\Result to use namespaced name.

Similar to the Connection class, the Result class registration now uses the structured approach with zend_namespaced_name and INIT_CLASS_NAME_NS. This consistent implementation across namespaced classes is important for the inner class functionality.

ext/snmp/snmp_arginfo.h (2)

267-270: SNMP class registration refactored to use namespaced name.

The SNMP class registration now follows the standardized pattern using zend_namespaced_name with INIT_CLASS_NAME, ensuring consistent class name handling that will be necessary for inner class support.


399-402: SNMPException class registration updated to use namespaced name.

The SNMPException class registration has been updated to use the zend_namespaced_name structure, maintaining consistency with the other class registration changes across the codebase.

ext/fileinfo/fileinfo_arginfo.h (2)

104-104: Addition of namespaced name variable for class registration

The zend_namespaced_name namespaced_name variable is added to properly support the new class naming structure for inner classes.


106-107: LGTM: Two-step class initialization for inner class support

The change replaces direct string initialization with a two-step process:

  1. Initialize the namespaced name structure
  2. Initialize the class entry using that structure

This modification is part of the broader inner class implementation, enabling proper class naming and scope handling.

ext/standard/dir_arginfo.h (2)

59-59: Addition of namespaced name variable for Directory class

The zend_namespaced_name namespaced_name variable is added to properly support the new class naming structure for inner classes.


61-62: LGTM: Two-step class initialization for inner class support

The class registration now properly uses the namespaced name structure instead of a direct string literal, following the same pattern applied consistently throughout the codebase to support inner classes.

ext/tidy/tidy_arginfo.h (4)

527-527: Addition of namespaced name variable for tidy class registration

The zend_namespaced_name namespaced_name variable is added to properly support the new class naming structure for inner classes.


529-530: LGTM: Two-step class initialization for inner class support

The class registration correctly implements the new pattern for class initialization using the namespaced name structure.


549-549: Addition of namespaced name variable for tidyNode class registration

The zend_namespaced_name namespaced_name variable is added to properly support the new class naming structure for inner classes.


551-552: LGTM: Two-step class initialization for inner class support

The class registration correctly implements the new pattern for class initialization using the namespaced name structure.

Zend/zend_operators.c (3)

236-236: Updated error message to use namespaced class name

This change improves error reporting by using the namespaced class name in the error message instead of just the class name. This is important for the new inner class implementation as it will show the full class path when an object cannot be converted to the specified type.


768-768: Enhanced error reporting with namespaced class name

Similar to the previous change, this modification ensures that error messages display the fully namespaced class name when an object cannot be converted to a string, providing more context for debugging, especially with nested classes.


2851-2851: Improved error message with namespaced class name

This change updates the recoverable error message to include the namespaced class name when an object cannot be converted to a boolean value. This is consistent with the other changes in this file and provides more precise error reporting when working with inner classes.

ext/libxml/libxml_arginfo.h (1)

106-109: LGTM: Refactored class registration to support inner classes.

The changes properly introduce a zend_namespaced_name variable and modify the class registration process to use a two-step approach:

  1. Initialize the namespaced class name with INIT_CLASS_NAME
  2. Pass that namespaced name to INIT_CLASS_ENTRY

This change is consistent with the inner class support implementation described in the PR objectives.

Zend/zend_interfaces_arginfo.h (8)

123-126: LGTM: Updated class registration for Traversable interface.

The modification correctly replaces direct string literal registration with a namespaced approach, enabling proper inner class support.


135-138: LGTM: Updated class registration for IteratorAggregate interface.

The implementation follows the same pattern of using zend_namespaced_name for class registration, ensuring consistency across the codebase.


148-151: LGTM: Updated class registration for Iterator interface.

The change properly implements the namespaced name approach for the Iterator interface, maintaining the same pattern as the other interfaces.


161-164: LGTM: Updated class registration for ArrayAccess interface.

The implementation correctly follows the established pattern for handling class names with the new namespaced approach.


173-176: LGTM: Updated class registration for Serializable interface.

The changes maintain consistency with the other interface registrations by using the same namespaced name approach.


185-188: LGTM: Updated class registration for Countable interface.

The implementation correctly introduces the namespaced name variable and initializes it properly for class registration.


197-200: LGTM: Updated class registration for Stringable interface.

The change follows the established pattern for using namespaced names in class registration, ensuring consistent implementation.


209-212: LGTM: Updated class registration for InternalIterator.

The implementation correctly applies the same namespaced name approach to a concrete class, showing the pattern works for both interfaces and regular classes.

ext/spl/spl_directory_arginfo.h (7)

485-488: LGTM: Updated class registration for SplFileInfo.

The implementation correctly follows the established pattern of using zend_namespaced_name for class registration.


506-509: LGTM: Updated class registration for DirectoryIterator.

The changes maintain consistency with the other class registrations by following the same approach for namespaced names.


519-522: LGTM: Updated class registration for FilesystemIterator.

The implementation correctly introduces the namespaced name variable and initializes it properly for the FilesystemIterator class.


603-606: LGTM: Updated class registration for RecursiveDirectoryIterator.

The changes follow the same pattern established for all other classes in this PR, ensuring consistency across the codebase.


617-620: LGTM: Updated class registration for GlobIterator.

The implementation properly applies the namespaced name approach to the conditional GlobIterator class, keeping consistent with the rest of the changes.


631-634: LGTM: Updated class registration for SplFileObject.

The changes maintain the consistent pattern of using namespaced names for all class registrations.


668-671: LGTM: Updated class registration for SplTempFileObject.

The implementation correctly applies the same namespaced name approach to the SplTempFileObject class, completing the consistent application of this pattern throughout the file.

ext/spl/spl_iterators.c (11)

520-520: Updated class name reference in exception message

The code now uses ce->namespaced_name.name instead of the previous ce->name to provide the fully qualified class name in the exception message. This change is part of broader support for inner/nested classes.


900-900: Updated error message to use namespaced class name

The code now references the fully qualified class name with namespaced_name.name in the error message, improving clarity when working with potentially nested or namespaced classes.


1246-1246: Improved class name reference in exception message

Updated to use the fully qualified namespaced class name in the exception message thrown when derived classes fail to call parent constructors.


1277-1277: Updated class name reference in exception message

Modified to use the class's namespaced name, providing better context in error messages, especially useful when working with nested classes.


2393-2394: Updated exception message with namespaced class name

Error message in CachingIterator::__toString now shows the fully qualified class name, which improves clarity when debugging issues, especially in namespace contexts.


2427-2428: Updated class name reference in exception message

Modified to use namespaced_name.name to show the fully qualified class name in the exception, consistent with the inner class support pattern.


2450-2451: Updated class name in exception message

Error message now uses the namespaced class name for improved clarity, especially useful when working with nested or namespaced classes.


2476-2477: Updated class name reference in exception message

Improved error message by using the fully qualified class name, providing better context for debugging.


2497-2498: Updated class name reference in exception message

Now using namespaced class name in the error message for better identification of classes, especially in complex inheritance hierarchies.


2515-2516: Updated class name reference in exception message

Changed to use the fully qualified class name in the exception message thrown when attempting to access the cache without proper configuration.


2580-2581: Updated class name reference in exception message

Modified to use the class's namespaced name, providing better identification in error messages when the count operation is performed without a full cache.

ext/shmop/shmop_arginfo.h (1)

71-74: Updated class registration to support namespaced names

The class registration pattern has been modified to use the new two-step initialization process with zend_namespaced_name:

  1. First initializing the namespaced name structure
  2. Then using that structure to initialize the class entry

This change is part of the implementation for inner/nested class support, making class name handling more consistent throughout the codebase.

ext/pdo/pdo_dbh_arginfo.h (1)

108-111: Appropriate change to support inner classes

The addition of zend_namespaced_name and the use of INIT_CLASS_NAME macro is consistent with the PR's objective to implement inner class support. This change properly modifies the class registration mechanism to work with the new namespaced class name structure instead of using string literals directly.

ext/zip/php_zip_arginfo.h (1)

581-584: Appropriate change to support inner classes

The addition of zend_namespaced_name and the use of INIT_CLASS_NAME macro aligns with the PR's implementation of inner class support. This change correctly updates the class registration mechanism to use the namespaced class name structure instead of direct string literals.

ext/zip/php_zip.c (1)

921-921: Improved error message with full class name

Good change to use the namespaced class name (object->ce->namespaced_name.name) in the error message instead of just the class name. This will provide more accurate and helpful error messages when classes with the same name exist in different namespaces or inner classes.

ext/curl/curl_arginfo.h (4)

1129-1132: Updated class registration to support namespaced class names

The registration of CurlHandle class has been modified to use the new zend_namespaced_name structure and the updated initialization pattern with INIT_CLASS_NAME followed by INIT_CLASS_ENTRY. This change is part of the overall implementation for inner class support.


1141-1144: Consistent use of namespaced class initialization for CurlMultiHandle

The class registration for CurlMultiHandle follows the same pattern as the other classes, ensuring consistency across all curl handle classes.


1153-1156: Same pattern applied to CurlShareHandle

The registration for CurlShareHandle also adopts the new namespaced class name initialization pattern.


1165-1168: Applied namespaced class initialization to CurlSharePersistentHandle

The CurlSharePersistentHandle class registration now uses the same two-step process with zend_namespaced_name structure, completing the update across all curl-related classes.

ext/gd/gd_arginfo.h (2)

969-972: Updated GdImage class registration to use namespaced names

The registration of the GdImage class now uses the new zend_namespaced_name structure and initialization pattern. This is consistent with the changes made to other class registrations and supports the implementation of inner classes.


981-984: Applied namespaced class initialization to GdFont class

The GdFont class registration follows the same pattern as the GdImage class, ensuring consistency in the implementation of the namespaced class names feature.

ext/sqlite3/sqlite3_arginfo.h (4)

291-294: Clean refactoring of class name handling for SQLite3Exception

The changes replace direct string usage with a structured approach using zend_namespaced_name, facilitating support for inner classes by improving class name handling.


303-306: Clean refactoring of class name handling for SQLite3

The updated class registration pattern correctly uses the new namespaced approach, maintaining consistency with the refactoring pattern across the codebase.


539-542: Clean refactoring of class name handling for SQLite3Stmt

The implementation follows the same pattern consistently, properly initializing the namespaced name structure before class registration.


551-554: Clean refactoring of class name handling for SQLite3Result

The change consistently applies the same pattern for handling class names, completing the refactoring of all SQLite3-related class registrations.

ext/mysqli/mysqli.c (10)

268-268: Updated error message to use namespaced class name

Error message properly references the namespaced class name for better diagnostics with inner classes.


379-379: Updated property handler lookup to use namespaced class name

Property handler lookup now correctly uses the namespaced class name structure, ensuring compatibility with inner classes.


414-414: Updated closed object error message to use namespaced class name

Error message for a closed object now references the proper namespaced class name.


508-508: Updated hash table key for mysqli_driver class properties

Property handler registration now uses namespaced class name for consistency with inner class support.


514-514: Updated hash table key for mysqli_link class properties

Consistent update to use namespaced class name for mysqli_link class properties.


520-520: Updated hash table key for mysqli_warning class properties

Properly updated to use namespaced class name structure for mysqli_warning.


527-527: Updated hash table key for mysqli_result class properties

Consistent application of the namespaced class name pattern for mysqli_result.


533-533: Updated hash table key for mysqli_stmt class properties

Completed the refactoring for all mysqli classes by updating mysqli_stmt to use namespaced class names.


762-762: Updated instantiation error message to use namespaced class name

Error message for class instantiation issues now references the proper namespaced class name.


809-809: Updated constructor parameter error message to use namespaced class name

Error message for constructor parameter issues now uses the namespaced class name for better diagnostics.

ext/spl/spl_functions.c (3)

29-33: Updated class name handling in hash operations

Hash lookup and insertion operations now correctly use the namespaced class name structure, ensuring proper functionality with inner classes.


56-58: Updated trait name resolution for better compatibility

Changed to use trait_names[num_traits].resolved_name instead of .name, providing more robust trait resolution that's needed for inner class support.


89-91: Updated property name mangling to use namespaced class names

Property name mangling now correctly uses the namespaced class name structure, ensuring proper property naming with inner classes.

ext/sockets/sockets_arginfo.h (2)

1116-1119: Updated Socket class registration to use namespaced approach

Changed from direct string usage to the structured approach with namespaced_name, maintaining consistency with the codebase-wide refactoring pattern.


1128-1131: Updated AddressInfo class registration to use namespaced approach

Applied the same namespaced class name pattern consistently to the AddressInfo class registration.

ext/spl/spl_iterators_arginfo.h (20)

606-609: Implementation adds namespaced class name support for EmptyIterator

The code now uses the new zend_namespaced_name structure to properly handle class naming, which is necessary for supporting inner classes. This change is consistent with the PR objectives for adding inner class support to PHP.


619-622: Implementation adds namespaced class name support for CallbackFilterIterator

The modification follows the same pattern as other classes, using the INIT_CLASS_NAME and INIT_CLASS_ENTRY macros with the namespaced name structure.


631-634: Implementation adds namespaced class name support for RecursiveCallbackFilterIterator

This change properly implements the namespaced class name handling required for inner classes.


644-647: Implementation adds namespaced class name support for RecursiveIterator

The interface registration now correctly uses the namespaced name structure.


657-660: Implementation adds namespaced class name support for RecursiveIteratorIterator

The change is consistent with the overall implementation pattern for handling namespaced class names.


694-697: Implementation adds namespaced class name support for OuterIterator

The interface registration correctly implements the namespaced name structure.


707-710: Implementation adds namespaced class name support for IteratorIterator

This change follows the established pattern for namespaced class name support.


720-723: Implementation adds namespaced class name support for FilterIterator

The abstract class registration is correctly updated to use the namespaced name structure.


732-735: Implementation adds namespaced class name support for RecursiveFilterIterator

The abstract class registration properly implements the namespaced name handling.


745-748: Implementation adds namespaced class name support for ParentIterator

This change is consistent with the pattern used throughout the file.


757-760: Implementation adds namespaced class name support for SeekableIterator

The interface registration correctly implements the namespaced name structure.


770-773: Implementation adds namespaced class name support for LimitIterator

The class registration is correctly updated to use the new namespaced name structure.


782-785: Implementation adds namespaced class name support for CachingIterator

This change properly implements namespaced class name handling for the CachingIterator class.


831-834: Implementation adds namespaced class name support for RecursiveCachingIterator

The class registration correctly uses the namespaced name structure.


844-847: Implementation adds namespaced class name support for NoRewindIterator

This change follows the established pattern for namespaced class name handling.


856-859: Implementation adds namespaced class name support for AppendIterator

The class registration correctly implements the namespaced name structure.


868-871: Implementation adds namespaced class name support for InfiniteIterator

This change properly implements the namespaced class name handling for InfiniteIterator.


880-883: Implementation adds namespaced class name support for RegexIterator

The class registration correctly uses the namespaced name structure.


940-943: Implementation adds namespaced class name support for RecursiveRegexIterator

This change follows the established pattern for namespaced class name support.


953-956: Implementation adds namespaced class name support for RecursiveTreeIterator

The class registration properly implements the namespaced name structure, completing the updates for all iterator classes.

Zend/zend_interfaces.c (8)

61-61: Error message updated to use namespaced class name

The error message now uses obj_ce->namespaced_name.name instead of obj_ce->name to display the full namespaced class name in error messages, which provides more context for debugging.


247-247: Exception message updated to use namespaced class names

The exception message in zend_user_it_get_new_iterator now properly uses the namespaced class name for both direct class entries and object class entries.


278-282: Error messages in traversable implementation check updated

The error messages in zend_implement_traversable now use the namespaced name properties of all class entries involved, providing more accurate context in error messages.


292-293: Error message in aggregate implementation check updated

The error message in zend_implement_aggregate now correctly uses the namespaced class name.


334-335: Error message in iterator implementation check updated

The error message in zend_implement_iterator now correctly uses the namespaced class name when reporting that a class cannot implement both Iterator and IteratorAggregate.


435-437: Serialization error message updated for namespaced class names

The exception message in zend_user_serialize now uses the namespaced class name when reporting that the serialize method must return a string or NULL.


480-480: Deprecation notice updated to use namespaced class name

The deprecation message in zend_implement_serializable now correctly uses the namespaced class name when warning about the deprecated Serializable interface.


482-483: Uncaught error message updated to use namespaced class name

The uncaught error message during inheritance in zend_implement_serializable now correctly uses the namespaced class name.

ext/pgsql/pgsql_arginfo.h (3)

1149-1152: Refactoring the class registration process to better support inner classes.

The change correctly implements the two-step initialization process for namespaced classes, which is part of the broader effort to support inner class declarations in PHP. The zend_namespaced_name structure is now used to explicitly store the namespace and class name information before initializing the class entry.


1161-1164: Consistent implementation of the namespaced class registration pattern.

The changes follow the same pattern as in the Connection class, maintaining consistency across all PostgreSQL classes. This aligns well with the PR's objective of supporting nested class declarations.


1173-1176: Completing the refactoring pattern for the third PostgreSQL class.

The Lob class registration completes the standardized approach to class name handling across all three PostgreSQL classes. This consistent implementation ensures that all classes will work properly with the new inner class support being added to the engine.

ext/spl/spl_array.c (11)

446-446: Consistent class name usage for error messaging.

The change from object->ce->name to object->ce->namespaced_name.name ensures proper display of class names in error messages, which is particularly important for nested classes.


523-523: Updated class name reference for error handling.

Correctly using the namespaced class name in the zend_illegal_container_offset call for better error reporting.


568-568: Consistent error handling for container offsets.

Similar to previous changes, updates the class name reference to use namespaced name.


640-640: Updated class name reference for illegal offset errors.

Consistently using namespaced class name for error reporting.


721-721: Enhanced error message clarity with fully qualified class name.

Using the namespaced class name in error messages improves clarity, especially when working with nested class structures.


875-875: Updated property pointer access with namespaced class name.

Consistently using the namespaced class name in the dimension pointer lookup.


1003-1003: Improved error message for incompatible types.

Updated to use the namespaced class name in the error message for better user experience.


1010-1010: Enhanced error message for enum compatibility.

Consistently using the namespaced class name in error messaging.


1084-1085: Updated iterator class name handling.

The change ensures the correct namespaced class name is returned from getIteratorClass().


1464-1464: Consistent class name handling in serialization.

Using namespaced class name when serializing iterator class information.


1614-1614: Enhanced error message for readonly properties.

Updated to use the namespaced class name in the error message about readonly properties.

ext/standard/var.c (8)

167-167: Improved enum display with namespaced class name.

Updated the output format for enum types to use the fully qualified class name.


617-617: Enhanced var_export with properly namespaced class names.

Using the namespaced class name when exporting object data improves clarity and correctness.


839-839: Improved error message for __sleep() method.

Updated error message to use the namespaced class name for better error reporting.


861-861: Enhanced error handling for __serialize() method.

Using the namespaced class name in the type error message provides better context.


917-917: Consistent error messaging in sleep property handling.

Updated to use the namespaced class name in warning messages about __sleep() return values.


933-934: Updated property name mangling with namespaced class name.

The change to use namespaced class name in property name mangling ensures proper handling of properties in nested classes.


1119-1119: Improved serialization error messages.

Updated error message for non-serializable classes to use the fully qualified class name.


1184-1185: Updated serialization handling for custom serializers.

Consistently using the namespaced class name in string formatting and memory calculations during serialization.

Also applies to: 1188-1188, 1192-1192

ext/standard/var_unserializer.re (7)

551-551: Updated class name access for property visibility check.

The code is now using ce->namespaced_name.name instead of ce->name for checking class name matches, which aligns with the inner class implementation where class names need to properly handle namespacing.


565-565: Updated class name reference in error message.

The error message now refers to existing_propinfo->ce->namespaced_name.name instead of existing_propinfo->ce->name, ensuring proper class name representation in error messages for virtual property unserialization failures.


645-645: Updated class name in dynamic property error message.

The error message now uses obj->ce->namespaced_name.name instead of obj->ce->name, ensuring proper class name representation when dynamic properties cannot be created.


650-650: Updated class name in deprecation notice.

The deprecation notice now uses obj->ce->namespaced_name.name instead of obj->ce->name, ensuring proper class name representation when warning about dynamic property creation.


774-774: Updated class name in unserializer warning.

The warning message now uses ce->namespaced_name.name instead of ce->name, ensuring proper class name representation when a class lacks an unserializer.


1283-1283: Updated class name in exception message.

The exception message now uses ce->namespaced_name.name instead of ce->name, ensuring proper class name representation when unserialization is not allowed.


1331-1331: Updated class name in data format error message.

The error message now uses ce->namespaced_name.name instead of ce->name, ensuring proper class name representation when reporting erroneous data format for unserialization.

ext/mysqli/mysqli_arginfo.h (6)

1195-1198: Added namespaced class name support in mysqli_driver registration.

Introduced zend_namespaced_name structure and updated class registration to use INIT_CLASS_NAME and the namespaced name structure instead of directly using string literals, which supports the inner class implementation.


1231-1234: Added namespaced class name support in mysqli class registration.

Using the namespaced name structure in class registration to properly handle class name representation, which is required for inner classes to work correctly.


1420-1423: Added namespaced class name support in mysqli_result class registration.

Using the namespaced name structure in class registration to properly handle class name representation, maintaining consistency with the inner class implementation.


1461-1464: Added namespaced class name support in mysqli_stmt class registration.

Using the namespaced name structure in class registration to properly handle class name representation, maintaining consistency with the inner class implementation.


1533-1536: Added namespaced class name support in mysqli_warning class registration.

Using the namespaced name structure in class registration to properly handle class name representation, maintaining consistency with the inner class implementation.


1561-1564: Added namespaced class name support in mysqli_sql_exception class registration.

Using the namespaced name structure in class registration to properly handle class name representation, maintaining consistency with the inner class implementation.

ext/soap/soap_arginfo.h (8)

321-324: Good implementation of namespaced class name handling

This change replaces the direct string reference with a structured approach using zend_namespaced_name, which is part of the broader changes to support inner class declarations.


333-336: Consistent implementation of namespaced class name handling

The introduction of the namespaced_name variable and the two-step initialization process is consistent with the changes made to other class registrations in this file.


345-348: Proper use of new INIT_CLASS_NAME macro

The change properly initializes the namespaced_name variable with the class name and then uses it for class entry initialization, following the same pattern as other class registrations.


369-372: Consistent handling of class name initialization

This change is part of the systematic update to support structured namespaced class names throughout the codebase.


409-412: Correct implementation for class that extends Exception

The change correctly maintains the inheritance relationship while updating to the new namespaced name structure.


463-466: Consistent implementation for SoapVar class registration

Following the same pattern as other classes, properly initializing the namespaced name before class entry.


511-514: Proper handling of SoapServer class registration

This change is consistent with the pattern used throughout the file and properly initializes the class with the new namespaced name approach.


530-533: Consistent implementation for SoapClient class

The change follows the systematic approach used throughout the codebase for updating class registrations to support inner classes.

ext/spl/spl_array_arginfo.h (3)

260-263: Good implementation of namespaced name handling for ArrayObject

The introduction of zend_namespaced_name and the two-step initialization process follows the same pattern used in other files to support inner class declarations.


285-288: Consistent implementation for ArrayIterator class

This change properly replaces the direct string reference with the structured approach using zend_namespaced_name, maintaining consistency with other class registrations.


310-313: Proper implementation for RecursiveArrayIterator class

The change correctly maintains the inheritance from ArrayIterator while updating to the new namespaced name structure.

Zend/zend_vm_execute.h (102)

2394-2394: Usage of ce->namespaced_name.name in the error message is consistent and clear.


2453-2453: Referencing the namespaced class name for argument warnings ensures accurate diagnostics.


2479-2479: Consistent approach for referencing the scope’s namespaced name in warnings.


2774-2774: Aligning the iterator error message with ce->namespaced_name.name is a good practice.


3313-3313: Introducing ZEND_FETCH_INNER_CLASS case cleanly integrates inner class support.


5011-5011: DTrace hook now uses the namespaced name—consistent with the rest of the changes.


5125-5125: Error message switched to namespaced_name, maintaining uniformity.


5840-5840: Iterator creation error referencing the namespaced class name looks correct.


6624-6632: Suspicious if (IS_CONST == IS_CONST) and else if (IS_CONST == IS_UNUSED) condition.
This check is always true and prevents intended branching. Use opline->op1_type instead, for example:

- if (IS_CONST == IS_CONST) {
- } else if (IS_CONST == IS_UNUSED) {
+ if (opline->op1_type == IS_CONST) {
+ } else if (opline->op1_type == IS_UNUSED) {

6628-6688: New inner class visibility checks (private/protected) appear logically correct.


7475-7475: Matching private constructor call error message with namespaced_name is consistent.


7706-7706: Using namespaced_name.name for the “class” magic constant is properly unified.


7718-7725: Updated error messages now accurately reference the namespaced constant or trait.


7763-7763: Consistent undefined constant error, referencing ce->namespaced_name.name.


8866-8866: ‘class’ magic constant handling with namespaced_name is correct.


8878-8885: Proper trait/constant access checks with updated naming.


8923-8923: Undefined constant error usage is properly updated.


10049-10049: Private constructor error message referencing the namespaced class is accurate.


10807-10807: Consistent usage of ce->namespaced_name.name for private constructor checks.


10905-10921: The return-type enforcement for private/protected inner classes is well-structured.


11499-11499: Deprecation notice referencing scope’s namespaced name is coherent.


11512-11512: Ensuring ZVAL_STR_COPY(..., Z_OBJCE_P(op1)->namespaced_name.name) is consistent.


11645-11650: Property access errors with updated namespaced class references are correct.


12559-12559: Private constructor call check now references the fully qualified class name.


15400-15400: Cloning error message referencing namespaced class is uniform with other changes.


15566-15566: Iterator creation error with namespaced_name is consistent.


15727-15727: Storing the class name in a result var for get_class() is correct.


15745-15745: Adding a case for ZEND_FETCH_INNER_CLASS to handle scope’s namespaced name.


15755-15755: Uses parent’s namespaced name for fetch—consistent solution.


16261-16305: Suspicious condition if ((IS_TMP_VAR|IS_VAR) == IS_CONST) / else if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED)
Replace with checks against opline->op1_type to avoid always-true or always-false branches.


16306-16351: Inner class fetch logic and visibility checks for tmpvar-based outer classes look solid.


19094-19094: Using ce->namespaced_name.name in deprecation notice affirms consistency.


19107-19107: Correctly retrieving the namespaced_name from an object’s class.


21762-21779: Return-type checks for public/protected methods returning private classes maintain encapsulation.


23414-23414: Read-only property reference error updated with namespaced class name.


25715-25715: Private constructor call detection with namespaced_name is accurate.


26103-26103: Class-level magic constant references are consistently using namespaced_name now.


26115-26122: Trait constant access errors referencing updated class name.


26160-26160: Undefined constant notice referencing the namespaced class is correct.


26672-26672: Namespaced_name usage for the 'class' magic constant remains consistent.


26684-26691: Error messages for trait constants with the namespaced_name are aligned with the new pattern.


26729-26729: Undefined constant error referencing the namespaced class name.


28648-28648: Private constructor call check updated with namespaced_name.


30158-30158: Consistent approach for private constructor calls in namespaced classes.


30256-30272: Prohibiting public methods from returning private/protected classes ensures correct visibility.


33115-33115: Recognizing private constructor calls with namespaced_name.


33701-33701: Cloning error message uses the updated, fully qualified class name.


33744-33744: Storing the object’s namespaced class name into the result is aligned with the rest of the file.


33762-33762: Fetching scope->namespaced_name.name for ZEND_FETCH_CLASS_SELF or ::parent is correct.


33772-33772: Deriving parent’s namespaced name is consistent with the new scope logic.


34016-34024: Suspicious if (IS_UNUSED == IS_CONST) / else if (IS_UNUSED == IS_UNUSED) conditions.
As before, compare opline->op1_type to IS_CONST/IS_UNUSED to avoid the always-true block.


34025-34106: Inner class resolution for ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_HANDLER follows the same pattern as other fetch handlers.


35488-35488: Keeping the namespaced_name in private constructor error is consistent.


35631-35631: Using ce->namespaced_name.name for 'class' magic constant references.


35643-35650: Access checks on trait constants with updated error messages are standard now.


35688-35688: Undefined constant message now includes the fully qualified class name.


35990-35990: Assigning the class name into the result var is consistent with the new scheme.


36002-36009: Trait constant access errors remain aligned with current approach.


36047-36047: Unified undefined constant handling.


37657-37657: Error for calling private constructors from non-scoped objects is updated.


38068-38068: Again, private constructor error referencing ce->namespaced_name.name is correct.


38166-38182: Visibility checks on return types for public/protected methods look properly enforced.


38534-38534: Return to scope’s namespaced name on get_class() without arguments is coherent.


38547-38547: Retrieving Z_OBJCE_P(op1)->namespaced_name.name streamlines the class name logic.


38570-38572: Preserving the object’s namespaced class name in EX_VAR remains consistent.


40320-40320: Consistent private constructor usage check for namespaced classes.


41323-41323: Error for uncloneable objects includes the fully qualified class.


41919-41919: Accurately referencing class name in iterator creation error.


42080-42080: Copying the namespaced class name to the result variable for dynamic reflection.


42098-42098: scope->namespaced_name.name usage for self references aligns with other handlers.


42108-42108: Inherited parent class name usage is symmetrical with the rest.


50985-51002: Restricting public/protected methods from returning private classes enforces proper encapsulation.


51771-51771: Continuation of deprecation for get_class() with no arguments referencing scope’s name.


51784-51784: Binding the object’s namespaced_name into the result, maintaining consistency.


58043-58046: Duplicate opcode labels ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL may indicate a labeling oversight.


59919-59923: New hybrid-case for ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST is aligned with the added handler.


61194-61198: Hybrid-case for ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST now integrated in the dispatch table.


62787-62791: Including ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST in the hybrid-case ensures completeness.


67250-67254: Repeated references to ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER risk confusion or missing variant coverage.


68212-68212: Adding rule entry 3491 for speculation seems intentional; no immediate issues noted.


68246-68246: Similar rule entry 3491 usage is consistent with the rest of the spec table.


68377-68423: No apparent issues: expanded spec rules referencing 3491 appear systematically inserted.


68595-68595: Use of 2590 in spec rules with SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE is consistent.


68622-68622: Arithmetic spec transitions appear correct (2665, 2690, etc.).


68716-68716: Comparisons extended with SPEC_RULE_SMART_BRANCH; logic remains consistent.


68729-68729: Continuing with new numeric specs for operators looks fine.


68742-68742: Maintaining consistent approach in the extended numeric specs.


68760-68760: Extended pre-increment spec (3425, 3427, etc.) aligns with numeric optimization.


68768-68768: Similar coverage for pre-decrement rules is consistent with the approach.


68775-68775: Post-increment coverage with new spec codes is well-structured.


68782-68782: Post-decrement spec extension likewise matches your numeric optimization pattern.


68789-68789: Specification for conditional jumps (2589) remains consistent.


68794-68794: Handling specialized init_fcall logic with spec 2582 is aligned with others.


68799-68799: Spec 2583 usage for recv not flagged—still consistent.


68804-68804: Send_val optimization with spec 3487 is a coherent extension.


68809-68809: Send_var_ex logic with spec 3482 lines up with previous approach.


68814-68814: FE_FETCH_R with spec 3489 further extends array iteration optimization.


68822-68822: Fetch_dim_r spec 3452 is properly introduced for array referencing.


68827-68827: Send_val_ex logic with spec 3488 is consistent with prior expansions.


68832-68832: Send_var with spec 3477 matches the pattern for zero-latency references.


68837-68837: Count with spec 2584 is a valid extension for array handling.


68882-68882: Additional expansions for bitwise ops appear consistent with the rest.

Zend/zend_API.h (3)

280-280: Macro refactor appears consistent.
No issues found with this direct delegation to INIT_CLASS_ENTRY_EX.


300-300: New macro definition for class entry initialization looks good.
This unified macro simplifies class entry setup. No immediate issues found.


303-303: Assignment of namespaced_name is consistent with prior macros.
Using class_container.namespaced_name = class_name; aligns with the new zend_namespaced_name struct usage. Ensure that the caller has allocated class_name properly to avoid accidental deallocation.

Zend/zend.h (7)

85-88: New enumeration for distinguishing name resolution kinds

This new enum zend_name_resolution_kind is a key addition for supporting inner classes, allowing the engine to differentiate between lexical scope resolution and namespace resolution when resolving class names.


90-98: Well-structured implementation of namespaced names

The new zend_namespaced_name structure elegantly combines the class name, resolved name, resolution kind, and source context (either lexical scope or namespace). This provides the foundation for properly handling inner class relationships.


164-164: Updated class entry structure to use namespaced_name

Replacing the direct name string with a namespaced_name structure enhances the class entry to support inner class semantics while maintaining backward compatibility.


168-169: Updated parent_name to use namespaced_name

This change is consistent with the overall approach of using namespaced_name for class identifiers, allowing parent classes to be properly resolved within inner class contexts.


182-185: Added scope-related members for inner class support

These new members (required_scope, lexical_scope, and required_scope_absolute) provide the essential data structure support for enforcing visibility and access rules for inner classes. The lexical scope allows tracking the containing class of an inner class.


232-233: Updated interface_names to use namespaced_name

Consistent modification to use namespaced_name for interface references, supporting proper resolution of interfaces when used with inner classes.


235-235: Updated trait_names to use namespaced_name

Similar to the interface_names change, this ensures traits are properly resolved in the context of inner classes.

ext/standard/user_filters_arginfo.h (2)

41-44: Updated class registration for php_user_filter

This change implements the new class registration pattern using zend_namespaced_name, aligning with the structural changes in core. The two-step initialization process with INIT_CLASS_NAME followed by INIT_CLASS_ENTRY ensures proper handling of class names within the new system.


71-75: Updated class registration for StreamBucket

Similar to the php_user_filter changes, this implements the new class registration pattern for StreamBucket, ensuring consistent class handling throughout the codebase.

ext/openssl/openssl_arginfo.h (3)

783-787: Updated OpenSSLCertificate class registration

This change adapts the OpenSSLCertificate class registration to use the new namespaced name approach, following the same pattern as other class registrations in the codebase.


795-799: Updated OpenSSLCertificateSigningRequest class registration

The changes to OpenSSLCertificateSigningRequest's registration follow the consistent pattern of using namespaced names for class registration.


807-811: Updated OpenSSLAsymmetricKey class registration

Consistent with other changes, this updates the OpenSSLAsymmetricKey class registration to use the namespaced name approach.

Zend/zend_exceptions.c (7)

66-68: Updated throwable interface check

This change updates the check for "Exception" and "Error" class names to use namespaced_name.name instead of directly accessing name, maintaining compatibility with the new class entry structure.


78-79: Updated error message for throwable implementation

The error message now correctly references the class and interface names using namespaced_name.name, ensuring proper error reporting when a class incorrectly implements Throwable.


696-697: Updated __toString method to use namespaced_name

This change ensures the exception's class name is retrieved from the namespaced_name.name field rather than the direct name field, adapting the exception string representation to the new class structure.


933-934: Updated warning message for __toString

The warning message about invalid return values from __toString() now uses namespaced_name.name to reference the class name, maintaining consistency with other changes.


951-953: Updated error handling for uncaught exceptions

The error message for uncaught exceptions during toString handling now correctly uses namespaced_name.name from both the caught exception and the original exception class.


973-974: Updated uncaught exception error message

Consistent with other changes, this updates the generic uncaught exception error message to use namespaced_name.name.


799-806: Updated internal exception class initialization

These changes correctly initialize the internal UnwindExit and GracefulExit classes using the new namespaced name approach, ensuring consistency with the rest of the exception handling system.

ext/ffi/ffi_arginfo.h (5)

202-206: Implementation of namespace support for FFI class

The added zend_namespaced_name variable and the two-step initialization with INIT_CLASS_NAME and INIT_CLASS_ENTRY prepares the FFI class for namespace support, which is essential for the inner class implementation. This approach consistently separates namespace handling from class entry initialization.


220-224: Namespace support for FFI_CData class

The change correctly implements namespace handling for the FFI\CData class, using INIT_CLASS_NAME_NS to properly set up the namespaced name with both the namespace "FFI" and the class name "CData" before initializing the class entry.


232-236: Namespace support for FFI_CType class

Similar to the other classes, this change properly implements namespace handling for the FFI\CType class. The modification maintains all the original functionality while supporting the inner class infrastructure.


474-478: Namespace support for FFI_Exception class

The implementation correctly handles the namespace for FFI\Exception while maintaining the inheritance from the Error class. The use of INIT_CLASS_NAME_NS ensures proper namespacing.


486-490: Namespace support for FFI_ParserException class

The changes implement namespace handling for the FFI\ParserException class, maintaining its inheritance from FFI\Exception. The approach is consistent with the other classes in this file.

Zend/zend_lazy_objects.c (4)

238-239: Updated error message to use namespaced class name

The error message now correctly uses the namespaced name of the class, which will provide more precise error information to users, especially when inner classes are involved.


244-246: Enhanced error reporting with namespaced parent class

The error message now includes fully qualified namespaced names for both the class and its parent class, which improves clarity and debugging in error scenarios involving inner classes or namespace hierarchies.


502-503: Improved type error message with namespaced class name

The type error message now uses the fully qualified namespaced name of the class, which will provide better context in error scenarios, particularly with inner classes.


512-513: Enhanced proxy compatibility error with namespaced class name

The error message about real instance and proxy class compatibility now uses the namespaced class name, providing better diagnostics for compatibility issues.

Zend/zend_exceptions_arginfo.h (11)

148-152: Namespace support for Throwable interface

The code now properly handles the Throwable interface with the new namespaced name structure, maintaining the interface implementation while supporting inner class infrastructure.


161-165: Namespace support for Exception class

The Exception class is now properly initialized with the namespaced name structure, which is crucial for the implementation of inner classes. The modification maintains all the original functionality.


203-207: Namespace support for ErrorException class

The change consistently implements the new namespace handling structure for the ErrorException class, ensuring it works correctly within the broader inner class support.


219-223: Namespace support for Error class

The Error class initialization is updated to use the new namespaced name structure, consistent with the pattern used throughout the codebase.


285-289: Namespace support for TypeError class

The TypeError class is properly set up with the namespaced name structure, ensuring consistency with the inner class implementation.


297-301: Namespace support for ArgumentCountError class

The changes correctly implement the namespace handling for ArgumentCountError, maintaining its inheritance from TypeError while supporting inner class functionality.


309-313: Namespace support for ValueError class

The ValueError class initialization is updated to use the new namespaced name structure, consistent with other exception classes.


321-325: Namespace support for ArithmeticError class

The changes properly implement namespace handling for the ArithmeticError class, maintaining its inheritance relationship while supporting inner class functionality.


333-337: Namespace support for DivisionByZeroError class

The DivisionByZeroError class is consistently updated to use the namespaced name structure, ensuring proper integration with the inner class system.


345-349: Namespace support for UnhandledMatchError class

The implementation correctly handles the namespace for UnhandledMatchError while maintaining its inheritance from Error. The approach is consistent with other classes.


357-361: Namespace support for RequestParseBodyException class

The changes implement namespace handling for RequestParseBodyException, maintaining its inheritance structure while integrating with the inner class support.

ext/date/php_date_arginfo.h (1)

868-870: Well-structured implementation for namespaced class name support.

The changes consistently modify class registration functions to use the zend_namespaced_name structure and INIT_CLASS_NAME macro instead of directly passing string literals to INIT_CLASS_ENTRY. This refactoring is necessary to support inner class declarations in PHP, as it provides a way to track the full qualified name of a class, including any parent class scope.

The pattern is consistently applied across all class registration functions in the file, ensuring uniform handling of class names.

Also applies to: 978-981, 991-994, 1004-1007, 1100-1103, 1112-1115, 1183-1186, 1195-1198, 1207-1210, 1219-1222, 1231-1234, 1243-1246, 1255-1258, 1267-1270, 1279-1282

ext/date/php_date.c (2)

312-323: Improved error messages with fully qualified class names

Updates error messages in date_throw_uninitialized_error to use ce->namespaced_name.name instead of ce->name, ensuring that error messages include the fully qualified class name. This is particularly important for classes that may have the same name in different namespaces, including inner classes.


6073-6073: Updated error message to include fully qualified class name

Enhances the error message in date_period_unset_property to show the fully qualified class name (including namespace) when attempting to unset a property. This change is consistent with other error message improvements in the codebase.

ext/dom/php_dom.c (7)

279-280: Updated class name reference for consistency

The code now uses basece->namespaced_name.name instead of basece->name to properly support the new class naming structure required for nested classes.


291-292: Updated class name reference for consistency

This change aligns the class name lookup with the new namespaced class structure, ensuring that class lookups work properly with inner class declarations.


414-415: Updated error message to use namespaced class name

The error message now correctly references the fully qualified class name including namespace, which will provide clearer error messages when working with nested classes.


480-481: Updated error message to use namespaced class name

Property unset errors now display the fully qualified class name, improving error clarity when working with nested classes.


852-853: Updated hash table key to use namespaced class name

The hash key is now using namespaced_name.name instead of name, ensuring correct lookups for nested classes.


874-875: Consistently updated class registration to use namespaced names

All hash table registrations throughout the DOM extension module initialization are now using namespaced class names for proper functionality with inner classes.

Also applies to: 891-892, 904-905, 916-917, 966-967, 970-971, 981-982, 990-991, 997-998, 1006-1007, 1013-1014, 1020-1021, 1027-1028, 1039-1040, 1053-1054, 1066-1067, 1083-1084, 1100-1101, 1125-1126, 1130-1131, 1139-1140, 1148-1149, 1153-1154, 1158-1159, 1163-1164, 1168-1169, 1182-1183, 1196-1197, 1206-1207, 1216-1217, 1230-1231, 1241-1242, 1253-1254, 1265-1266, 1275-1276, 1285-1286, 1301-1302, 1307-1308, 1318-1319


2296-2297: Updated error messages in dimension accessors to use namespaced class names

Error messages in array access and dimension-related functions now correctly display the fully qualified class name including namespace, providing more specific error information.

Also applies to: 2388-2389, 2430-2431, 2449-2450, 2479-2480

ext/zend_test/test_arginfo.h (5)

584-587: Architecture change to support inner class handling

The changes to use zend_namespaced_name and the two-step initialization process (with INIT_CLASS_NAME followed by INIT_CLASS_ENTRY) provide the foundation for supporting nested class declarations in PHP. This pattern is consistently applied throughout all class registration functions.


603-606: LGTM: Consistent implementation pattern

The same two-step initialization pattern is correctly applied for _ZendTestClass. This consistency across all class registrations ensures reliable behavior for inner class support.


752-755: LGTM: Implementation follows established pattern

The implementation maintains consistency with other class registrations using the new namespaced name pattern.


1204-1205: LGTM: Proper namespace handling

For namespaced classes, INIT_CLASS_NAME_NS is correctly used instead of INIT_CLASS_NAME, which properly separates the namespace and class name components.


1274-1276: LGTM: Nested namespace registration

The implementation correctly handles deeper namespace nesting with ZendTestNS2\\ZendSubNS, demonstrating that the architecture modifications properly support both inner classes and complex namespace hierarchies.

ext/dom/php_dom_arginfo.h (5)

1878-1881: Class initialization refactored to support inner classes.

The code now uses a new zend_namespaced_name structure and the INIT_CLASS_NAME macro instead of directly passing class names as strings to INIT_CLASS_ENTRY. This change provides a consistent way to handle class names when supporting inner classes.


2979-2984: Consistent implementation of class initialization pattern.

This code correctly follows the same pattern for handling class names as seen throughout the file, ensuring consistency in how classes are registered regardless of namespace.


3673-3681: XPath class registration properly adapted for new class name handling.

The conditional compilation (#if defined(LIBXML_XPATH_ENABLED)) pattern is maintained while updating the initialization method to use the new namespaced name approach.


3161-3164: Inner class registration structure for HTMLElement.

The initialization follows the established pattern, inheriting from Dom_Element while properly setting up the namespaced class name structure.


2766-2774: Dom_ParentNode interface properly registered with new class name handling.

The interface registration uses the namespaced name structure correctly, keeping the interface definition consistent with class definitions throughout the file.

ext/intl/uchar/uchar_arginfo.h (1)

307-310: Changes support inner class declarations in PHP.

These modifications update how the IntlChar class is registered, switching from using a simple string to using the new zend_namespaced_name structure with the INIT_CLASS_NAME macro. This is part of the broader RFC implementation for inner classes in PHP.

Zend/zend_fibers.c (1)

1095-1101: Updated error message to use namespaced class name

The change correctly updates the error message to use the namespaced class name (namespaced_name.name) instead of the simple class name (name). This is important for providing more accurate context in error messages, especially when dealing with inner classes or classes in namespaces.

ext/dom/document.c (1)

2252-2252: Updated error message to use namespaced class name

The error message now correctly references the namespaced name of the base class using basece->namespaced_name.name instead of just basece->name, providing more useful error information when classes are nested or in namespaces.

ext/intl/resourcebundle/resourcebundle_arginfo.h (1)

59-63: Updated class registration to support namespaced class names

The code now properly initializes classes with namespaced name support by:

  1. Adding a zend_namespaced_name variable
  2. Using a two-step initialization process with INIT_CLASS_NAME and INIT_CLASS_ENTRY

This change is part of the inner class implementation and ensures proper class naming in nested contexts.

ext/intl/calendar/calendar_arginfo.h (2)

326-329: Implementation of namespaced class names for IntlCalendar.

The changes introduce support for namespaced class names by using a dedicated zend_namespaced_name structure instead of direct string literals. The INIT_CLASS_NAME macro initializes the namespaced name structure, which is then passed to INIT_CLASS_ENTRY.


572-575: Implementation of namespaced class names for IntlGregorianCalendar.

Similar to the previous change, this implements the namespaced class name structure for the IntlGregorianCalendar class, using the same pattern of INIT_CLASS_NAME followed by INIT_CLASS_ENTRY.

ext/intl/normalizer/normalizer_arginfo.h (1)

33-36: Implementation of namespaced class names for Normalizer.

The changes introduce support for namespaced class names by using a dedicated zend_namespaced_name structure instead of direct string literals. This is consistent with the approach used in other class registrations, preparing the code for better namespace handling.

ext/intl/spoofchecker/spoofchecker_arginfo.h (1)

63-66: Implementation of namespaced class names for Spoofchecker.

The changes introduce support for namespaced class names by using a dedicated zend_namespaced_name structure instead of direct string literals. This follows the same pattern as seen in other class registration functions and supports the inner class implementation effort.

ext/pdo/pdo_stmt.c (2)

40-40: Using namespaced class name in error message for better context.

The error message now uses the fully qualified namespaced class name via Z_OBJ(EX(This))->ce->namespaced_name.name instead of just the class name, providing more informative error messages.


2165-2165: Updated error message to use namespaced class name.

Similar to the previous change, this updates the error message in the pdo_stmt_iter_get function to use the namespaced class name, ensuring consistency in error reporting.

Zend/zend_generators.c (1)

1083-1083: Updated class name retrieval for namespaced support

The change modifies the class name retrieval in the __debugInfo method to use func->common.scope->namespaced_name.name instead of directly accessing func->common.scope->name. This supports the inner class implementation by ensuring the fully qualified class name is used in debug output.

Zend/zend_objects.c (3)

136-139: Updated error message to use namespaced class names

The error message for private destructor access violations now correctly uses the namespaced class name structure (namespaced_name.name) for both the object's class and the scope class. This ensures proper error reporting when dealing with inner classes.


157-160: Updated error message to use namespaced class names

Similar to the private destructor case, the error message for protected destructor access violations now correctly uses the namespaced class name structure. This provides more accurate error messages that reflect the full class name hierarchy.


166-166: Updated warning message to use namespaced class name

The warning message for protected destructor calls during shutdown has been updated to use the namespaced class name structure, maintaining consistency with the other error messages.

ext/intl/dateformat/dateformat_arginfo.h (1)

146-149: Updated class registration to support namespaced names

The class registration for IntlDateFormatter has been enhanced to use the new zend_namespaced_name structure:

  1. A namespaced_name variable is declared
  2. The class name is initialized with INIT_CLASS_NAME
  3. The class entry is initialized with this namespaced name

This modification supports the inner class implementation by using the structured approach to class names throughout the engine.

ext/intl/transliterator/transliterator_arginfo.h (1)

59-62: Updated class registration to support namespaced names

Similar to IntlDateFormatter, the Transliterator class registration now uses the structured approach with zend_namespaced_name instead of direct string initialization. This ensures consistent handling of namespaced class names across the codebase.

ext/intl/msgformat/msgformat_arginfo.h (2)

79-79: Structural change for class name handling

This introduces a zend_namespaced_name variable to enhance the class name handling, which is part of the infrastructure needed to support inner class declarations in PHP.


81-82: New pattern for class registration

Changed from using direct string literals to a structured approach with INIT_CLASS_NAME and INIT_CLASS_ENTRY using namespaced names. This change is consistent with the PR's objective to support inner classes by providing proper class name management.

ext/ftp/ftp_arginfo.h (2)

297-297: Added namespaced name structure

Similar to other files in this PR, introducing the zend_namespaced_name structure enhances class name handling and is necessary for the inner class implementation.


299-300: Updated namespaced class registration pattern

Changed from using INIT_NS_CLASS_ENTRY to a two-step process with INIT_CLASS_NAME_NS and INIT_CLASS_ENTRY using the namespaced name structure. This approach provides a more consistent way to handle namespaced classes including inner classes.

Zend/zend_fibers_arginfo.h (4)

76-76: Added namespaced name variable for Fiber class

Introducing the zend_namespaced_name variable for the Fiber class registration - consistent with the approach across the codebase for inner class support.


78-79: Updated class entry initialization for Fiber

Changed from direct string initialization to a structured approach with INIT_CLASS_NAME and INIT_CLASS_ENTRY using namespaced name. This change is part of the infrastructure needed for inner classes.


88-88: Added namespaced name variable for FiberError class

Same pattern applied to FiberError class, maintaining consistency in the implementation.


90-91: Updated class entry initialization for FiberError

Modified the class registration pattern to use the namespaced name structure, providing a consistent approach for class name handling across the codebase.

ext/intl/common/common_arginfo.h (2)

180-180: Added namespaced name variable for IntlIterator class

Introducing the zend_namespaced_name variable for the IntlIterator class, consistent with other changes in this PR.


182-183: Updated class entry initialization for IntlIterator

Changed from direct string initialization to the structured approach with INIT_CLASS_NAME and INIT_CLASS_ENTRY using namespaced name. This provides a consistent pattern for class registration that can accommodate inner classes.

ext/intl/locale/locale_arginfo.h (1)

109-112: Improved class registration with namespaced name support

The code now uses a zend_namespaced_name structure and proper initialization macros instead of directly passing string literals to INIT_CLASS_ENTRY. This change supports inner class declarations by ensuring classes are properly registered with namespace information.

Zend/zend_generators_arginfo.h (2)

56-59: Consistency with namespaced class registration pattern

Added support for proper class name resolution using the zend_namespaced_name structure and initialization macros. This change is part of the broader inner class implementation.


69-72: Consistent naming structure for exception class registration

Similar to the Generator class, the ClosedGeneratorException registration now uses the namespaced name structure, maintaining consistency across the codebase and supporting the inner class implementation.

Zend/zend_enum_arginfo.h (2)

30-33: Updated enum interface registration to use namespaced names

The UnitEnum interface registration now properly uses the zend_namespaced_name structure, ensuring consistent handling of class names throughout the engine.


42-45: Consistent namespaced name handling for BackedEnum interface

Similar to the UnitEnum change, this ensures BackedEnum registration follows the new naming pattern, supporting proper resolution of inner and namespaced classes.

Zend/zend_ast.c (3)

664-665: Updated class name resolution for CLASS in expressions

The code now correctly uses scope->namespaced_name.name instead of just scope->name, ensuring that inner classes have the correct CLASS constant value.


675-683: Fixed self and parent class name resolution for inner classes

The code now properly uses namespaced names for both self and parent class references, which is critical for inner class implementations to resolve their scope correctly.


1104-1105: Updated trait method deprecation message with namespaced name

Error messages for static trait method calls now use the namespaced class name, improving debugging clarity for inner classes.

ext/intl/timezone/timezone_arginfo.h (1)

165-168: Architecture change to support namespaced class names.

The introduction of zend_namespaced_name and use of INIT_CLASS_NAME instead of directly passing a string to INIT_CLASS_ENTRY is part of the core infrastructure changes needed to support inner classes. This change standardizes how class names are handled throughout the codebase.

Zend/zend_compile.h (5)

586-586: Updated function scope name macro to use namespaced name.

The macro now references namespaced_name.name instead of just name, which is necessary to properly support inner classes in error messages and debugging.


897-897: Added inner class target to modifier enum.

This new enum value enables the application of modifiers (like public, private, protected) to inner class declarations.


1024-1024: Added ZEND_FETCH_CLASS_OUTER constant for class fetch operations.

This constant will be used when fetching outer classes in the context of inner class operations, providing the necessary infrastructure for inner/outer class relationships.


1031-1031: Added ZEND_FETCH_CLASS_NO_INNER constant for class fetch operations.

This constant allows for excluding inner classes during class fetch operations, providing finer control over class resolution.


1037-1039: Properly indented name resolution constants.

These existing constants were realigned for better code readability and consistency.

Zend/zend_builtin_functions_arginfo.h (1)

370-373: Updated stdClass registration to use namespaced name structure.

Similar to other class registrations, stdClass now uses the new zend_namespaced_name structure and corresponding initialization macros, ensuring consistent handling of class names throughout the codebase.

Zend/zend_compile.c (49)

896-910: Allowing T_READONLY, T_ABSTRACT, T_FINAL for inner classes looks sensible.
These additions correctly grant inner classes the relevant flags without conflicting with existing code.


947-948: New "inner class" member label.
This straightforwardly extends member labeling to inner classes.


1056-1086: Modifier restrictions for inner classes.
Disallowing static and access-type setters on inner classes is logical. Please ensure test coverage checks these error messages (e.g., “Static inner classes are not allowed”).


1102-1109: Use of “|” delimiter in zend_prefix_with_outer_class.
Earlier reviews flagged possible delimiter collisions (|, :>, \\). Consider documenting or unifying delimiters to avoid confusion.


1222-1227: Continuing return of zend_namespaced_name *.
Same concern as above. Verify consistent usage in subsequent code.


1455-1459: Splitting class name on “|” for nested scope.
Reiterating the delimiter collision concern.


1537-1537: Assigning name = called_scope->namespaced_name.name;
Check that called_scope->namespaced_name.name is truly zend_string *; otherwise, it may provoke C4133 warnings.


1796-1796: Usage of namespaced_name.name in zend_is_scoped_const_expr.
No issues spotted.


1825-1857: zend_resolve_nested_class_name: building “outer:>inner”.
Implementation is correct, but you now have “|” and “:>” delimiters simultaneously. Document and unify if possible.


1890-1893: Emitting nested class name into zval.
Looks consistent with the new function.


1911-1918: ZVAL_STR_COPY: assigning namespaced_name.name to zval.
Implementation looks correct, but re-check for type mismatch warnings.


1958-1958: ce = zend_hash_find_ptr_lc(…, ce->parent_name->name);
Looks good for parent resolution.


2947-2981: zend_compile_inner_class_ref logic.
Clean approach to generating an op for fetching an inner class reference. Consider negative tests for invalid outer classes.


3026-3032: Static modifier disallowed on inner class.
Clear error message. Implementation is straightforward.


5501-5501: Comparing namespaced_name.name with lcname.
No concerns here.


7134-7141: class_name = CG(active_class_entry)->namespaced_name.name or …->parent_name->name.
Ensure the correct pointer type usage to avoid C4133 warnings.


7453-7455: Inner classes in type declarations.
ZEND_AST_INNER_CLASS resolves to a zend_string * name properly.


7918-7924: Using scope->namespaced_name.name in compile-time error messages.
Implementation is consistent.


7949-7949: Readonly property error referencing scope->namespaced_name.name.
Works as intended.


8200-8200: Stringable check in interface list.
No issues found.


8212-8213: “Stringable” interned strings.
Looks good for tracking interface names.


8241-8274: Error messages referencing namespaced_name.name.
No functional concerns.


8285-8285: Property redeclaration error.
Seems clear and consistent.


8337-8338: Class name used in error/logging.
Straightforward usage.


8655-8655: Compile error for unknown hook.
Naming and message are aligned.


8677-8677: “get hook must not have a parameter list.”
Message logic is clear.


8787-8787: “Enum cannot include properties.”
Correctly enforced.


8850-8850: Property type error referencing namespaced_name.name.
Valid usage.


8861-8861: Duplicate property redeclaration check.
Implementation is fine.


8882-8882: Cannot use that default value for property.
Clear error handling.


8898-8908: Readonly property constraints.
Proper checks for type, default value, and static usage.


8973-8980: Class constant cannot have type.
No issues.


8990-8990: Class constant value mismatch.
Error message logic is consistent.


9092-9092: Trait usage within an interface.
Error message is coherent.


9120-9132: Implementing multiple interfaces with zend_namespaced_name.
The approach is correct, populating array entries with lowered interface names.

🧰 Tools
🪛 GitHub Actions: Push

[error] 9130-9130: warning C4133: 'initializing': incompatible types - from 'zend_namespaced_name *' to 'zend_string *'


9180-9197: Deferred class declarations for inner classes.
Implementation is logical: stored in inner_class_queue until outer class finishes.


9223-9268: Building up an inner class name with possible additional flags.
Double-check how “protected” or “private” scope is enforced at runtime.


9285-9286: Resetting required/lexical scope for top-level classes.
Implementation appears coherent.


9297-9301: Assign ce->namespaced_name.name and optionally cache.
Straightforward and correct.


9328-9330: Interface compilation for inner classes.
Looks consistent with zend_compile_implements.


9369-9369: Lookup of ce->parent_name->name with zend_lookup_class_ex.
Implementation is standard.


9384-9384: goto compile_inner_classes for final linking.
Used as a short-circuit approach.


9401-9401: Lowercasing parent name.
No concerns.


9455-9472: Compile queued inner classes.
Collects them from inner_class_queue and compiles in sequence.


9484-9484: Capturing enum class name.
No problems spotted.


9871-9871: Creating a member string from scope->namespaced_name.name.
Implementation is consistent.


9884-9884: ZVAL_STR_COPY(zv, ce->namespaced_name.name); for __CLASS__.
No issues.


11743-11746: Defer class declaration if already inside a class.
This logic ensures nested classes wait until the outer is fully compiled.


11917-11920: ZEND_AST_INNER_CLASS: compile-time reference.
Cleanly delegates to zend_compile_inner_class_ref.

ext/pdo/pdo_dbh.c (5)

245-246: Update to use namespaced class name representation

The code now correctly uses namespaced_name.name instead of name to reference the class name in error messages. This ensures that fully qualified class names are displayed in error messages.


248-251: Consistent use of namespaced class names in error messages

The change to use namespaced_name.name here is consistent with other changes in this file and ensures accurate representation of class names in error messages.


264-267: Improved error message clarity with namespaced class names

Using namespaced_name.name instead of just name ensures that the error message includes the fully qualified class name, which is especially helpful in codebases with multiple namespaces.


283-289: Consistent error message formatting with namespaced class names

The change ensures that all error messages consistently use the fully qualified class names, which improves debugging and error handling across the codebase.


1015-1019: Proper handling of namespaced statement class names

The change to use namespaced_name.name when retrieving the default statement class name ensures that the correct, fully qualified class name is returned in the getAttribute method.

ext/intl/breakiterator/breakiterator_arginfo.h (3)

157-160: Support for namespaced class initialization

The addition of the namespaced_name variable and the use of INIT_CLASS_NAME and INIT_CLASS_ENTRY macros improves the class registration process by properly handling namespaced class names.


284-288: Consistent class registration pattern for IntlRuleBasedBreakIterator

The change follows the same pattern as earlier in the file, ensuring consistent handling of namespaced class names across all class registrations.


296-300: Consistent class registration pattern for IntlCodePointBreakIterator

The implementation of namespaced class registration is consistent with the pattern established for other classes, promoting code consistency.

Zend/zend_closures_arginfo.h (1)

45-48: Enhanced Closure class registration with namespaced support

The code now uses a two-step process for class registration with the addition of the namespaced_name variable. This change aligns with the broader effort to support inner classes and proper namespace handling throughout the codebase.

ext/intl/converter/converter_arginfo.h (1)

123-126: Updated UConverter class registration with namespaced support

The introduction of namespaced_name and the updated initialization pattern is consistent with changes in other files, ensuring a uniform approach to class registration across the codebase.

ext/pdo/pdo_stmt_arginfo.h (2)

138-141: Updated class registration to use namespaced names for PDOStatement.

The registration now uses zend_namespaced_name to properly handle class names, which is consistent with the inner class support being implemented in this PR.


157-160: Updated class registration to use namespaced names for PDORow.

Similar to the change for PDOStatement, this change introduces the use of zend_namespaced_name for PDORow registration, ensuring consistent handling of class names.

Zend/zend_property_hooks.c (2)

171-171: Updated error message to use namespaced class name.

Changed the error message to use namespaced_name.name instead of direct access to the class name, which is necessary for proper identification of inner classes in error reporting.


200-200: Updated readonly property error message to use namespaced class name.

Modified the error message to reference the class through its namespaced name structure, ensuring accurate error reporting for inner/nested classes when accessing readonly properties.

Zend/zend_closures.c (3)

92-94: Updated error message to use namespaced class names for incompatible $this binding.

The error message now properly displays the fully qualified names of classes involved when binding an incompatible object to an internal method, which will be particularly important for inner classes.


110-110: Updated error message to use namespaced class name for internal class scope binding.

Properly references the namespaced class name when reporting that a closure cannot be bound to an internal class scope.


600-600: Updated class name reference for fake closures.

Modified the reference to obtain the class name through the namespaced_name.name property instead of directly using name, ensuring proper display of class names for fake closures.

ext/intl/php_intl_arginfo.h (1)

1227-1230: Updated IntlException class registration to use namespaced names.

The initialization of the IntlException class now uses the zend_namespaced_name structure and the INIT_CLASS_NAME macro, consistent with the pattern applied throughout the codebase for proper inner class support.

Zend/zend_builtin_functions.c (1)

595-595: Consistent update to use namespaced class names

The code has been updated to use namespaced_name.name instead of name when accessing class names throughout various functions. This change is essential for supporting inner classes by ensuring that class names are properly namespaced and fully qualified.

The changes affect:

  • get_class()
  • get_called_class()
  • get_parent_class()
  • is_a_impl()
  • get_declared_class_impl()
  • zend_fetch_debug_backtrace()

This consistent approach ensures that all class name references properly handle namespaced class names, including inner classes.

Also applies to: 602-602, 619-619, 642-642, 682-682, 1389-1389, 2045-2047, 2060-2060

Zend/zend_execute_API.c (4)

554-554: Change to use namespaced_name structure.

This change moves from accessing the class name directly to using the new namespaced_name.name field, which supports the inner class implementation.


621-621: Consistent use of namespaced_name structure.

Similar to the previous change, this updates the member string creation to use the namespaced_name.name field, maintaining consistency throughout the codebase.


1106-1106: Further namespaced_name adoption.

Continuing the pattern of using the new namespaced_name.name property for class name access.


1308-1316: Integration of nested class resolution into class lookup.

This addition to zend_lookup_class_ex checks if we need to consider nested classes (when the ZEND_FETCH_CLASS_NO_INNER flag is not set) and calls the new zend_resolve_nested_class function if needed.

Zend/zend_execute.c (3)

1048-1078: New visibility check function to enforce inner class access rules.

This new function zend_check_class_visibility correctly implements the PHP visibility rules for inner classes:

  • Public classes (no required scope) are always visible
  • Protected classes are visible in the same or derived classes
  • Private classes are only visible within their defining class

The error messages clearly explain why visibility is being denied, aiding developers in understanding access violations.


1082-1085: Enforcing object visibility rules for property assignments.

This addition ensures that objects of private/protected inner classes cannot be assigned to properties with higher visibility. This prevents visibility leaks through property assignments, closing a potential access control loophole.


616-616: Updated class name access across error messages.

These changes update various error messages to use namespaced_name.name instead of name for class references, ensuring consistent class naming for inner classes throughout error messages in the codebase.

Also applies to: 626-626, 636-636, 852-852, 868-869, 898-898, 909-909, 920-920, 948-948, 950-950, 1401-1401, 1543-1543, 1609-1609, 2147-2147, 2167-2167, 2174-2174, 2507-2507, 2521-2521, 3762-3762, 3765-3765, 3777-3777, 3789-3789, 3792-3792, 4105-4105, 4107-4107

Zend/zend_API.c (11)

156-157: Changes for proper namespaced name handling

The code now correctly uses the namespaced name for object class entries when getting value names, ensuring proper display of fully-qualified class names.


175-176: Consistent use of namespaced name

Properly using the namespaced class name to support inner classes and ensure consistent class name representation.


1819-1832: New inner class scope restriction implementation

This critical addition implements scope restrictions for inner classes:

  1. Private inner classes (required_scope_absolute) can only be instantiated from the exact required scope or its lexical scope
  2. Protected inner classes can be instantiated from classes that inherit from the required scope
  3. Classes with scope restrictions cannot be instantiated from global scope

This properly enforces encapsulation for inner classes according to their visibility modifiers.


464-465: Consistent use of namespaced name in error messages

Updated the error message to use the full namespaced name when reporting class redeclaration errors.


483-485: Use namespaced name in type error messages

Updated type error messages to use the full namespaced name, providing clearer error messages for users.


986-991: Updated parameter type check to use namespaced names

Error messages for parameter type checking now display the full namespaced class name, improving error clarity.


1020-1022: Consistent error message for class name requirements

Updated the error message to consistently use the full namespaced class name when checking derived class requirements.


1493-1494: Cache allocation updated for namespaced names

The CE cache allocation now correctly uses the namespaced name structure.


1501-1504: Updated lowercase name creation for namespaced names

Properly generating lowercase names using the namespaced name structure to ensure correct class registration.


3507-3512: Stringable interface check with namespaced names

Updated the Stringable interface check to correctly use the namespaced name structure.


4668-4669: Property name mangling with namespaced names

Updated property name mangling to use the namespaced name structure, ensuring proper property name generation for private properties.

Zend/zend_enum.c (4)

31-31: LGTM: Consistent update of class name references

The changes correctly update all references from ce->name to ce->namespaced_name.name in error messages and function calls related to enums. This is an important part of supporting inner classes by ensuring proper name representation throughout the codebase.

Also applies to: 76-76, 107-107, 116-116, 134-135, 144-145, 151-152, 319-319, 322-322, 435-435, 602-602


185-190: LGTM: Updated interface name handling

The interface name assignment now correctly uses the namespaced name structure. This ensures that enum classes implementing UnitEnum and BackedEnum interfaces display proper namespaced names in error messages and reflection information.


208-208: LGTM: Updated enum_class_name reference

The enum_class_name variable now references the namespaced name, ensuring consistent class name usage throughout enum case handling.


509-511: LGTM: Added namespaced name support for internal enum initialization

The initialization of internal enums now uses the new namespaced name structure, which is necessary for properly supporting inner class declarations within the enum system.

@@ -2000,7 +2018,7 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string
#define Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, is_null, allow_null) \
Z_PARAM_PROLOGUE(0, 0); \
if (UNEXPECTED(!zend_parse_arg_obj_or_long(_arg, &dest_obj, _ce, &dest_long, &is_null, allow_null, _i))) { \
_error = ZSTR_VAL((_ce)->name); \
_error = ZSTR_VAL((_ce)->namespaced_name.name); \
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Logic flaw: success scenario is treated as an error.
The else block again sets _error_code and breaks, leaving no valid success route for zend_parse_arg_obj_or_long(). Revisit the control flow to ensure a legitimate success path.

@@ -1960,7 +1978,7 @@
Z_PARAM_PROLOGUE(deref, 0); \
if (UNEXPECTED(!zend_parse_arg_object(_arg, &dest, _ce, check_null))) { \
if (_ce) { \
_error = ZSTR_VAL((_ce)->name); \
_error = ZSTR_VAL((_ce)->namespaced_name.name); \
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Duplicated bug: success path triggers an error code and break.
Similar to the issue at line 1793, the else path unconditionally sets _error_code and breaks, negating a successful parse outcome.

You can fix it by removing the else block and handling success explicitly, as shown in the previous comment’s diff.

@@ -1981,7 +1999,7 @@
Z_PARAM_PROLOGUE(deref, 0); \
if (UNEXPECTED(!zend_parse_arg_obj(_arg, &dest, _ce, check_null))) { \
if (_ce) { \
_error = ZSTR_VAL((_ce)->name); \
_error = ZSTR_VAL((_ce)->namespaced_name.name); \
_error_code = check_null ? ZPP_ERROR_WRONG_CLASS_OR_NULL : ZPP_ERROR_WRONG_CLASS; \
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Likely unintended break in the success path.
This path should not force an error if zend_parse_arg_obj() succeeds. Remove the else block or separate the success logic to avoid always breaking with an error code.

@@ -1772,7 +1790,7 @@
Z_PARAM_PROLOGUE(0, 0); \
if (UNEXPECTED(!zend_parse_arg_obj_or_str(_arg, &destination_object, base_ce, &destination_string, allow_null, _i))) { \
if (base_ce) { \
_error = ZSTR_VAL((base_ce)->name); \
_error = ZSTR_VAL((base_ce)->namespaced_name.name); \
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Suspicious control flow logic — success path always breaks as an error.
Even if zend_parse_arg_obj_or_str() succeeds, the else block sets _error_code and performs a break. There's effectively no success path. This likely prevents this macro from ever succeeding.

Below is a suggested fix to preserve a proper success path:

-    if (UNEXPECTED(!zend_parse_arg_obj_or_str(_arg, &destination_object, base_ce, &destination_string, allow_null, _i))) {
-        _error = ZSTR_VAL((base_ce)->namespaced_name.name);
-        _error_code = allow_null ? ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL : ZPP_ERROR_WRONG_CLASS_OR_STRING;
-        break;
-    } else {
-        _expected_type = allow_null ? Z_EXPECTED_OBJECT_OR_STRING_OR_NULL : Z_EXPECTED_OBJECT_OR_STRING;
-        _error_code = ZPP_ERROR_WRONG_ARG;
-        break;
-    }
+    if (UNEXPECTED(!zend_parse_arg_obj_or_str(_arg, &destination_object, base_ce, &destination_string, allow_null, _i))) {
+        _error = ZSTR_VAL((base_ce)->namespaced_name.name);
+        _error_code = allow_null ? ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL : ZPP_ERROR_WRONG_CLASS_OR_STRING;
+        break;
+    }
+    // On success, do not set error codes and do not break here.
📝 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
_error = ZSTR_VAL((base_ce)->namespaced_name.name); \
if (UNEXPECTED(!zend_parse_arg_obj_or_str(_arg, &destination_object, base_ce, &destination_string, allow_null, _i))) {
_error = ZSTR_VAL((base_ce)->namespaced_name.name);
_error_code = allow_null ? ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL : ZPP_ERROR_WRONG_CLASS_OR_STRING;
break;
}
// On success, do not set error codes and do not break here.

Comment on lines +1205 to +1211
return actual_name;
//return zend_string_copy(name);
}

if (type == ZEND_NAME_RELATIVE) {
return zend_prefix_with_ns(name);
return actual_name;
//return zend_prefix_with_ns(name);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Returning zend_namespaced_name * vs. the commented-out zend_string *.
This change may trigger compiler warnings (C4133). Ensure all usages align with the new pointer type.

Comment on lines +1239 to +1262
return actual_name;
//return zend_concat_names(
// ZSTR_VAL(import_name), ZSTR_LEN(import_name), ZSTR_VAL(name) + len + 1, ZSTR_LEN(name) - len - 1);
}
} else {
/* If an unqualified name is an alias, replace it. */
zend_string *import_name
= zend_hash_find_ptr_lc(FC(imports), name);

if (import_name) {
return zend_string_copy(import_name);
return actual_name;
//return zend_string_copy(import_name);
}
}
}

if (CG(active_class_entry)) {
return actual_name;
//return zend_prefix_with_outer_class(name);
}

/* If not fully qualified and not an alias, prepend the current namespace */
return zend_prefix_with_ns(name);
return actual_name;
//return zend_prefix_with_ns(name);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Refactoring zend_resolve_class_name: repeated actual_name returns.
Consider returning a zend_string * or adjusting all callers if a zend_namespaced_name * is truly needed.

Comment on lines +1190 to +1193
static zend_namespaced_name *zend_resolve_class_name(zend_string *name, uint32_t type) /* {{{ */
{
char *compound;
zend_namespaced_name *actual_name = NULL;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential type mismatch in zend_resolve_class_name.
This function now returns zend_namespaced_name * instead of zend_string *. Verify all callers accept a zend_namespaced_name * and properly handle or convert it.

withinboredom pushed a commit that referenced this pull request Mar 29, 2025
```
ext/gd/libgd/gd.c:2275:14: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
    #0 0x5d6a2103e1db in php_gd_gdImageCopy /home/dcarlier/Contribs/php-src/ext/gd/libgd/gd.c:2275
    #1 0x5d6a210a2b63 in gdImageCrop /home/dcarlier/Contribs/php-src/ext/gd/libgd/gd_crop.c:57
    #2 0x5d6a21018ca4 in zif_imagecrop /home/dcarlier/Contribs/php-src/ext/gd/gd.c:3575
    #3 0x5d6a21e46e7a in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/dcarlier/Contribs/php-src/Zend/zend_vm_execute.h:1337
    #4 0x5d6a221188da in execute_ex /home/dcarlier/Contribs/php-src/Zend/zend_vm_execute.h:57246
    #5 0x5d6a221366bd in zend_execute /home/dcarlier/Contribs/php-src/Zend/zend_vm_execute.h:61634
    #6 0x5d6a21d107a6 in zend_execute_scripts /home/dcarlier/Contribs/php-src/Zend/zend.c:1895
    #7 0x5d6a21a63409 in php_execute_script /home/dcarlier/Contribs/php-src/main/main.c:2529
    #8 0x5d6a22516d5e in do_cli /home/dcarlier/Contribs/php-src/sapi/cli/php_cli.c:966
    php#9 0x5d6a2251981d in main /home/dcarlier/Contribs/php-src/sapi/cli/php_cli.c:1341
    php#10 0x7f10d002a3b7 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    php#11 0x7f10d002a47a in __libc_start_main_impl ../csu/libc-start.c:360
    php#12 0x5d6a20a06da4 in _start (/home/dcarlier/Contribs/php-src/sapi/cli/php+0x2806da4) (BuildId: d9a79c7e0e4872311439d7313cb3a81fe04190a2)
```

close phpGH-18006
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant