├── tests ├── .hhconfig ├── Classes │ ├── .hhconfig │ ├── Aircraft.php.expect │ ├── MyList.php.expect │ ├── Point.php.expect │ ├── Point2.php.expect │ ├── Vehicle.php.expect │ ├── MathLibrary.php.expect │ ├── MyCollection.php.expect │ ├── PassengerJet.php.expect │ ├── MathLibrary_test1.php.expect │ ├── invoke.php.expect │ ├── cc.php.expectf │ ├── visibility.php.expect │ ├── classes.php.expect │ ├── type_constants.php.expect │ ├── property_initializer.php.expect │ ├── Vehicle_test1.php.expect │ ├── destructors.php.expect │ ├── abstract_constants.php.expect │ ├── require_extends_implements.php.expectf │ ├── test_for_new_types.php.expectf │ ├── Vehicle.php │ ├── Closure_call.php.expectf │ ├── MyCollection.php │ ├── Serializable.php.expectf │ ├── Generator_getReturn.php.expectf │ ├── Serializable_with_untrusted_data.php.expectf │ ├── Aircraft.php │ ├── classes.php │ ├── MyList.php │ ├── invoke.php │ ├── MathLibrary.php │ ├── Vehicle_test1.php │ ├── test_for_new_types.php │ ├── PassengerJet.php │ ├── MathLibrary_test1.php │ ├── constructors.php.expect │ ├── dynamic_methods.php.expect │ ├── abstract_constants.php │ ├── cc.php │ ├── property_initializer.php │ ├── destructors.php │ ├── Point2.php │ ├── Closure_call.php │ ├── dynamic_methods.php │ ├── Generator_getReturn.php │ ├── __PHP_Incomplete_Class.php.expect │ ├── __PHP_Incomplete_Class.php │ ├── require_extends_implements.php │ └── cloning.php.expect ├── Enums │ ├── .hhconfig │ ├── enums.php.expect │ ├── enum_constraints.php.expect │ ├── string_int_equality_problem.php.expectf │ ├── enums_ops.php.expect │ ├── string_int_equality_problem.php │ └── enum_constraints.php ├── Shapes │ ├── .hhconfig │ ├── shapes_rf.php.expect │ └── shapes.php.expect ├── Traits │ ├── .hhconfig │ ├── trait_requirements.php.expect │ ├── trait_implements_interface.php.expect │ ├── traits.php.expect │ ├── trait_implements_interface.php │ └── trait_requirements.php ├── Tuples │ ├── .hhconfig │ ├── tuples.php.expect │ └── tuples.php ├── Types │ ├── .hhconfig │ ├── bool.php.expect │ ├── enum.php.expect │ ├── float.php.expect │ ├── mixed.php.expect │ ├── tuple.php.expect │ ├── shapes_rf.php.expect │ ├── string.php.expect │ ├── determined_type.php.expect │ ├── type_side_effects.php.expect │ ├── closure.php.expect │ ├── Issue_110.php.expect │ ├── void.php.expect │ ├── this.php.expectf │ ├── Testfile.txt │ ├── arraykey.php.expect │ ├── type_aliases_rf.php.expectf │ ├── Issue_109.php.expectf │ ├── int.php.expect │ ├── type_aliases.php.expectf │ ├── num.php.expect │ ├── Issue_109.php │ ├── type_inferencing.php.expect │ ├── shapes.php.expectf │ ├── shapes.php.expect │ ├── bool.php │ ├── float.php │ ├── mixed.php │ ├── string.php │ ├── tuple.php │ ├── Issue_110.php │ ├── resources.php.expectf │ ├── shape_subtyping.php.expect │ ├── enum.php │ ├── void.php │ ├── int.php │ ├── type_inferencing.php │ ├── numeric_like_strings.php.expect │ ├── closure.php │ ├── scalar_general.php.expectf │ ├── resources.php │ ├── num.php │ ├── arraykey.php │ ├── shapes2.php.expectf │ └── shape_subtyping.php ├── Attributes │ ├── .hhconfig │ ├── __Override.php.expect │ └── __ConsistentConstruct.php.expect ├── Collections │ └── .hhconfig ├── Constants │ ├── .hhconfig │ ├── core_predefined_constants.php.expect │ ├── Testfile.txt │ └── constants.php.expect ├── Expressions │ ├── .hhconfig │ ├── Unary_Operators │ │ ├── .hhconfig │ │ ├── cast.php.expect │ │ ├── error_control.php.expectf │ │ ├── error_control.php │ │ ├── pre-increment_and_decrement.php.expect │ │ ├── pre-increment_and_decrement_integer_edge_cases.php.expect │ │ ├── cast.php │ │ └── pre-increment_and_decrement_integer_edge_cases.php │ ├── Yield_Operator │ │ ├── .hhconfig │ │ ├── yield.php.expectf │ │ ├── yield_from.php.expectf │ │ └── yield_from.php │ ├── Additive_Operators │ │ ├── .hhconfig │ │ ├── addition_subtraction_concatenation.php │ │ └── array_concatenation.php.expect │ ├── Conditional_Operator │ │ ├── .hhconfig │ │ └── conditional.php.expect │ ├── Equality_Operators │ │ ├── .hhconfig │ │ ├── Testfile1.txt │ │ ├── Testfile2.txt │ │ ├── comparisons.php.expect │ │ └── equality_comparison_of_objects.php.expect │ ├── Instanceof_Operator │ │ ├── .hhconfig │ │ └── instanceof.php.expect │ ├── Lambda_Expressions │ │ └── .hhconfig │ ├── Postfix_Operators │ │ ├── .hhconfig │ │ ├── new.php.expect │ │ ├── subscripting.php.expect │ │ ├── nullable_and_arithmetic.php.expect │ │ ├── exponentiation.php.expect │ │ ├── nullsafe_member_selection.php.expect │ │ ├── function_call.php.expect │ │ ├── member_selection_operator.php.expect │ │ ├── array_creation.php.expect │ │ ├── function_call_with_strict_checking.php.expectf │ │ ├── subscripting_2.php.expectf │ │ ├── new_anonymous_classes.php.expectf │ │ ├── scope_resolution_operator.php.expectf │ │ ├── array_creation.php │ │ ├── new.php │ │ ├── post_increment_and_decrement.php.expect │ │ ├── function_call_with_strict_checking.php │ │ ├── post-increment_and_decrement_integer_edge_cases.php.expect │ │ ├── subscripting_2.php.expect │ │ ├── subscripting_2.php │ │ ├── nullsafe_member_selection.php │ │ ├── post-increment_and_decrement_integer_edge_cases.php │ │ ├── exponentiation.php │ │ └── function_call.php │ ├── Primary_Expressions │ │ ├── .hhconfig │ │ ├── Point.php.expect │ │ ├── Point2.php.expect │ │ ├── intrinsics_invariant.php.expect │ │ ├── primary.php.expect │ │ ├── intrinsics_echo.php.expect │ │ ├── intrinsics_exit.php.expect │ │ ├── primary.php │ │ ├── Point2.php │ │ ├── listPHP.php.expect │ │ ├── intrinsics_list.php.expect │ │ ├── intrinsics_exit.php │ │ ├── Point.php │ │ ├── intrinsics_echo.php │ │ └── intrinsics_invariant.php │ ├── Relational_Operators │ │ ├── .hhconfig │ │ ├── Testfile1.txt │ │ ├── Testfile2.txt │ │ ├── combined_comparison.php.expectf │ │ ├── relational_comparison_of_objects.php.expect │ │ └── combined_comparison.php │ ├── Binary_Logical_Operators │ │ ├── .hhconfig │ │ ├── binary_logical_operators.php.expect │ │ └── binary_logical_operators.php │ ├── Bitwise_Shift_Operators │ │ ├── .hhconfig │ │ └── bitwise_shift.php │ ├── Multiplicative_Operators │ │ ├── .hhconfig │ │ ├── multiplication_division_modulus.php.expect │ │ └── multiplication_division_modulus.php │ ├── Null_safe_method_call │ │ ├── .hhconfig │ │ ├── null_safe_calls.php.expect │ │ └── null_safe_calls.php │ ├── Bitwise_and_or_xor_Operators │ │ ├── .hhconfig │ │ └── bitwise_and_or_xor.php.expect │ ├── Coalesce Operator │ │ ├── coalesce.php.expect │ │ └── coalesce.php │ ├── limits_on_types_in_arithmetic.php.expect │ ├── Testfile.txt │ ├── yield.php.expectf │ └── limits_on_types_in_arithmetic.php ├── Functions │ ├── .hhconfig │ ├── TestInc.php.expect │ ├── noreturn.php.expect │ ├── override_on_return_type.php.expect │ ├── callable_typehint.php.expect │ ├── TestInc.php │ ├── variable_functions.php.expect │ ├── recursion.php.expect │ ├── async_functions2.php.expect │ ├── conditionally_defined_function.php.expectf │ ├── anonymous_function_name.php.expect │ ├── basics.php.expectf │ ├── recursion.php │ ├── callable_typehint.php │ ├── variable_functions.php │ ├── this_play.php.expect │ ├── anonymous_functions2.php.expect │ ├── anonymous_function_name.php │ ├── async_functions2.php │ ├── async_functions.php.expectf │ ├── anonymous_functions2.php │ ├── conditionally_defined_function.php │ └── basics.php ├── Generics │ ├── .hhconfig │ ├── Complex.php.expect │ ├── Stack.php.expect │ ├── MyVector.php.expect │ ├── generics.php.expect │ ├── MyVector_test.php.expect │ ├── contravariance_example.php.expect │ ├── constraints.php.expect │ ├── generic_function.php.expect │ ├── contravariance_example.php │ ├── covariance_example.php.expect │ ├── covariance_example.php │ ├── Stack_test.php.expect │ ├── Interface_Support.php.expect │ ├── Stack.php │ ├── MyVector.php │ ├── Complex_test.php.expect │ ├── Complex.php │ ├── Complex_test.php │ └── constraints.php ├── Interfaces │ ├── .hhconfig │ ├── MyList.php.expect │ ├── MyQueue.php.expect │ ├── MyCollection.php.expect │ ├── interface_requirements.php.expect │ ├── qq.php.expect │ ├── MyCollection.php │ ├── interface_requirements.php │ ├── MyList.php │ ├── MyQueue.php │ ├── interfaces.php.expect │ └── qq.php ├── Namespaces │ ├── .hhconfig │ ├── Point.php.expect │ ├── Circle.php.expect │ ├── using_namespaces_3.php.expect │ ├── use_groups_require_file.php.expect │ ├── using_namespaces_3_test.php.expect │ ├── using_namespaces_1.php.expect │ ├── namespaces2.php.expectf │ ├── namespaces2_test.php.expectf │ ├── use_groups.php.expectf │ ├── using_namespaces_3_test.php │ ├── namespaces2_test.php │ ├── namespaces1.php.expect │ ├── Circle.php │ ├── use_groups_require_file.php │ ├── Point.php │ ├── using_namespaces_1.php │ ├── namespaces2.php │ ├── using_namespaces_3.php │ └── namespaces1.php ├── Statements │ ├── .hhconfig │ ├── Jump │ │ ├── .hhconfig │ │ ├── break.php.expect │ │ ├── continue.php.expect │ │ ├── break.php │ │ └── continue.php │ ├── Iteration │ │ ├── .hhconfig │ │ ├── do.php.expect │ │ ├── while.php.expect │ │ ├── do.php │ │ ├── for.php.expect │ │ ├── while.php │ │ └── for.php │ ├── Selection │ │ ├── .hhconfig │ │ ├── switch.php.expect │ │ └── if.php.expectf │ ├── expression_statement.php.expect │ └── expression_statement.php ├── Variables │ ├── .hhconfig │ ├── predefined_variables.php.expect │ ├── predefined_variables.php │ ├── variable_kinds.php.expect │ └── placeholder_variable.php.expect ├── Basic_Concepts │ ├── .hhconfig │ ├── top_level_stuff.php.expect │ ├── program_structure.php │ ├── program_structure.php.expectf │ └── top_level_stuff.php ├── Lexical_Structure │ ├── .hhconfig │ ├── Tokens │ │ ├── .hhconfig │ │ ├── names.php.expect │ │ ├── heredoc_string_literals.php.expect │ │ ├── nowdoc_string_literals.php.expect │ │ ├── integer_literals_edge_cases.php.expect │ │ ├── name_case_sensitivity.php.expectf │ │ ├── heredoc_string_literals.php │ │ ├── nowdoc_string_literals.php │ │ ├── unicode_escape_sequences.php.expect │ │ ├── array_literals.php │ │ ├── name_case_sensitivity.php │ │ ├── array_literals.php.expect │ │ ├── string_literals.php.expect │ │ └── integer_literals_edge_cases.php │ ├── keywords.php.expect │ ├── comments.php.expect │ ├── keywords.php │ └── comments.php ├── Nullable_Types │ └── .hhconfig ├── Script_Inclusion │ ├── .hhconfig │ ├── Circle.php.expect │ ├── Point.php.expect │ ├── Positions.php.expect │ ├── limits.php.expect │ ├── mycolors.php.expect │ ├── return_none.php.expect │ ├── return_with_value.php.expect │ ├── return_none.php │ ├── mycolors.php │ ├── limits.php │ ├── require_once.php.expectf │ ├── Positions.php │ ├── Point.php │ ├── return_with_value.php │ ├── Circle.php │ ├── require.php.expectf │ ├── require_once.php │ └── require.php ├── Serialization │ ├── .hhconfig │ ├── Point.php.expectf │ ├── serialize.php.expectf │ ├── serialize.php │ └── Point.php └── Exception_Handling │ ├── .hhconfig │ ├── MyRangeException.php.expect │ ├── hierarchy_of_exception_classes.php.expect │ ├── jump_from_catch_or_finally_clause.php.expect │ ├── odds_and_ends.php.expect │ ├── MyRangeException_test1.php │ ├── jump_from_catch_or_finally_clause.php │ ├── MyRangeException.php │ ├── MyRangeException_test1.php.expectf │ ├── odds_and_ends.php │ └── hierarchy_of_exception_classes.php ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── CONTRIBUTING.md ├── spec ├── 24-bibliography.md └── 01-introduction.md ├── FORMATTING.md ├── README.md └── tools ├── README.md ├── add_hh_fixme_to_tests.php ├── add_language_to_code_blocks.php └── toc.php /tests/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Enums/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Shapes/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Traits/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Tuples/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Attributes/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Collections/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Constants/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Enums/enums.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Functions/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Generics/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Interfaces/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Namespaces/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Statements/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/bool.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/enum.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/float.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/mixed.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/tuple.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Variables/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Basic_Concepts/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/Aircraft.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/MyList.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/Point.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/Point2.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/Vehicle.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Generics/Complex.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Generics/Stack.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Lexical_Structure/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Namespaces/Point.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Nullable_Types/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Serialization/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Shapes/shapes_rf.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Statements/Jump/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Tuples/tuples.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/shapes_rf.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/string.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/MathLibrary.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/MyCollection.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/PassengerJet.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Exception_Handling/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Functions/TestInc.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Functions/noreturn.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Generics/MyVector.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Interfaces/MyList.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Interfaces/MyQueue.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Namespaces/Circle.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Statements/Iteration/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Statements/Selection/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/determined_type.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/MathLibrary_test1.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/invoke.php.expect: -------------------------------------------------------------------------------- 1 | bool(true) -------------------------------------------------------------------------------- /tests/Enums/enum_constraints.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Unary_Operators/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Yield_Operator/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Interfaces/MyCollection.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Lexical_Structure/Tokens/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/Circle.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/Point.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/Positions.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/limits.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/mycolors.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Traits/trait_requirements.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/type_side_effects.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Basic_Concepts/top_level_stuff.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Additive_Operators/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Conditional_Operator/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Equality_Operators/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Instanceof_Operator/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Lambda_Expressions/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Relational_Operators/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Lexical_Structure/Tokens/names.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Namespaces/using_namespaces_3.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/return_none.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Statements/expression_statement.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Variables/predefined_variables.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/cc.php.expectf: -------------------------------------------------------------------------------- 1 | int(7) 2 | int(8) 3 | -------------------------------------------------------------------------------- /tests/Constants/core_predefined_constants.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Exception_Handling/MyRangeException.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Binary_Logical_Operators/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Bitwise_Shift_Operators/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Multiplicative_Operators/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Null_safe_method_call/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/new.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Functions/override_on_return_type.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Interfaces/interface_requirements.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Namespaces/use_groups_require_file.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/return_with_value.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Traits/trait_implements_interface.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Types/closure.php.expect: -------------------------------------------------------------------------------- 1 | int(10) 2 | int(25) -------------------------------------------------------------------------------- /tests/Classes/visibility.php.expect: -------------------------------------------------------------------------------- 1 | CON1: 123 2 | int(0) -------------------------------------------------------------------------------- /tests/Expressions/Bitwise_and_or_xor_Operators/.hhconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/Point.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/Point2.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Lexical_Structure/keywords.php.expect: -------------------------------------------------------------------------------- 1 | red white blue -------------------------------------------------------------------------------- /tests/Types/Issue_110.php.expect: -------------------------------------------------------------------------------- 1 | bool(true) 2 | bool(true) -------------------------------------------------------------------------------- /tests/Types/void.php.expect: -------------------------------------------------------------------------------- 1 | object(NS_void\C)#1 (0) { 2 | } -------------------------------------------------------------------------------- /tests/Expressions/Conditional_Operator/conditional.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/subscripting.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/classes.php.expect: -------------------------------------------------------------------------------- 1 | object(NS_classes\C2)#1 (0) { 2 | } -------------------------------------------------------------------------------- /tests/Classes/type_constants.php.expect: -------------------------------------------------------------------------------- 1 | string(3) "abc" 2 | int(123) -------------------------------------------------------------------------------- /tests/Expressions/Coalesce Operator/coalesce.php.expect: -------------------------------------------------------------------------------- 1 | bool(true) 2 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/nullable_and_arithmetic.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/intrinsics_invariant.php.expect: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/Classes/property_initializer.php.expect: -------------------------------------------------------------------------------- 1 | (0,0) 2 | (100,0) 3 | (1000,2000) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | www.pid 3 | .commit-template 4 | *.php.diff 5 | *.php.out 6 | -------------------------------------------------------------------------------- /tests/Expressions/limits_on_types_in_arithmetic.php.expect: -------------------------------------------------------------------------------- 1 | int(124) 2 | float(3.4) 3 | int(11) -------------------------------------------------------------------------------- /tests/Classes/Vehicle_test1.php.expect: -------------------------------------------------------------------------------- 1 | $pj's maximum speed: 550 2 | $pj's maximum altitude: 30000 -------------------------------------------------------------------------------- /tests/Classes/destructors.php.expect: -------------------------------------------------------------------------------- 1 | In D4 destructor 2 | In D3 destructor 3 | In D2 destructor -------------------------------------------------------------------------------- /tests/Basic_Concepts/program_structure.php: -------------------------------------------------------------------------------- 1 | closing tag not allowed 4 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/exponentiation.php.expect: -------------------------------------------------------------------------------- 1 | =========== some basic tests =========== -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/nullsafe_member_selection.php.expect: -------------------------------------------------------------------------------- 1 | int(5) 2 | string(5) "Hello" -------------------------------------------------------------------------------- /tests/Lexical_Structure/comments.php.expect: -------------------------------------------------------------------------------- 1 | int(567) 2 | int(5) 3 | int(5) 4 | int(6) 5 | int(5) 6 | int(6) -------------------------------------------------------------------------------- /tests/Namespaces/using_namespaces_3_test.php.expect: -------------------------------------------------------------------------------- 1 | object(NS18\D)#1 (0) { 2 | } 3 | CON1 = 100 4 | In NS17\f -------------------------------------------------------------------------------- /tests/Expressions/Unary_Operators/cast.php.expect: -------------------------------------------------------------------------------- 1 | bool(false) 2 | int(0) 3 | float(0) 4 | string(1) "0" 5 | int(0) -------------------------------------------------------------------------------- /tests/Types/this.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: Traits cannot have constants in %s/tests/Types/this.php on line 9 -------------------------------------------------------------------------------- /tests/Exception_Handling/hierarchy_of_exception_classes.php.expect: -------------------------------------------------------------------------------- 1 | In handler for DeviceException 2 | In finally block -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/function_call.php.expect: -------------------------------------------------------------------------------- 1 | Inside function NS_function_call\f 2 | 2, 3, 3, 12, 11 -------------------------------------------------------------------------------- /tests/Namespaces/using_namespaces_1.php.expect: -------------------------------------------------------------------------------- 1 | $p1 = (3,5) 2 | $p1 = (-3,8) 3 | $c1 = [(2,4):3.6] 4 | $c2 = [(1,-2):1.4] -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/primary.php.expect: -------------------------------------------------------------------------------- 1 | int(110) 2 | int(100) 3 | int(100) 4 | int(100) 5 | int(6) 6 | int(6) -------------------------------------------------------------------------------- /tests/Script_Inclusion/return_none.php: -------------------------------------------------------------------------------- 1 | S'o'me "\"t e xt; $v = 123" 2 | Some more text< 3 | 4 | string(0) "" 5 | string(7) "xxx 6 | yyy" -------------------------------------------------------------------------------- /tests/Lexical_Structure/Tokens/nowdoc_string_literals.php.expect: -------------------------------------------------------------------------------- 1 | >S'o'me "\"t e\txt; \$v = $v" 2 | Some more text< 3 | 4 | string(0) "" 5 | string(7) "xxx 6 | yyy" -------------------------------------------------------------------------------- /tests/Expressions/Unary_Operators/error_control.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Warning: No such file or directory in %s/tests/Expressions/Unary_Operators/error_control.php on line 6 -------------------------------------------------------------------------------- /tests/Functions/TestInc.php: -------------------------------------------------------------------------------- 1 | (0,0)< 2 | $p1 is >(3,9)< 3 | int(555) 4 | int(123) 5 | int(999) 6 | float(3.14159) 7 | Hello from f -------------------------------------------------------------------------------- /tests/Lexical_Structure/Tokens/integer_literals_edge_cases.php.expect: -------------------------------------------------------------------------------- 1 | int(-9223372036854775808) 2 | int(9223372036854775807) 3 | int(9223372036854775807) 4 | int(9223372036854775807) -------------------------------------------------------------------------------- /tests/Classes/test_for_new_types.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: syntax error, unexpected T_LNUMBER, expecting T_VARIABLE or T_PIPE_VAR or '$' in %s/tests/Classes/test_for_new_types.php on line 18 -------------------------------------------------------------------------------- /tests/Script_Inclusion/Positions.php: -------------------------------------------------------------------------------- 1 | >1|123<< 2 | >>1|123<< 3 | >>1|123<< 4 | >>1|123<< 5 | >>2030||Hello|(3,5)<< 6 | >>2030||Hello|(3,5)<< 7 | string(9) "qqq123zzz" 8 | qqq123zzz -------------------------------------------------------------------------------- /tests/Script_Inclusion/Point.php: -------------------------------------------------------------------------------- 1 | not allowed (Line: 3, Char: 30) 3 | syntax error, unexpected T_HH_ERROR, expecting $end in %s/tests/Basic_Concepts/program_structure.php on line 3 -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/array_creation.php.expect: -------------------------------------------------------------------------------- 1 | array(5) { 2 | [1]=> 3 | int(10) 4 | ["xx"]=> 5 | int(20) 6 | [4]=> 7 | int(30) 8 | [0]=> 9 | int(40) 10 | [-10]=> 11 | int(50) 12 | } -------------------------------------------------------------------------------- /tests/Expressions/Yield_Operator/yield.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: HH mode: content before prop = 100 5 | In try-block 6 | In catch-block Except 7 | $e->prop = 100 8 | $e->prop = 999 9 | $o->prop = 999 -------------------------------------------------------------------------------- /tests/Expressions/Yield_Operator/yield_from.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: HH mode: content before 7 | int(3) 8 | } 9 | array(2) { 10 | [0]=> 11 | int(3) 12 | [1]=> 13 | bool(true) 14 | } -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/new_anonymous_classes.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: HH mode: content before { 6 | const int MAX_NUMBER_ITEMS = 1000; 7 | 8 | public function put(T $item): void; 9 | public function get(): T; 10 | } 11 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/scope_resolution_operator.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Fatal error: HH mode: content before 7 | int(10) 8 | ["green"]=> 9 | int(15) 10 | ["white"]=> 11 | int(20) 12 | } 13 | object(NS_type_inferencing\C)#1 (0) { 14 | } -------------------------------------------------------------------------------- /tests/Statements/Jump/continue.php.expect: -------------------------------------------------------------------------------- 1 | 1 is odd 2 | 3 is odd 3 | 5 is odd 4 | 5 | $i = 10: ten 6 | Just beyond the switch 7 | $i = 20: 8 | Just beyond the switch 9 | $i = 30: thirty 10 | Just beyond the switch 11 | $i = 40: 12 | Just beyond the switch 13 | ---------- -------------------------------------------------------------------------------- /tests/Types/shapes.php.expectf: -------------------------------------------------------------------------------- 1 | ----------- Play ------------ 2 | 3 | ----------- Create some shape values ------------ 4 | 5 | $point1 is -3 6 | shape(...)['y'] is 6 7 | 8 | Fatal error: Call to undefined function NS_shapes_rf\Point_toString() in %s/tests/Types/shapes.php on line 62 -------------------------------------------------------------------------------- /tests/Namespaces/using_namespaces_3_test.php: -------------------------------------------------------------------------------- 1 | 10, 'xx' => 20, 4.5 => 30, false => 40, '-10' => 50]; 7 | var_dump($a); 8 | } 9 | 10 | /* HH_FIXME[1002] call to main in strict*/ 11 | main(); 12 | 13 | -------------------------------------------------------------------------------- /tests/Expressions/Multiplicative_Operators/multiplication_division_modulus.php.expect: -------------------------------------------------------------------------------- 1 | >100< % >100<, result: int(0) 2 | >100< % >-3<, result: int(1) 3 | ------------------------------------- 4 | >-3< % >100<, result: int(-3) 5 | >-3< % >-3<, result: int(0) 6 | ------------------------------------- 7 | >11< % >3<, result: int(2) -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/new.php: -------------------------------------------------------------------------------- 1 | >[2:2:2:2:2:2:2]<< 2 | $iv1: >>[2:55:2:-15:2:6:2]<< 3 | $sv1: >>[X:X:X:X:X]<< 4 | $sv1: >>[X:AB:X:XZZ:X]<< 5 | $viv: >>[[-1:-1]:[-1:-1]:[-1:-1]]<< 6 | $viv: >>[[1:1]:[2:2:2:2]:[5:5:5]]<< 7 | $res: >>[[1:1]:[2:55:2:-15:2:6:2]:[5:5:5]]<< 8 | $viv: >>[[1:1]:[2:55:2:-15:2:6:2]:[5:5:5]]<< -------------------------------------------------------------------------------- /tests/Namespaces/namespaces1.php.expect: -------------------------------------------------------------------------------- 1 | Inside function NS1\f1, namespace NS1 2 | Inside function NS1\Sub1\f2, namespace NS1\Sub1 3 | Inside function NS2\f3, namespace NS2 4 | Inside function NS3\Sub1\f4, namespace NS3\Sub1 5 | Inside function NS3\Sub1\f5, namespace NS3\Sub1 6 | Inside function NS3\Sub1\C1::f, namespace NS3\Sub1 -------------------------------------------------------------------------------- /tests/Statements/Iteration/do.php: -------------------------------------------------------------------------------- 1 | prop = $val; 11 | } 12 | 13 | public function getProp(): bool { 14 | return $this->prop; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/Classes/classes.php: -------------------------------------------------------------------------------- 1 | prop = $val; 11 | } 12 | 13 | public function getProp(): float { 14 | return $this->prop; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/Types/mixed.php: -------------------------------------------------------------------------------- 1 | prop = $val; 11 | } 12 | 13 | public function getProp(): mixed { 14 | return $this->prop; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/Functions/anonymous_function_name.php.expect: -------------------------------------------------------------------------------- 1 | __FUNCTION__ = NS_anonymous_function_name\main 2 | __METHOD__ = NS_anonymous_function_name\main 3 | __FUNCTION__ = {closure} 4 | __METHOD__ = {closure} 5 | __FUNCTION__ = f 6 | __METHOD__ = NS_anonymous_function_name\C::f 7 | __FUNCTION__ = {closure} 8 | __METHOD__ = NS_anonymous_function_name\C::{closure} -------------------------------------------------------------------------------- /tests/Types/string.php: -------------------------------------------------------------------------------- 1 | prop = $val; 11 | } 12 | 13 | public function getProp(): string { 14 | return $this->prop; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/require.php.expectf: -------------------------------------------------------------------------------- 1 | MY_MIN is not defined 2 | Array 3 | ( 4 | [0] => %s/tests/Script_Inclusion/require.php 5 | [1] => %s/tests/Script_Inclusion/limits.php 6 | [2] => %s/tests/Script_Inclusion/mycolors.php 7 | [3] => %s/tests/Script_Inclusion/return_none.php 8 | [4] => %s/tests/Script_Inclusion/return_with_value.php 9 | ) -------------------------------------------------------------------------------- /tests/Enums/enums_ops.php.expect: -------------------------------------------------------------------------------- 1 | 2 | ====== various operations on int and string enums ====== 3 | 4 | 5 | ______ < 6 | bool(true) 7 | ______ >= 8 | bool(false) 9 | 10 | ______ < 11 | bool(false) 12 | ______ >= 13 | bool(true) 14 | 15 | ______ == 16 | bool(false) 17 | ______ !== 18 | bool(true) 19 | 20 | ______ == 21 | bool(false) 22 | ______ !== 23 | bool(true) -------------------------------------------------------------------------------- /tests/Classes/MyList.php: -------------------------------------------------------------------------------- 1 | 3 | object(NS_contravariance_example\Animal)#2 (0) { 4 | } 5 | } 6 | object(NS_contravariance_example\C)#1 (1) { 7 | ["t":"NS_contravariance_example\C":private]=> 8 | object(NS_contravariance_example\Cat)#2 (0) { 9 | } 10 | } -------------------------------------------------------------------------------- /tests/Statements/Iteration/for.php.expect: -------------------------------------------------------------------------------- 1 | 1 1 2 | 2 4 3 | 3 9 4 | 4 16 5 | 5 25 6 | 6 36 7 | 7 49 8 | 8 64 9 | 9 81 10 | 10 100 11 | 1 1 12 | 2 4 13 | 3 9 14 | 4 16 15 | 5 25 16 | 6 36 17 | 7 49 18 | 8 64 19 | 9 81 20 | 10 100 21 | 1 1 22 | 2 4 23 | 3 9 24 | 4 16 25 | 5 25 26 | 6 36 27 | 7 49 28 | 8 64 29 | 9 81 30 | 10 100 31 | 2 100 32 | 4 90 33 | 6 80 34 | 8 70 35 | 10 60 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Facebook has dedicated all copyright to this specification to the public 2 | domain worldwide under the CC0 Public Domain Dedication located at 3 | . 4 | 5 | The first draft of this specification was initially written in 2015 by 6 | Facebook, Inc. 7 | 8 | This specification is distributed without any warranty. 9 | 10 | -------------------------------------------------------------------------------- /tests/Serialization/serialize.php: -------------------------------------------------------------------------------- 1 | implements MyCollection { 8 | private array $list = array(); 9 | 10 | public function put(T $item): void { 11 | // ... 12 | } 13 | 14 | public function get(): T { 15 | // ... 16 | return $this->list[0]; 17 | } 18 | 19 | // ... 20 | } 21 | -------------------------------------------------------------------------------- /tests/Interfaces/MyQueue.php: -------------------------------------------------------------------------------- 1 | implements MyCollection { 8 | private array $list = array(); 9 | 10 | public function put(T $item): void { 11 | // ... 12 | } 13 | 14 | public function get(): T { 15 | // ... 16 | return $this->list[0]; 17 | } 18 | 19 | // ... 20 | } 21 | -------------------------------------------------------------------------------- /tests/Exception_Handling/MyRangeException_test1.php: -------------------------------------------------------------------------------- 1 | $re<\n"; 14 | } 15 | 16 | /* HH_FIXME[1002] call to main in strict*/ 17 | main(); 18 | -------------------------------------------------------------------------------- /tests/Basic_Concepts/top_level_stuff.php: -------------------------------------------------------------------------------- 1 | getMaxSpeed() . "\n"; 10 | echo "\$pj's maximum altitude: " . $pj->getMaxAltitude() . "\n"; 11 | } 12 | 13 | /* HH_FIXME[1002] call to main in strict*/ 14 | main(); 15 | -------------------------------------------------------------------------------- /tests/Types/tuple.php: -------------------------------------------------------------------------------- 1 | prop = $val; 11 | } 12 | 13 | public function getProp(): (int, string) { 14 | return $this->prop; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/Classes/test_for_new_types.php: -------------------------------------------------------------------------------- 1 | 10< 4 | f1: # arguments passed is 2 5 | arg[0] = >1< 6 | arg[1] = >green< 7 | f1: # arguments passed is 3 8 | arg[0] = >23.45< 9 | arg[1] = >< 10 | 11 | Notice: Array to string conversion in %s/tests/Functions/basics.php on line 17 12 | arg[2] = >Array< 13 | f2: $p1 = 10, $p2 = 20 14 | 5 squared = 25 15 | 7 16 | object(HH\Vector)#3 (0) { 17 | } -------------------------------------------------------------------------------- /tests/Classes/MathLibrary_test1.php: -------------------------------------------------------------------------------- 1 | 7 | int(10) 8 | ["pr3":protected]=> 9 | int(30) 10 | ["pr5"]=> 11 | int(50) 12 | ["p2":"NS_constructors\C2":private]=> 13 | int(20) 14 | ["p4":protected]=> 15 | float(40) 16 | ["p6"]=> 17 | string(3) "xxx" 18 | } 19 | 50 20 | xxx -------------------------------------------------------------------------------- /tests/Classes/dynamic_methods.php.expect: -------------------------------------------------------------------------------- 1 | Calling instance method >iMethod< 2 | array(3) { 3 | [0]=> 4 | int(10) 5 | [1]=> 6 | bool(true) 7 | [2]=> 8 | string(3) "abc" 9 | } 10 | Calling static method >sMethod< 11 | array(2) { 12 | [0]=> 13 | NULL 14 | [1]=> 15 | float(1.234) 16 | } 17 | Calling static method >sMethod< 18 | array(2) { 19 | [0]=> 20 | NULL 21 | [1]=> 22 | float(1.234) 23 | } 24 | Calling static method >[]{}< 25 | array(0) { 26 | } -------------------------------------------------------------------------------- /tests/Generics/constraints.php.expect: -------------------------------------------------------------------------------- 1 | object(NS_generics_constraints\C1a)#1 (1) { 2 | ["p1":"NS_generics_constraints\C1a":private]=> 3 | bool(true) 4 | } 5 | object(NS_generics_constraints\C1a)#2 (1) { 6 | ["p1":"NS_generics_constraints\C1a":private]=> 7 | bool(false) 8 | } 9 | Inside NS_generics_constraints\C2::__construct 10 | Inside NS_generics_constraints\C2::__construct 11 | =============== maxVal ================== 12 | 13 | maxVal(10, 20) = 20 14 | maxVal(15.6, -20.78) = 15.6 -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to the Specification for Hack 2 | 3 | We'd love your help in improving, correcting, adding to the specification. 4 | Please [file an issue](https://github.com/hhvm/hack-langspec/issues/) or submit a 5 | pull request at the [spec git repo](https://github.com/hhvm/hack-langspec). 6 | 7 | ## License for your Contributions 8 | 9 | Any contribution you provide to the Specification for Hack must adhere to the 10 | same license as stated in the [LICENSE](LICENSE). 11 | -------------------------------------------------------------------------------- /tests/Generics/generic_function.php.expect: -------------------------------------------------------------------------------- 1 | =============== maxVal ================== 2 | 3 | maxVal(10, 20) = 20 4 | maxVal(20, 10) = 20 5 | maxVal(10, 10) = 10 6 | maxVal(15.6, -20.78) = 15.6 7 | maxVal('red', 'green') = red 8 | maxVal(10, 20.5) = 20.5 9 | float(20.5) 10 | maxVal(20.5, 10) = 20.5 11 | float(20.5) 12 | maxVal(0, true) = 1 13 | bool(true) 14 | maxVal(1, false) = 1 15 | int(1) 16 | 17 | =============== arrayCopy ================== 18 | 19 | array(1) { 20 | [0]=> 21 | int(0) 22 | } -------------------------------------------------------------------------------- /tests/Variables/predefined_variables.php: -------------------------------------------------------------------------------- 1 | 1) ? $int * factorial($int - 1) : $int; 16 | } 17 | 18 | /* HH_FIXME[1002] call to main in strict*/ 19 | main(); 20 | -------------------------------------------------------------------------------- /tests/Namespaces/Circle.php: -------------------------------------------------------------------------------- 1 | center = new Point($x, $y); 14 | $this->radius = $radius; 15 | } 16 | 17 | public function __toString(): string { 18 | return '[' . $this->center . ':' . $this->radius . ']'; 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /tests/Functions/callable_typehint.php: -------------------------------------------------------------------------------- 1 | $s<\n\n"; 15 | 16 | var_dump(<<$s<\n\n"; 15 | 16 | var_dump(<<<'X' 17 | X 18 | ); 19 | 20 | var_dump(<<<'X' 21 | xxx 22 | yyy 23 | X 24 | ); 25 | } 26 | 27 | /* HH_FIXME[1002] call to main in strict*/ 28 | main(); 29 | -------------------------------------------------------------------------------- /tests/Types/Issue_110.php: -------------------------------------------------------------------------------- 1 | $p1 = C::class; 7 | public static string $str = 'Issue_110\C'; 8 | 9 | public static function sf1(): void { 10 | var_dump(C::$str == C::$p1); // value-equality 11 | } 12 | public static function sf2(): void { 13 | var_dump(C::$str === C::$p1); // same-type-and-value-equality 14 | } 15 | } 16 | 17 | function main(): void { 18 | C::sf1(); 19 | C::sf2(); 20 | } 21 | 22 | /* HH_FIXME[1002] call to main in strict*/ 23 | main(); -------------------------------------------------------------------------------- /tests/Statements/Iteration/while.php: -------------------------------------------------------------------------------- 1 | 35.3< 2 | define CON2 succeeded; value is >15< 3 | define CON3 succeeded; value is >15< 4 | define CON4 succeeded; value is >15< 5 | define CON5 succeeded; value is >16< 6 | define CON6 succeeded; value is >16< 7 | define CON7 succeeded; value is >15< 8 | define CON8 succeeded; value is >1024< 9 | define CON9 succeeded; value is >< 10 | define CON10 succeeded; value is >123< 11 | define CON11 succeeded; value is >150< 12 | define CON21 succeeded; value is >36.3< 13 | define CON22 succeeded; value is >65.3< -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/primary.php: -------------------------------------------------------------------------------- 1 | 6 | array(0) { 7 | } 8 | } 9 | object(NS_MyCollectionClasses\MyQueue)#2 (1) { 10 | ["list":"NS_MyCollectionClasses\MyQueue":private]=> 11 | array(0) { 12 | } 13 | } 14 | object(NS_MyCollectionClasses\MyQueue)#3 (1) { 15 | ["list":"NS_MyCollectionClasses\MyQueue":private]=> 16 | array(0) { 17 | } 18 | } 19 | int(1000) 20 | int(1000) 21 | int(1000) -------------------------------------------------------------------------------- /tests/Types/resources.php.expectf: -------------------------------------------------------------------------------- 1 | resource(1) of type (stream) 2 | bool(true) 3 | string(6) "stream" 4 | resource(2) of type (stream) 5 | bool(true) 6 | string(6) "stream" 7 | resource(3) of type (stream) 8 | bool(true) 9 | string(6) "stream" 10 | 11 | Warning: No such file or directory in %s/tests/Types/resources.php on line 35 12 | bool(false) 13 | 14 | 15 | 16 | Warning: No such file or directory in %s/tests/Types/resources.php on line 41 17 | bool(false) 18 | object(NS_resources\C)#1 (1) { 19 | ["prop":"NS_resources\C":private]=> 20 | resource(2) of type (stream) 21 | } -------------------------------------------------------------------------------- /tests/Lexical_Structure/Tokens/unicode_escape_sequences.php.expect: -------------------------------------------------------------------------------- 1 | ================= Basic checks ================= 2 | 3 | string(3) ">A<" 4 | string(8) ">\U{41}<" 5 | string(3) ">A<" 6 | string(3) ">A<" 7 | string(3) ">A<" 8 | string(3) ">A<" 9 | string(4) ">©<" 10 | string(4) ">©<" 11 | string(4) ">©<" 12 | string(4) ">æ<" 13 | string(5) ">†<" 14 | string(6) ">𠀀<" 15 | string(6) ">𠀀<" 16 | string(6) ">􏿿<" 17 | 18 | ================= Is variable substitution allowed? ================= 19 | 20 | string(4) ">41<" 21 | string(5) ">041<" 22 | string(5) ">041<" 23 | string(6) ">\u41<" -------------------------------------------------------------------------------- /tests/Traits/traits.php.expect: -------------------------------------------------------------------------------- 1 | === display some __***__ values === 2 | 3 | Inside >NS_traits\main< 4 | Inside >NS_traits\main< 5 | 6 | === Play with C5a and C5b === 7 | 8 | 123 9 | 43.56 10 | 11 | === Play with C6a === 12 | 13 | Inside NS_traits\T6::f 14 | $v = 0 15 | Inside NS_traits\T6::f 16 | $v = 1 17 | 18 | === Play with C6b === 19 | 20 | Inside NS_traits\T6::f 21 | $v = 0 22 | Inside NS_traits\T6::f 23 | $v = 1 24 | Inside NS_traits\T6::f 25 | $v = 2 26 | 27 | === Play with T7 === 28 | 29 | ------- 30 | Inside NS_traits\T7 31 | Inside NS_traits\T7 32 | Inside NS_traits\T7::g -------------------------------------------------------------------------------- /tests/Types/shape_subtyping.php.expect: -------------------------------------------------------------------------------- 1 | array(3) { 2 | ["trtype"]=> 3 | int(1) 4 | ["toaccnum"]=> 5 | int(23456) 6 | ["amount"]=> 7 | float(100) 8 | } 9 | Deposit: 100 to Account 23456 10 | array(3) { 11 | ["trtype"]=> 12 | int(2) 13 | ["fromaccnum"]=> 14 | int(3157) 15 | ["amount"]=> 16 | float(100) 17 | } 18 | Withdrawal: 100 from Account 3157 19 | array(4) { 20 | ["trtype"]=> 21 | int(3) 22 | ["fromaccnum"]=> 23 | int(23456) 24 | ["toaccnum"]=> 25 | int(3157) 26 | ["amount"]=> 27 | float(100) 28 | } 29 | Transfer: 100 from Account 23456 to Account 3157 -------------------------------------------------------------------------------- /tests/Statements/Jump/break.php: -------------------------------------------------------------------------------- 1 | ++/--/-- 30 | int(6) 31 | int(5) 32 | int(4) -------------------------------------------------------------------------------- /tests/Traits/trait_implements_interface.php: -------------------------------------------------------------------------------- 1 | f(); } 15 | } 16 | 17 | class C { // implicit implements clause 18 | use T; 19 | public function f(): void {} 20 | public function g(): void {} 21 | } 22 | 23 | class C2 implements I1, I2 { // explicit implements clause 24 | use T; 25 | public function f(): void {} 26 | public function g(): void {} 27 | } -------------------------------------------------------------------------------- /tests/Lexical_Structure/Tokens/array_literals.php: -------------------------------------------------------------------------------- 1 | $prop10 = array(); 7 | private array $prop11 = array(10, "red", true); 8 | private array $prop12 = array('a' => 10, 'r' => array(20,30)); 9 | 10 | private array $prop20 = []; 11 | private array $prop21 = [10, "red", true]; 12 | private array $prop22 = ['a' => 10, 'r' => [20,30]]; 13 | } 14 | 15 | function main(): void { 16 | $x = new X(); 17 | var_dump($x); 18 | } 19 | 20 | /* HH_FIXME[1002] call to main in strict*/ 21 | main(); 22 | -------------------------------------------------------------------------------- /tests/Script_Inclusion/require_once.php: -------------------------------------------------------------------------------- 1 | prop = $val; 18 | } 19 | 20 | public function getProp(): ControlStatus { 21 | return $this->prop; 22 | } 23 | } 24 | 25 | function main(): void { 26 | } 27 | 28 | /* HH_FIXME[1002] call to main in strict*/ 29 | main(); 30 | -------------------------------------------------------------------------------- /tests/Functions/this_play.php.expect: -------------------------------------------------------------------------------- 1 | object(NS_this_play\Base)#1 (2) { 2 | ["pr1":"NS_this_play\Base":private]=> 3 | NULL 4 | ["x":"NS_this_play\Base":private]=> 5 | int(10) 6 | } 7 | object(NS_this_play\Base)#1 (2) { 8 | ["pr1":"NS_this_play\Base":private]=> 9 | NULL 10 | ["x":"NS_this_play\Base":private]=> 11 | int(10) 12 | } 13 | object(NS_this_play\Derived)#2 (2) { 14 | ["pr1":"NS_this_play\Base":private]=> 15 | NULL 16 | ["x":"NS_this_play\Base":private]=> 17 | int(20) 18 | } 19 | object(NS_this_play\Derived)#2 (2) { 20 | ["pr1":"NS_this_play\Base":private]=> 21 | NULL 22 | ["x":"NS_this_play\Base":private]=> 23 | int(20) 24 | } -------------------------------------------------------------------------------- /tests/Expressions/Relational_Operators/relational_comparison_of_objects.php.expect: -------------------------------------------------------------------------------- 1 | 2 | ===== compare instances of the same (empty) object type ===== 3 | 4 | bool(true) 5 | bool(false) 6 | bool(true) 7 | bool(false) 8 | 9 | ===== compare instances of the same object type with same values ===== 10 | 11 | bool(true) 12 | bool(false) 13 | bool(true) 14 | bool(false) 15 | 16 | ===== compare instances of the same object type with diff values ===== 17 | 18 | bool(false) 19 | bool(false) 20 | bool(true) 21 | bool(true) 22 | 23 | ===== compare instances of the same object type with a pair of diff values ===== 24 | 25 | bool(true) 26 | bool(true) 27 | bool(false) 28 | bool(false) -------------------------------------------------------------------------------- /tests/Script_Inclusion/require.php: -------------------------------------------------------------------------------- 1 | " . constant("MY_MIN") . "\n"; 17 | else 18 | echo "MY_MIN is not defined\n"; 19 | //*/ 20 | 21 | // get the set of included files 22 | 23 | print_r(get_included_files()); 24 | } 25 | 26 | /* HH_FIXME[1002] call to main in strict*/ 27 | main(); 28 | -------------------------------------------------------------------------------- /tests/Expressions/Instanceof_Operator/instanceof.php.expect: -------------------------------------------------------------------------------- 1 | bool(true) 2 | bool(false) 3 | bool(false) 4 | bool(true) 5 | bool(true) 6 | bool(false) 7 | -------------------- 8 | bool(true) 9 | bool(false) 10 | bool(true) 11 | -------------------- 12 | bool(false) 13 | bool(true) 14 | bool(false) 15 | -------------------- 16 | bool(true) 17 | bool(false) 18 | bool(true) 19 | ------- Interfaces ------------- 20 | bool(true) 21 | bool(true) 22 | bool(true) 23 | ------- Non-Instances ------------- 24 | bool(false) 25 | bool(false) 26 | bool(false) 27 | bool(false) 28 | ------- Non-class/Non-interface types ------------- 29 | bool(true) 30 | bool(false) 31 | bool(true) 32 | bool(true) 33 | bool(true) -------------------------------------------------------------------------------- /tests/Types/void.php: -------------------------------------------------------------------------------- 1 | prop = v(); // the default (null) value "returned" from a void function is used 17 | } 18 | */ 19 | // public function setProp(void $val): void { 20 | // $this->prop = $val; 21 | // } 22 | 23 | public function getProp(): void { 24 | } 25 | } 26 | 27 | function main(): void { 28 | $c = new C(); 29 | var_dump($c); 30 | } 31 | 32 | /* HH_FIXME[1002] call to main in strict*/ 33 | main(); 34 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/function_call_with_strict_checking.php: -------------------------------------------------------------------------------- 1 | { 7 | public function __construct(private T1 $t1, private T2 $t2, private T3 $t3) {} 8 | } 9 | */ 10 | 11 | class C<-T> { 12 | public function __construct(private T $t) {} 13 | } 14 | 15 | class Animal {} 16 | class Cat extends Animal {} 17 | 18 | function f(C $p1): void { var_dump($p1); } 19 | 20 | function main(): void { 21 | // UNSAFE (type error - this is not accepted) 22 | f(new C(new Animal())); // accepted 23 | // UNSAFE (type error - this is not accepted) 24 | f(new C(new Cat())); 25 | } 26 | 27 | /* HH_FIXME[1002] call to main in strict*/ 28 | main(); 29 | -------------------------------------------------------------------------------- /tests/Classes/abstract_constants.php: -------------------------------------------------------------------------------- 1 | value = $value; 16 | } 17 | 18 | public function getValue() { 19 | return $this->value; 20 | } 21 | } 22 | 23 | $three = new Value(3); 24 | $four = new Value(4); 25 | 26 | $closure = function ($delta) { var_dump($this->getValue() + $delta); }; 27 | $closure->call($three, 4); 28 | $closure->call($four, 4); -------------------------------------------------------------------------------- /tests/Functions/anonymous_functions2.php.expect: -------------------------------------------------------------------------------- 1 | =========== $doubler1 =============== 2 | 3 | int(3) 4 | int(6) 5 | float(4.2) 6 | float(8.4) 7 | int(10) 8 | int(20) 9 | 10 | =========== $doubler2 =============== 11 | 12 | int(3) 13 | float(6) 14 | float(4.2) 15 | float(8.4) 16 | int(10) 17 | float(20) 18 | 19 | =========== $doubler3 =============== 20 | 21 | int(3) 22 | int(6) 23 | =========== $doubler1 =============== 24 | 25 | int(3) 26 | int(6) 27 | float(4.2) 28 | float(8.4) 29 | float(1.3) 30 | float(2.6) 31 | 32 | =========== $doubler2 =============== 33 | 34 | int(3) 35 | float(6) 36 | float(4.2) 37 | float(8.4) 38 | float(1.3) 39 | float(2.6) 40 | 41 | =========== $doubler3 =============== 42 | 43 | int(3) 44 | int(6) -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/Point2.php: -------------------------------------------------------------------------------- 1 | x = $x; 17 | $this->y = $y; 18 | ++self::$pointCount; 19 | } 20 | 21 | public function __destruct() { 22 | --self::$pointCount; 23 | } 24 | 25 | public function __toString(): string { 26 | return '(' . $this->x . ',' . $this->y . ')'; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/Types/int.php: -------------------------------------------------------------------------------- 1 | prop = $val; 11 | } 12 | 13 | public function getProp(): int { 14 | return $this->prop; 15 | } 16 | } 17 | 18 | function main(): void { 19 | var_dump(-PHP_INT_MAX - 1); 20 | var_dump(-PHP_INT_MAX - 1 - 1); // wraps to max positive 21 | 22 | var_dump(PHP_INT_MAX); 23 | var_dump(PHP_INT_MAX + 1); // wraps to min negative 24 | 25 | var_dump(PHP_INT_MAX/2 + PHP_INT_MAX); // converts to float 26 | 27 | var_dump(PHP_INT_MIN); // added in PHP7 28 | } 29 | 30 | /* HH_FIXME[1002] call to main in strict*/ 31 | main(); 32 | -------------------------------------------------------------------------------- /tests/Generics/covariance_example.php.expect: -------------------------------------------------------------------------------- 1 | object(NS_covariance_example\C)#1 (1) { 2 | ["t":"NS_covariance_example\C":private]=> 3 | object(NS_covariance_example\Animal)#2 (0) { 4 | } 5 | } 6 | object(NS_covariance_example\C)#1 (1) { 7 | ["t":"NS_covariance_example\C":private]=> 8 | object(NS_covariance_example\Cat)#2 (0) { 9 | } 10 | } 11 | array(2) { 12 | [0]=> 13 | object(NS_covariance_example\Animal)#1 (0) { 14 | } 15 | [1]=> 16 | object(NS_covariance_example\Animal)#2 (0) { 17 | } 18 | } 19 | array(3) { 20 | [0]=> 21 | object(NS_covariance_example\Cat)#2 (0) { 22 | } 23 | [1]=> 24 | object(NS_covariance_example\Cat)#3 (0) { 25 | } 26 | [2]=> 27 | object(NS_covariance_example\Animal)#4 (0) { 28 | } 29 | } -------------------------------------------------------------------------------- /tests/Generics/covariance_example.php: -------------------------------------------------------------------------------- 1 | { // equivalent to the following line, as type parameters are covariant by default 6 | class C<+T> { 7 | public function __construct(private T $t) {} 8 | } 9 | 10 | class Animal {} 11 | class Cat extends Animal {} 12 | 13 | function f(C $p1): void { var_dump($p1); } 14 | 15 | function g(array $p1): void { var_dump($p1); } 16 | 17 | function main(): void { 18 | f(new C(new Animal())); 19 | f(new C(new Cat())); // accepted 20 | 21 | g(array(new Animal(), new Animal())); 22 | g(array(new Cat(), new Cat(), new Animal())); // arrays are covariant 23 | } 24 | 25 | /* HH_FIXME[1002] call to main in strict*/ 26 | main(); 27 | -------------------------------------------------------------------------------- /tests/Expressions/Unary_Operators/pre-increment_and_decrement_integer_edge_cases.php.expect: -------------------------------------------------------------------------------- 1 | --- start incdec --- 2 | int(-9223372036854775808) 3 | int(9223372036854775807) 4 | int(9223372036854775806) 5 | int(9223372036854775807) 6 | int(-9223372036854775808) 7 | int(-9223372036854775808) 8 | int(9223372036854775807) 9 | int(9223372036854775806) 10 | int(9223372036854775807) 11 | int(-9223372036854775808) 12 | --- end incdec --- 13 | --- start incdecrev --- 14 | int(9223372036854775807) 15 | int(-9223372036854775808) 16 | int(-9223372036854775807) 17 | int(-9223372036854775808) 18 | int(9223372036854775807) 19 | int(9223372036854775807) 20 | int(-9223372036854775808) 21 | int(-9223372036854775807) 22 | int(-9223372036854775808) 23 | int(9223372036854775807) 24 | --- end incdecrev --- -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/post-increment_and_decrement_integer_edge_cases.php.expect: -------------------------------------------------------------------------------- 1 | --- start incdec --- 2 | int(-9223372036854775808) 3 | int(9223372036854775807) 4 | int(9223372036854775806) 5 | int(9223372036854775807) 6 | int(-9223372036854775808) 7 | int(-9223372036854775808) 8 | int(9223372036854775807) 9 | int(9223372036854775806) 10 | int(9223372036854775807) 11 | int(-9223372036854775808) 12 | --- end incdec --- 13 | --- start incdecrev --- 14 | int(9223372036854775807) 15 | int(-9223372036854775808) 16 | int(-9223372036854775807) 17 | int(-9223372036854775808) 18 | int(9223372036854775807) 19 | int(9223372036854775807) 20 | int(-9223372036854775808) 21 | int(-9223372036854775807) 22 | int(-9223372036854775808) 23 | int(9223372036854775807) 24 | --- end incdecrev --- -------------------------------------------------------------------------------- /tests/Lexical_Structure/Tokens/name_case_sensitivity.php: -------------------------------------------------------------------------------- 1 | x = $x; 11 | $this->y = $y; 12 | } 13 | 14 | public function __toString(): string { 15 | return '(' . $this->x . ',' . $this->y . ')'; 16 | } 17 | } 18 | 19 | function main(): void { 20 | $p = new Point(); 21 | echo $p . "\n"; 22 | 23 | $p = new Point(100.0); 24 | echo $p . "\n"; 25 | 26 | $p = new Point(1000.0, 2000.0); 27 | echo $p . "\n"; 28 | } 29 | 30 | /* HH_FIXME[1002] call to main in strict*/ 31 | main(); 32 | -------------------------------------------------------------------------------- /tests/Statements/Iteration/for.php: -------------------------------------------------------------------------------- 1 | 10) 23 | break; 24 | echo "$i\t".($i * $i)."\n"; // output a table of squares 25 | ++$i; 26 | } 27 | 28 | // use groups of expressions 29 | 30 | for ($a = 100, $i = 1; ++$i, $i <= 10; ++$i, $a -= 10) { 31 | echo "$i\t$a\n"; 32 | } 33 | } 34 | 35 | /* HH_FIXME[1002] call to main in strict*/ 36 | main(); 37 | -------------------------------------------------------------------------------- /tests/Expressions/Null_safe_method_call/null_safe_calls.php.expect: -------------------------------------------------------------------------------- 1 | ------------ test(new C()) 2 | ------------ $x?->f1(++$i, hello($i)) 3 | Inside NS_null_safe_calls\hello; $j = 6 4 | Inside NS_null_safe_calls\C::f1 5 | object(NS_null_safe_calls\D)#2 (0) { 6 | } 7 | ------------ $x?->f2(++$i, hello($i)) 8 | Inside NS_null_safe_calls\hello; $j = 7 9 | Inside NS_null_safe_calls\C::f2 10 | NULL 11 | ------------ $x?->f3(++$i, hello($i)) 12 | Inside NS_null_safe_calls\hello; $j = 8 13 | Inside NS_null_safe_calls\C::f3 14 | NULL 15 | ------------ test(null) 16 | ------------ $x?->f1(++$i, hello($i)) 17 | Inside NS_null_safe_calls\hello; $j = 6 18 | NULL 19 | ------------ $x?->f2(++$i, hello($i)) 20 | Inside NS_null_safe_calls\hello; $j = 7 21 | NULL 22 | ------------ $x?->f3(++$i, hello($i)) 23 | Inside NS_null_safe_calls\hello; $j = 8 24 | NULL -------------------------------------------------------------------------------- /tests/Statements/Selection/if.php.expectf: -------------------------------------------------------------------------------- 1 | Inside processTransaction 2 | Inside postMessage 3 | Line 2 4 | >10< is true int(10) 5 | >-100< is true int(-100) 6 | >0< is false int(0) 7 | >1.234< is true float(1.234) 8 | >0< is false float(0) 9 | >1< is true bool(true) 10 | >< is false bool(false) 11 | >< is false NULL 12 | >xx< is true string(2) "xx" 13 | >< is false string(0) "" 14 | 15 | Notice: Array to string conversion in %s/tests/Statements/Selection/if.php on line 37 16 | >Array< is true array(3) { 17 | [0]=> 18 | string(3) "red" 19 | [1]=> 20 | string(5) "white" 21 | [2]=> 22 | string(4) "blue" 23 | } 24 | object(NS_if\Name)#1 (2) { 25 | ["firstName":"NS_if\Name":private]=> 26 | string(3) "xxx" 27 | ["lastName":"NS_if\Name":private]=> 28 | string(3) "yyy" 29 | } 30 | >$aName< is true 31 | Path 1 32 | Path 3 33 | Path 1 -------------------------------------------------------------------------------- /tests/Types/type_inferencing.php: -------------------------------------------------------------------------------- 1 | 10, 'green' => 15, 'white' => 20); // $v has type map-like array of int 21 | var_dump($v); 22 | $v = new C(); // $v has type C 23 | var_dump($v); 24 | } 25 | 26 | function main (): void { 27 | f(); 28 | } 29 | 30 | /* HH_FIXME[1002] call to main in strict*/ 31 | main(); 32 | -------------------------------------------------------------------------------- /tests/Expressions/Equality_Operators/equality_comparison_of_objects.php.expect: -------------------------------------------------------------------------------- 1 | 2 | ===== compare instances of different object types ===== 3 | 4 | bool(false) 5 | bool(false) 6 | bool(true) 7 | bool(true) 8 | 9 | ===== compare instances of the same (empty) object type ===== 10 | 11 | bool(true) 12 | bool(false) 13 | bool(true) 14 | bool(false) 15 | bool(true) 16 | 17 | ===== compare instances of the same object type with same values ===== 18 | 19 | bool(true) 20 | bool(false) 21 | bool(true) 22 | bool(false) 23 | bool(true) 24 | 25 | ===== compare instances of the same object type with diff values ===== 26 | 27 | bool(false) 28 | bool(false) 29 | bool(true) 30 | bool(true) 31 | bool(true) 32 | 33 | ===== compare instances of the same object type with a pair of diff values ===== 34 | 35 | bool(false) 36 | bool(false) 37 | bool(true) 38 | bool(true) 39 | bool(true) -------------------------------------------------------------------------------- /tests/Expressions/Unary_Operators/cast.php: -------------------------------------------------------------------------------- 1 | 0) { 19 | ; // null statement 20 | } 21 | 22 | $i = 10; 23 | while ($i-- > 0) { 24 | continue; // in this context, equivalent to using a null statement 25 | } 26 | } 27 | 28 | /* HH_FIXME[1002] call to main in strict*/ 29 | main(); 30 | 31 | -------------------------------------------------------------------------------- /tests/Classes/destructors.php: -------------------------------------------------------------------------------- 1 | 0 6 | [1] => 100 7 | [2] => 67 8 | ) 9 | $min: 10, $max: 1100, 10 | $min: 20, $max: 2100 11 | $min: 30 12 | --------- test with more array elements than variables ------------- 13 | $min: 40, $max: 4100, $avg: 467 14 | Array 15 | ( 16 | [0] => 40 17 | [1] => 4100 18 | [2] => 467 19 | [3] => 22 20 | [4] => 33 21 | ) 22 | --------- test with target vars being array elements ------------- 23 | Array 24 | ( 25 | [4] => 567 26 | [2] => 5100 27 | [0] => 50 28 | ) 29 | Array 30 | ( 31 | [0] => 50 32 | [1] => 5100 33 | [2] => 567 34 | ) 35 | --------- test with no variables ------------- 36 | Array 37 | ( 38 | [0] => 0 39 | [1] => 100 40 | [2] => 67 41 | ) -------------------------------------------------------------------------------- /tests/Classes/Point2.php: -------------------------------------------------------------------------------- 1 | x = $x; 17 | $this->y = $y; 18 | ++self::$pointCount; 19 | } 20 | 21 | public function __destruct() { 22 | --self::$pointCount; 23 | } 24 | ///* 25 | public function __clone(): void { 26 | ++self::$pointCount; 27 | 28 | echo "Inside " . __METHOD__ . ", point count = " . self::$pointCount . "\n"; 29 | } 30 | //*/ 31 | 32 | public function __toString(): string { 33 | return '(' . $this->x . ',' . $this->y . ')'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/intrinsics_list.php.expect: -------------------------------------------------------------------------------- 1 | --------- test with full and omitted LHS vars ------------- 2 | $min: 0, $max: 100, $avg: 67 3 | Array 4 | ( 5 | [0] => 0 6 | [1] => 100 7 | [2] => 67 8 | ) 9 | $min: 10, $max: 1100, 10 | $min: 20, $max: 2100 11 | $min: 30 12 | --------- test with more array elements than variables ------------- 13 | $min: 40, $max: 4100, $avg: 467 14 | Array 15 | ( 16 | [0] => 40 17 | [1] => 4100 18 | [2] => 467 19 | [3] => 22 20 | [4] => 33 21 | ) 22 | --------- test with target vars being array elements ------------- 23 | Array 24 | ( 25 | [4] => 567 26 | [2] => 5100 27 | [0] => 50 28 | ) 29 | Array 30 | ( 31 | [0] => 50 32 | [1] => 5100 33 | [2] => 567 34 | ) 35 | --------- test with no variables ------------- 36 | Array 37 | ( 38 | [0] => 0 39 | [1] => 100 40 | [2] => 67 41 | ) -------------------------------------------------------------------------------- /tests/Functions/anonymous_function_name.php: -------------------------------------------------------------------------------- 1 | f(); 32 | } 33 | 34 | /* HH_FIXME[1002] call to main in strict*/ 35 | main(); 36 | -------------------------------------------------------------------------------- /tests/Namespaces/Point.php: -------------------------------------------------------------------------------- 1 | x; } 10 | public function setX(float $x): void { $this->x = $x; } 11 | public function getY(): float { return $this->y; } 12 | public function setY(float $y): void { $this->y = $y; } 13 | 14 | public function __construct(float $x = 0.0, float $y = 0.0) { 15 | $this->x = $x; 16 | $this->y = $y; 17 | } 18 | 19 | public function move(float $x, float $y): void { 20 | $this->x = $x; 21 | $this->y = $y; 22 | } 23 | 24 | public function translate(float $x, float $y): void { 25 | $this->x += $x; 26 | $this->y += $y; 27 | } 28 | 29 | public function __toString(): string { 30 | return '(' . $this->x . ',' . $this->y . ')'; 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /tests/Types/numeric_like_strings.php.expect: -------------------------------------------------------------------------------- 1 | ============== var_dump(numeric_like_string) =================== 2 | 3 | string(8) "12345xxx" 4 | string(9) "12345 xxx" 5 | string(10) "12345.6xxx" 6 | string(11) "12345.6 xxx" 7 | 8 | ============== is_numeric(numeric_like_string) =================== 9 | 10 | bool(false) 11 | bool(false) 12 | bool(false) 13 | bool(false) 14 | 15 | ============== cast of numeric_like_string =================== 16 | 17 | int(12345) 18 | int(12345) 19 | float(12345.6) 20 | float(12345.6) 21 | 22 | ============== +/- numeric_like_string =================== 23 | 24 | 25 | ============== relational/equality ops with numeric_like_string =================== 26 | 27 | bool(true) 28 | bool(true) 29 | bool(true) 30 | bool(true) 31 | bool(false) 32 | bool(false) 33 | bool(false) 34 | bool(false) 35 | 36 | ============== ++/-- ops with numeric_like_string =================== 37 | -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/intrinsics_exit.php: -------------------------------------------------------------------------------- 1 | 1) . "\n"; // 0 16 | echo (1 <=> 2) . "\n"; // -1 17 | echo (2 <=> 1) . "\n"; // 1 18 | 19 | // Floats 20 | 21 | echo (1.5 <=> 1.5) . "\n"; // 0 22 | echo (1.5 <=> 2.5) . "\n"; // -1 23 | echo (2.5 <=> 1.5) . "\n"; // 1 24 | 25 | // Strings 26 | 27 | echo ("a" <=> "a") . "\n"; // 0 28 | echo ("a" <=> "b") . "\n"; // -1 29 | echo ("b" <=> "a") . "\n"; // 1 30 | } 31 | 32 | /* HH_FIXME[1002] call to main in strict*/ 33 | main(); 34 | -------------------------------------------------------------------------------- /tests/Classes/Closure_call.php: -------------------------------------------------------------------------------- 1 | // NOT YET IMPLEMENTED IN CHECKER OR ENGINE value = $value; 16 | } 17 | 18 | public function getValue(): int { 19 | return $this->value; 20 | } 21 | } 22 | 23 | function main(): void { 24 | 25 | $three = new Value(3); 26 | $four = new Value(4); 27 | 28 | $closure = function ($delta) { var_dump($this->getValue() + $delta); }; 29 | $closure->call($three, 4); 30 | $closure->call($four, 4); 31 | } 32 | 33 | /* HH_FIXME[1002] call to main in strict*/ 34 | main(); 35 | -------------------------------------------------------------------------------- /tests/Functions/async_functions2.php: -------------------------------------------------------------------------------- 1 | { 6 | 7 | echo 'Inside ' . __FUNCTION__ . "\n"; 8 | 9 | // ... 10 | 11 | echo "Enter await\n"; 12 | $r1 = await g(); // $r1 = int($r1); that is, the int is unwrapped from the Awaitable object 13 | echo "Exit await; \$r1 = "; 14 | var_dump($r1); 15 | 16 | return $r1; // int($r1) is wrapped by an Awaitable object, which is returned 17 | } 18 | 19 | async function g(): Awaitable { 20 | 21 | echo 'Inside ' . __FUNCTION__ . "\n"; 22 | 23 | // ... 24 | $r2 = 10; 25 | 26 | return $r2; // int($r2) is wrapped by an Awaitable object, which is returned 27 | } 28 | 29 | function main (): void { 30 | $v = f(); // $v = object(HH\StaticWaitHandle)#1 (0) 31 | echo "\$v = "; 32 | var_dump($v); 33 | } 34 | 35 | /* HH_FIXME[1002] call to main in strict*/ 36 | main(); 37 | -------------------------------------------------------------------------------- /tests/Classes/dynamic_methods.php: -------------------------------------------------------------------------------- 1 | $arguments): int { 7 | echo "Calling instance method >$name<\n"; 8 | var_dump($arguments); 9 | 10 | return 987; 11 | } 12 | 13 | public static function __callStatic(string $name, array $arguments): string { 14 | echo "Calling static method >$name<\n"; 15 | var_dump($arguments); 16 | 17 | return "hello"; 18 | } 19 | } 20 | 21 | function main(): void { 22 | $obj = new Widget(); 23 | 24 | $obj->iMethod(10, true, "abc"); 25 | // $obj->__call('iMethod', array(10, true, "abc")); 26 | // $obj->__call('123#$%', []); 27 | 28 | Widget::sMethod(null, 1.234); 29 | Widget::__callStatic('sMethod', array(null, 1.234)); 30 | Widget::__callStatic('[]{}', []); 31 | } 32 | 33 | /* HH_FIXME[1002] call to main in strict*/ 34 | main(); 35 | -------------------------------------------------------------------------------- /tests/Expressions/Bitwise_and_or_xor_Operators/bitwise_and_or_xor.php.expect: -------------------------------------------------------------------------------- 1 | ======= check for even/odd integer values by inspecting the low-order bit ======== 2 | -5 is odd 3 | -4 is even 4 | -3 is odd 5 | -2 is even 6 | -1 is odd 7 | 0 is even 8 | 1 is odd 9 | 2 is even 10 | 3 is odd 11 | 4 is even 12 | 5 is odd 13 | Lowercase equivalent of 'A' is 'a' 14 | Uppercase equivalent of 's' is 'S' 15 | ======= swap two integers ======== 16 | $v1 = 1234, $v2 = -987 17 | $v1 = -987, $v2 = 1234 18 | ======= misc stuff ======== 19 | 0b101101 & 0b111 = 0b101 20 | 0b101101 | 0b111 = 0b101111 21 | 0b101101 ^ 0b111 = 0b101010 22 | ======= Test all kinds of scalar values to see which are ints or can be implicitly converted ======== 23 | -3 & 123 = int(121) 24 | -3 | 123 = int(-1) 25 | -3 ^ 123 = int(-122) 26 | 0 & 123 = int(0) 27 | 0 | 123 = int(123) 28 | 0 ^ 123 = int(123) 29 | 1000 & 123 = int(104) 30 | 1000 | 123 = int(1019) 31 | 1000 ^ 123 = int(915) -------------------------------------------------------------------------------- /tests/Classes/Generator_getReturn.php: -------------------------------------------------------------------------------- 1 | // NOT YET IMPLEMENTED { 12 | yield 1; 13 | yield 2; 14 | return 42; 15 | } 16 | 17 | function main(): void { 18 | $bar = foo(); 19 | 20 | try { 21 | var_dump($bar->getReturn()); 22 | echo "Call to getReturn succeded\n"; 23 | } 24 | catch (\Exception $e) { 25 | echo "Call to getReturn failed\n"; 26 | echo $e . "\n"; 27 | } 28 | 29 | foreach ($bar as $element) { 30 | echo $element, "\n"; 31 | } 32 | 33 | var_dump($bar->getReturn()); 34 | } 35 | 36 | /* HH_FIXME[1002] call to main in strict*/ 37 | main(); 38 | -------------------------------------------------------------------------------- /tests/Serialization/Point.php: -------------------------------------------------------------------------------- 1 | x = $x; 14 | $this->y = $y; 15 | $this->id = self::$nextId++; 16 | } 17 | 18 | public function __toString(): string { 19 | return 'ID:' . $this->id . '(' . $this->x . ',' . $this->y . ')'; 20 | } 21 | 22 | public function serialize(): string { 23 | return serialize(array('y' => $this->y, 'x' => $this->x)); 24 | } 25 | 26 | public function unserialize(string $sdata): void { 27 | $data = unserialize($sdata); 28 | $this->x = $data['x']; 29 | $this->y = $data['y']; 30 | $this->id = self::$nextId++; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Attributes/__ConsistentConstruct.php.expect: -------------------------------------------------------------------------------- 1 | 2 | ============== on constructor ===================== 3 | 4 | making a new object 5 | In NS_ConsistentConstruct\Base::__construct 6 | object(NS_ConsistentConstruct\Base)#1 (0) { 7 | } 8 | making a new object 9 | In NS_ConsistentConstruct\Derived::__construct 10 | In NS_ConsistentConstruct\Base::__construct 11 | object(NS_ConsistentConstruct\Derived)#2 (0) { 12 | } 13 | making a new object 14 | In NS_ConsistentConstruct\C1::__construct 15 | object(NS_ConsistentConstruct\C1)#3 (0) { 16 | } 17 | making a new object 18 | In NS_ConsistentConstruct\C2::__construct 19 | In NS_ConsistentConstruct\C1::__construct 20 | object(NS_ConsistentConstruct\C2)#4 (0) { 21 | } 22 | 23 | ============== top-level function f1 ===================== 24 | 25 | Inside NS_ConsistentConstruct\f1 26 | array(1) { 27 | [0]=> 28 | int(3) 29 | } 30 | array(2) { 31 | [0]=> 32 | int(3) 33 | [1]=> 34 | bool(true) 35 | } -------------------------------------------------------------------------------- /tests/Namespaces/using_namespaces_1.php: -------------------------------------------------------------------------------- 1 | x; } 10 | public function setX(float $x): void { $this->x = $x; } 11 | public function getY(): float { return $this->y; } 12 | public function setY(float $y): void { $this->y = $y; } 13 | 14 | public function __construct(float $x = 0.0, float $y = 0.0) { 15 | $this->x = $x; 16 | $this->y = $y; 17 | } 18 | 19 | public function move(float $x, float $y): void { 20 | $this->x = $x; 21 | $this->y = $y; 22 | } 23 | 24 | public function translate(float $x, float $y): void { 25 | $this->x += $x; 26 | $this->y += $y; 27 | } 28 | 29 | public function __toString(): string { 30 | return '(' . $this->x . ',' . $this->y . ')'; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Types/closure.php: -------------------------------------------------------------------------------- 1 | prop = $val; 12 | } 13 | 14 | public function getProp(): (function (): void) { 15 | return $this->prop; 16 | } 17 | 18 | public function __construct() { 19 | $this->prop = function (): void { echo "Hi there!\n"; }; 20 | } 21 | } 22 | 23 | function doit(int $iValue, (function (int): int) $process): int { 24 | return $process($iValue); 25 | } 26 | 27 | function main(): void { 28 | $result = doit(5, function ($p) { return $p * 2; }); // doubles 5 29 | var_dump($result); 30 | $result = doit(5, function ($p) { return $p * $p; }); // squares 5 31 | var_dump($result); 32 | } 33 | 34 | /* HH_FIXME[1002] call to main in strict*/ 35 | main(); 36 | -------------------------------------------------------------------------------- /tests/Expressions/limits_on_types_in_arithmetic.php: -------------------------------------------------------------------------------- 1 | 100 5 | stack depth = 0 6 | Inside NS_Stack\Stack::push: stackPtr = 0 7 | object(NS_Stack\Stack)#1 (2) { 8 | ["stack":"NS_Stack\Stack":private]=> 9 | array(1) { 10 | [0]=> 11 | float(10.5) 12 | } 13 | ["stackPtr":"NS_Stack\Stack":private]=> 14 | int(1) 15 | } 16 | Inside NS_Stack\Stack::pop: stackPtr = 1 17 | pop => 10.5 18 | Inside NS_Stack\Stack::push: stackPtr = 0 19 | object(NS_Stack\Stack)#1 (2) { 20 | ["stack":"NS_Stack\Stack":private]=> 21 | array(1) { 22 | [0]=> 23 | string(3) "abc" 24 | } 25 | ["stackPtr":"NS_Stack\Stack":private]=> 26 | int(1) 27 | } 28 | Inside NS_Stack\Stack::pop: stackPtr = 1 29 | pop => abc 30 | Inside NS_Stack\Stack::__construct: stackPtr = 0 31 | Inside NS_Stack\Stack::push: stackPtr = 0 32 | Inside NS_Stack\Stack::push: stackPtr = 1 -------------------------------------------------------------------------------- /tests/Exception_Handling/jump_from_catch_or_finally_clause.php: -------------------------------------------------------------------------------- 1 | >' . $v1 . '|' . $v2 . "<<\n"; 16 | echo '>>' , $v1 , '|' , $v2 , "<<\n"; 17 | echo ('>>' . $v1 . '|' . $v2 . "<<\n"); 18 | echo (('>>') . ($v1) . ('|') . ($v2) . ("<<\n"));// outer parens are part of optional syntax 19 | // inner ones are redundant grouping parens 20 | // echo ('>>' , $v1 , '|' , $v2 , "<<\n"); // parens no allowed with commas 21 | 22 | echo '>>' . $v3 . '|' . $v4 . '|' . $v5 . '|' . $v6 . "<<\n"; 23 | echo '>>' , $v3 , '|' , $v4 , '|' , $v5 , '|' , $v6 , "<<\n"; 24 | 25 | $v3 = "qqq{$v2}zzz"; 26 | var_dump($v3); 27 | echo "$v3\n"; 28 | } 29 | 30 | /* HH_FIXME[1002] call to main in strict*/ 31 | main(); -------------------------------------------------------------------------------- /tests/Namespaces/using_namespaces_3.php: -------------------------------------------------------------------------------- 1 | badValue = $badValue; 14 | $this->lowerValue = $lowerValue; 15 | $this->upperValue = $upperValue; 16 | } 17 | 18 | public function getBadValue(): int { return $this->badValue; } 19 | public function getLowerValue(): int { return $this->lowerValue; } 20 | public function getUpperValue(): int { return $this->upperValue; } 21 | 22 | public function __toString(): string { 23 | return parent::__toString() 24 | . ", badValue: " . $this->badValue 25 | . ", lowerValue: " . $this->lowerValue 26 | . ", upperValue: " . $this->upperValue; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /FORMATTING.md: -------------------------------------------------------------------------------- 1 | # Formatting rules 2 | 3 | 1. The format of the Hack Language Specification is 4 | [Markdown](http://daringfireball.net/projects/markdown/). 5 | 2. Everything in the actual specification document must be ASCII only. 6 | 3. The only allowed extensions to original Markdown are tables and code blocks 7 | (indicated by three backticks). 8 | 4. Style 9 | * Use spaces to indent, not tabs. 10 | * For headings, use prefixed hash symbols `# Example`, not underlining it 11 | with `===`. 12 | * Use of *inline* links `[example](http://example.org)` is preferred over 13 | *reference* links `[example][xmpl]` unless used multiple times in a 14 | paragraph or section. This is to allow for easier splitting and 15 | reorganization of the document. 16 | * Try to stick to 80 chars wide, if possible. This is not as strict as 17 | in coding standard rules, but still easier to read most of the times. 18 | This does only apply to text, not to code examples or tables. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Deprecated, Unmaintained 2 | 3 | This repo contains the Hack Language Specification, a modified version 4 | of the PHP specification. It is no longer maintained and does not 5 | reflect the current version of Hack. 6 | 7 | # Hack Language Specification 8 | 9 | The easiest way to navigate the specification is 10 | via the [table of contents](https://github.com/hhvm/hack-langspec/blob/master/spec/00-specification-for-hack.md). 11 | 12 | The latest official release of the specification is [1.1](https://github.com/hhvm/hack-langspec/releases/tag/v1.1). 13 | 14 | You can run the specification tests with [HHVM](https://docs.hhvm.com/hhvm/) via its 15 | [test runner](https://github.com/facebook/hhvm/blob/master/hphp/test/README.md) and the 16 | [Hack typechecker](https://docs.hhvm.com/hack/typechecker/introduction) via `hh_client`. 17 | 18 | Pull requests, issue filings and comments are extremely welcome. 19 | 20 | Make sure you understand the [*contribution process*](CONTRIBUTING.md). 21 | -------------------------------------------------------------------------------- /tests/Expressions/Primary_Expressions/intrinsics_invariant.php: -------------------------------------------------------------------------------- 1 | yay!"; 22 | } 23 | } 24 | 25 | function baz(int $a): I { 26 | return $a === 1 ? new A() : new B(); 27 | } 28 | 29 | function bar(): B { 30 | $iface = baz(2); 31 | invariant($iface instanceof B, "Object must have type B"); 32 | $iface->yay(); 33 | return $iface; 34 | } 35 | 36 | function main(?int $p): void { 37 | bar(); 38 | 39 | invariant(!is_null($p), "Value can't be null"); 40 | $v = $p << 2; 41 | 42 | $max = 100; 43 | invariant(!is_null($p) && $p <= $max, "Value %d must be <= %d", $p, $max); 44 | } 45 | 46 | //main(123); 47 | //main(null); 48 | -------------------------------------------------------------------------------- /tests/Generics/Interface_Support.php.expect: -------------------------------------------------------------------------------- 1 | ------- Container ------- 2 | 3 | V is a Container 4 | IV is a Container 5 | M is a Container 6 | IM is a Container 7 | S is a Container 8 | IS is a Container 9 | P is a Container 10 | A is a Container 11 | 12 | ------- KeyedContainer ------- 13 | 14 | V is a KeyedContainer 15 | IV is a KeyedContainer 16 | M is a KeyedContainer 17 | IM is a KeyedContainer 18 | S is **NOT** a KeyedContainer 19 | IS is **NOT** a KeyedContainer 20 | P is a KeyedContainer 21 | A is a KeyedContainer 22 | ------- Traversable ------- 23 | 24 | V is a Traversable 25 | IV is a Traversable 26 | M is a Traversable 27 | IM is a Traversable 28 | S is a Traversable 29 | IS is a Traversable 30 | P is a Traversable 31 | A is a Traversable 32 | 33 | ------- KeyedTraversable ------- 34 | 35 | V is a KeyedTraversable 36 | IV is a KeyedTraversable 37 | M is a KeyedTraversable 38 | IM is a KeyedTraversable 39 | S is a KeyedTraversable 40 | IS is a KeyedTraversable 41 | P is a KeyedTraversable 42 | A is a KeyedTraversable -------------------------------------------------------------------------------- /tests/Lexical_Structure/Tokens/array_literals.php.expect: -------------------------------------------------------------------------------- 1 | object(NS_array_literals\X)#1 (6) { 2 | ["prop10":"NS_array_literals\X":private]=> 3 | array(0) { 4 | } 5 | ["prop11":"NS_array_literals\X":private]=> 6 | array(3) { 7 | [0]=> 8 | int(10) 9 | [1]=> 10 | string(3) "red" 11 | [2]=> 12 | bool(true) 13 | } 14 | ["prop12":"NS_array_literals\X":private]=> 15 | array(2) { 16 | ["a"]=> 17 | int(10) 18 | ["r"]=> 19 | array(2) { 20 | [0]=> 21 | int(20) 22 | [1]=> 23 | int(30) 24 | } 25 | } 26 | ["prop20":"NS_array_literals\X":private]=> 27 | array(0) { 28 | } 29 | ["prop21":"NS_array_literals\X":private]=> 30 | array(3) { 31 | [0]=> 32 | int(10) 33 | [1]=> 34 | string(3) "red" 35 | [2]=> 36 | bool(true) 37 | } 38 | ["prop22":"NS_array_literals\X":private]=> 39 | array(2) { 40 | ["a"]=> 41 | int(10) 42 | ["r"]=> 43 | array(2) { 44 | [0]=> 45 | int(20) 46 | [1]=> 47 | int(30) 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /tests/Functions/async_functions.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Test some basics ====================== 3 | 4 | $result = 100 5 | 6 | Wait on multiple async operations ====================== 7 | 8 | 9 | Use async iterators ====================== 10 | 11 | int(3) 12 | int(2) 13 | int(1) 14 | int(0) 15 | int(3) 16 | string(1) "3" 17 | int(2) 18 | string(1) "2" 19 | int(1) 20 | string(1) "1" 21 | int(0) 22 | string(1) "0" 23 | 24 | Test async blocks ====================== 25 | 26 | object(HH\StaticWaitHandle)#%d (0) { 27 | } 28 | ----------------- 29 | object(HH\StaticWaitHandle)#%d (0) { 30 | } 31 | ----------------- 32 | int(123) 33 | object(HH\StaticWaitHandle)#%d (0) { 34 | } 35 | ----------------- 36 | float(1.23) 37 | object(HH\StaticWaitHandle)#%d (0) { 38 | } 39 | ----------------- 40 | object(HH\Vector)#%d (2) { 41 | [0]=> 42 | int(10) 43 | [1]=> 44 | float(1.2) 45 | } 46 | ----------------- 47 | object(HH\Vector)#%d (2) { 48 | [0]=> 49 | float(1.2) 50 | [1]=> 51 | int(10) 52 | } 53 | 54 | Check usage contexts for await ====================== 55 | -------------------------------------------------------------------------------- /tests/Expressions/Yield_Operator/yield_from.php: -------------------------------------------------------------------------------- 1 | // SUPPORT IS NOT YET IMPLEMENTED { 10 | yield 1; 11 | yield from gen2(); 12 | yield 4; 13 | } 14 | 15 | function gen2(): Generator { 16 | yield 2; 17 | yield 3; 18 | } 19 | 20 | function g(): Generator { 21 | yield 1; 22 | yield from [2, 3]; 23 | yield 4; 24 | } 25 | 26 | function main(): void { 27 | echo "====== yielding from another generator =========\n\n"; 28 | 29 | foreach (gen() as $val) 30 | { 31 | echo $val . "\n"; 32 | } 33 | 34 | echo "\n====== yielding from an array =========\n\n"; 35 | 36 | $g = g(); 37 | foreach ($g as $yielded) { 38 | echo $yielded . "\n"; 39 | } 40 | } 41 | 42 | /* HH_FIXME[1002] call to main in strict*/ 43 | main(); 44 | -------------------------------------------------------------------------------- /tests/Types/scalar_general.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Warning: No such file or directory in %s/tests/Types/scalar_general.php on line 8 3 | ========== is_numeric tests ========== 4 | 5 | is_numeric(true): False 6 | is_numeric(false): False 7 | is_numeric(10): True 8 | is_numeric(12.34): True 9 | is_numeric(""): False 10 | is_numeric("123"): True 11 | is_numeric("123abc"): False 12 | is_numeric("abc"): False 13 | is_numeric(null): False 14 | is_numeric(array(10,20)): False 15 | is_numeric(new C()): False 16 | is_numeric(resource): False 17 | 18 | ========== is_numeric tests ========== 19 | 20 | is_scalar(true): True 21 | is_scalar(10): True 22 | is_scalar(12.34): True 23 | is_scalar("123"): True 24 | is_scalar(null): False 25 | is_scalar(array(10,20)): False 26 | is_scalar(new C()): False 27 | is_scalar(resource): True 28 | 29 | ========== is_numeric tests ========== 30 | 31 | is_null(true): False 32 | is_null(10): False 33 | is_null(12.34): False 34 | is_null("123"): False 35 | is_null(null): True 36 | is_null(array(10,20)): False 37 | is_null(new C()): False 38 | is_null(resource): False -------------------------------------------------------------------------------- /tests/Generics/Stack.php: -------------------------------------------------------------------------------- 1 | { 8 | private array $stack; 9 | private int $stackPtr; 10 | 11 | public function __construct() { 12 | $this->stackPtr = 0; 13 | $this->stack = array(); 14 | 15 | echo "Inside " . __METHOD__ . ": stackPtr = " . $this->stackPtr . "\n"; 16 | } 17 | 18 | public function __destruct() { 19 | $this->stack = array(); 20 | } 21 | 22 | public function push(T $value): void { 23 | echo "Inside " . __METHOD__ . ": stackPtr = " . $this->stackPtr . "\n"; 24 | 25 | $this->stack[$this->stackPtr++] = $value; 26 | } 27 | 28 | public function pop(): T { 29 | echo "Inside " . __METHOD__ . ": stackPtr = " . $this->stackPtr . "\n"; 30 | 31 | if ($this->stackPtr > 0) { 32 | return $this->stack[--$this->stackPtr]; 33 | } else { 34 | throw new StackUnderflowException(); 35 | } 36 | } 37 | 38 | public function getStackDepth(): int { 39 | return $this->stackPtr; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/Expressions/Additive_Operators/addition_subtraction_concatenation.php: -------------------------------------------------------------------------------- 1 | $e1< + >$e2<, result: "; var_dump($e1 + $e2); 11 | } 12 | echo "-------------------------------------\n"; 13 | } 14 | //*/ 15 | ///* 16 | foreach ($oper as $e1) { 17 | foreach ($oper as $e2) { 18 | echo ">$e1< - >$e2<, result: "; var_dump($e1 - $e2); 19 | } 20 | echo "-------------------------------------\n"; 21 | } 22 | //*/ 23 | ///* 24 | $oper = array(100, -3.4, true, null, "123", "2e+5", "", "abc"); 25 | foreach ($oper as $e1) { 26 | foreach ($oper as $e2) { 27 | echo ">$e1< . >$e2<, result: "; var_dump($e1 . $e2); 28 | } 29 | echo "-------------------------------------\n"; 30 | } 31 | //*/ 32 | } 33 | 34 | function main(): void { 35 | doit(11); 36 | } 37 | 38 | /* HH_FIXME[1002] call to main in strict*/ 39 | main(); 40 | -------------------------------------------------------------------------------- /tests/Statements/Jump/continue.php: -------------------------------------------------------------------------------- 1 | 0) { 17 | if ((($j * $i) % 2) == 0) { 18 | $j -= 3; 19 | continue 1; 20 | } 21 | echo ($j * $i)." is odd\n"; 22 | $j -= 5; 23 | } 24 | echo "In for loop\n"; 25 | } 26 | */ 27 | 28 | // In PHP, 'continue;' inside a switch statement is equivalent to 'break;'. Hack does not 29 | // support this; use 'break' if that is what you meant. 30 | 31 | for ($i = 10; $i <= 40; $i +=10) { 32 | echo "\n\$i = $i: "; 33 | switch($i) { 34 | case 10: echo "ten"; break; 35 | // case 20: echo "twenty"; continue; 36 | case 30: echo "thirty"; break; 37 | } 38 | echo "\nJust beyond the switch"; 39 | } 40 | echo "\n----------\n"; 41 | } 42 | 43 | /* HH_FIXME[1002] call to main in strict*/ 44 | main(); 45 | -------------------------------------------------------------------------------- /tests/Expressions/Additive_Operators/array_concatenation.php.expect: -------------------------------------------------------------------------------- 1 | ============= vector-like arrays ================ 2 | result of p1 + p2 = array(2) { 3 | [0]=> 4 | int(66) 5 | [1]=> 6 | int(200) 7 | } 8 | result of p2 + p1 = array(2) { 9 | [0]=> 10 | int(100) 11 | [1]=> 12 | int(200) 13 | } 14 | ============= map-like arrays ================ 15 | result of p8 + p9 = array(4) { 16 | [2]=> 17 | string(2) "aa" 18 | [12]=> 19 | string(2) "bb" 20 | [-4]=> 21 | string(2) "cc" 22 | [6]=> 23 | string(2) "dd" 24 | } 25 | result of p11 + p12 = array(3) { 26 | ["red"]=> 27 | int(12) 28 | ["green"]=> 29 | int(7) 30 | ["blue"]=> 31 | int(3) 32 | } 33 | ============= concating to an empty/untyped array ================ 34 | result of p1 + array() = array(1) { 35 | [0]=> 36 | int(66) 37 | } 38 | result of array() + p1 = array(1) { 39 | [0]=> 40 | int(66) 41 | } 42 | result of p10 + array() = array(1) { 43 | [-3]=> 44 | bool(true) 45 | } 46 | result of p11 + array() = array(2) { 47 | ["red"]=> 48 | int(12) 49 | ["green"]=> 50 | int(7) 51 | } 52 | result of array() + array() = array(0) { 53 | } -------------------------------------------------------------------------------- /tests/Functions/anonymous_functions2.php: -------------------------------------------------------------------------------- 1 | 16 | float(2) 17 | ["y":"NS___PHP_Incomplete_Class\Point":private]=> 18 | float(5) 19 | } 20 | 21 | --- fake string value --- 22 | 23 | string(135) "O:31:"NS___PHP_Incomplete_Class\Joint":2:{s:34:"NS___PHP_Incomplete_Class\Pointx";d:2;s:34:"NS___PHP_Incomplete_Class\Pointy";d:5;}" 24 | 25 | --- unserialize that Point to non-existant class type --- 26 | 27 | object(__PHP_Incomplete_Class)#3 (3) { 28 | ["__PHP_Incomplete_Class_Name"]=> 29 | string(31) "NS___PHP_Incomplete_Class\Joint" 30 | ["x":"NS___PHP_Incomplete_Class\Point":private]=> 31 | float(2) 32 | ["y":"NS___PHP_Incomplete_Class\Point":private]=> 33 | float(5) 34 | } -------------------------------------------------------------------------------- /tests/Types/resources.php: -------------------------------------------------------------------------------- 1 | prop = STDOUT; 11 | } 12 | 13 | public function setProp(resource $val): void { 14 | $this->prop = $val; 15 | } 16 | 17 | public function getProp(): resource { 18 | return $this->prop; 19 | } 20 | } 21 | 22 | function main(): void { 23 | var_dump(STDIN); 24 | var_dump(is_resource(STDIN)); 25 | var_dump(get_resource_type(STDIN)); 26 | 27 | var_dump(STDOUT); 28 | var_dump(is_resource(STDIN)); 29 | var_dump(get_resource_type(STDIN)); 30 | 31 | var_dump(STDERR); 32 | var_dump(is_resource(STDIN)); 33 | var_dump(get_resource_type(STDIN)); 34 | 35 | $infile = fopen("Testfile.txt", 'r'); 36 | var_dump($infile); 37 | echo "\n"; 38 | print_r($infile); 39 | echo "\n"; 40 | 41 | $infile = fopen("NoSuchFile.txt", 'r'); 42 | var_dump($infile); 43 | 44 | $c = new C(); 45 | var_dump($c); 46 | } 47 | 48 | /* HH_FIXME[1002] call to main in strict*/ 49 | main(); 50 | 51 | -------------------------------------------------------------------------------- /tests/Generics/MyVector.php: -------------------------------------------------------------------------------- 1 | { 6 | private int $length; 7 | private array $vector; 8 | 9 | public function getLength(): int { 10 | return $this->length; 11 | } 12 | 13 | private function setLength(int $newLength): void { 14 | $this->length = $newLength; 15 | } 16 | 17 | public function getElement(int $index): T { 18 | // bounds checking omitted 19 | return $this->vector[$index]; 20 | } 21 | 22 | public function setElement(int $index, T $newValue): void { 23 | // bounds checking omitted 24 | 25 | $this->vector[$index] = $newValue; 26 | } 27 | 28 | public function __construct(int $vectorLength, T $initValue) { 29 | $this->length = $vectorLength; 30 | $this->vector = array(); 31 | for ($i = 0; $i < $this->length; ++$i) { 32 | $this->vector[] = $initValue; 33 | } 34 | } 35 | 36 | public function __toString(): string { 37 | $s = '['; 38 | for ($i = 0; $i < $this->length - 1; ++$i) { 39 | $s .= (string)$this->vector[$i] . ':'; 40 | } 41 | $s .= (string)$this->vector[$i] . ']'; 42 | return $s; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/subscripting_2.php.expect: -------------------------------------------------------------------------------- 1 | ====== vector-like array without index; simple assignment ========= 2 | int(991) 3 | array(3) { 4 | [0]=> 5 | int(33) 6 | [1]=> 7 | int(-11) 8 | [2]=> 9 | int(991) 10 | } 11 | ------ 12 | ====== array without index; compound assignment ========= 13 | int(991) 14 | array(3) { 15 | [0]=> 16 | int(33) 17 | [1]=> 18 | int(-11) 19 | [2]=> 20 | int(991) 21 | } 22 | ------ 23 | int(-991) 24 | array(3) { 25 | [0]=> 26 | int(33) 27 | [1]=> 28 | int(-11) 29 | [2]=> 30 | int(-991) 31 | } 32 | ------ 33 | int(0) 34 | array(3) { 35 | [0]=> 36 | int(33) 37 | [1]=> 38 | int(-11) 39 | [2]=> 40 | int(0) 41 | } 42 | ====== array without index; ++/-- ========= 43 | NULL 44 | array(3) { 45 | [0]=> 46 | int(33) 47 | [1]=> 48 | int(-11) 49 | [2]=> 50 | int(1) 51 | } 52 | ------ 53 | int(1) 54 | array(4) { 55 | [0]=> 56 | int(33) 57 | [1]=> 58 | int(-11) 59 | [2]=> 60 | int(1) 61 | [3]=> 62 | int(1) 63 | } 64 | ------ 65 | NULL 66 | array(5) { 67 | [0]=> 68 | int(33) 69 | [1]=> 70 | int(-11) 71 | [2]=> 72 | int(1) 73 | [3]=> 74 | int(1) 75 | [4]=> 76 | NULL 77 | } -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | Tools and scripts to help with rendering and enhancing the documentation in general. 2 | 3 | Here are some possible examples: 4 | 5 | 1. A script to convert from Markdown to Word or PDF might live in here. 6 | 2. A tool to help move cross reference links from Word to Markdown. 7 | 3. A script to add numbered headings to Markdown. 8 | 9 | If you are converting from something like Word to Markdown for the first time, this the order of tool running you might consider: 10 | 11 | 1. If the documentation has been converted from Word to **one big** markdown file, you will probably want to run `split.php` first. This will split the big markdown into multiple markdown files based on primary section headings. If the document is already split, then you can go to step (2). 12 | 2. Then you will want to run `toc.php` to create the table of contents for the split documentation. 13 | 3. Then run `xreference.php` to get all the cross references correct. For documentation that has been split into multiple markdown files, you can specify a directory of those files so that all the files there get modified for cross-references. If the documentation is one big file still, you can just specify that file. 14 | 15 | -------------------------------------------------------------------------------- /tests/Expressions/Coalesce Operator/coalesce.php: -------------------------------------------------------------------------------- 1 | "bar", "qux" => null]; 17 | $obj = (object)$arr; 18 | 19 | $a = $arr["foo"] ?? "bang"; // "bar" as $arr["foo"] is set and not null 20 | $a = $arr["qux"] ?? "bang"; // "bang" as $arr["qux"] is null 21 | $a = $arr["bing"] ?? "bang"; // "bang" as $arr["bing"] is not set 22 | 23 | $a = $obj->foo ?? "bang"; // "bar" as $obj->foo is set and not null 24 | $a = $obj->qux ?? "bang"; // "bang" as $obj->qux is null 25 | $a = $obj->bing ?? "bang"; // "bang" as $obj->bing is not set 26 | 27 | $a = null ?? $arr["bing"] ?? 2; // 2 as null is null, and $arr["bing"] is not set 28 | var_dump(true ?? foo()); // outputs bool(true), "executed!" does not appear as it short-circuits 29 | } 30 | 31 | /* HH_FIXME[1002] call to main in strict*/ 32 | main(); 33 | -------------------------------------------------------------------------------- /tests/Interfaces/qq.php: -------------------------------------------------------------------------------- 1 | openDoors(); 22 | $this->closeDoors(); 23 | return $this->fly(); 24 | } 25 | 26 | public function fly(): bool { 27 | return true; 28 | } 29 | } 30 | 31 | // Having this will not only cause a typechecker error, but also cause a fatal 32 | // error in HHVM since we did not meet the interface requirement (extending 33 | // Machine). 34 | 35 | /*class Paper implements Fliers { 36 | public function fly(): bool { 37 | return false; 38 | } 39 | } 40 | */ 41 | 42 | function main(): void { 43 | $ab = new AirBus(); 44 | var_dump($ab); 45 | var_dump($ab->takeOff()); 46 | $p = new AirBus(); 47 | var_dump($p); 48 | var_dump($p->takeOff()); 49 | } 50 | 51 | /* HH_FIXME[1002] call to main in strict*/ 52 | main(); 53 | -------------------------------------------------------------------------------- /tests/Expressions/Binary_Logical_Operators/binary_logical_operators.php: -------------------------------------------------------------------------------- 1 | 1 && $month <= 12) 11 | echo "\$month $month is in-bounds\n"; 12 | else 13 | echo "\$month $month is out-of-bounds\n"; 14 | 15 | $month = 14; 16 | if ($month > 1 && $month <= 12) 17 | echo "\$month $month is in-bounds\n"; 18 | else 19 | echo "\$month $month is out-of-bounds\n"; 20 | 21 | $month = 6; 22 | if ($month < 1 || $month > 12) 23 | echo "\$month $month is out-of-bounds\n"; 24 | else 25 | echo "\$month $month is in-bounds\n"; 26 | 27 | $month = 14; 28 | if ($month < 1 || $month > 12) 29 | echo "\$month $month is out-of-bounds\n"; 30 | else 31 | echo "\$month $month is in-bounds\n"; 32 | 33 | // sequence point 34 | 35 | $i = 5; 36 | $v = (f($i++) && g($i)); 37 | var_dump($v); 38 | $i = 0; 39 | $v = (g($i++) || f($i)); 40 | var_dump($v); 41 | } 42 | 43 | /* HH_FIXME[1002] call to main in strict*/ 44 | main(); 45 | -------------------------------------------------------------------------------- /tests/Variables/placeholder_variable.php.expect: -------------------------------------------------------------------------------- 1 | $_ is >33< 2 | 3 | 4 | ========================= Using $_ as an exception catch parameter name ========================= 5 | 6 | 7 | 8 | ========================= Is $_ defined by default? ========================= 9 | 10 | 11 | 12 | ========================= Can the value of $_ be changed? ========================= 13 | 14 | $_ is >Hello< 15 | $_ is >10< 16 | 17 | 18 | ========================= Odd behavior with var_dump and $_ ========================= 19 | 20 | string(1) "a" 21 | int(10) 22 | int(10) 23 | string(1) "f" 24 | int(30) 25 | int(10) 26 | 27 | 28 | ========================= An intended use of $_ with foreach, but ... ========================= 29 | 30 | string(1) "a" 31 | int(10) 32 | string(1) "f" 33 | int(30) 34 | $_ is >xx< 35 | 36 | 37 | ========================= An odd use of $_ ========================= 38 | 39 | $_ is >10< 40 | $_ is >30< 41 | $_ is >30< 42 | 43 | 44 | ========================= Using $_ for both key and value ========================= 45 | 46 | $_ is >a< 47 | $_ is >f< 48 | $_ is >f< 49 | 50 | 51 | ========================= An intended use of $_ with list ========================= 52 | 53 | int(1) 54 | int(3) 55 | int(2) -------------------------------------------------------------------------------- /tests/Generics/Complex_test.php.expect: -------------------------------------------------------------------------------- 1 | ================== Complex =================== 2 | 3 | $c1 = (10.5 + 5.67i) 4 | $c2 = (-10.98 - 123.45i) 5 | $c1 + $c2 = (-0.48 - 117.78i) 6 | $c1 - $c2 = (21.48 + 129.12i) 7 | 8 | ================== Complex =================== 9 | 10 | $c3 = (5 + 6i) 11 | $c4 = (-10 - 12i) 12 | $c3 + $c4 = (-5 - 6i) 13 | $c3 - $c4 = (15 + 18i) 14 | 15 | ================== Complex =================== 16 | 17 | $c5 = (9 + 5.4i) 18 | $c6 = (12.2 - 20i) 19 | $c5 + $c6 = (21.2 - 14.6i) 20 | $c5 - $c6 = (-3.2 + 25.4i) 21 | object(NS_Complex\Complex)#5 (2) { 22 | ["real":"NS_Complex\Complex":private]=> 23 | int(9) 24 | ["imag":"NS_Complex\Complex":private]=> 25 | float(5.4) 26 | } 27 | object(NS_Complex\Complex)#6 (2) { 28 | ["real":"NS_Complex\Complex":private]=> 29 | float(12.2) 30 | ["imag":"NS_Complex\Complex":private]=> 31 | int(-20) 32 | } 33 | object(NS_Complex\Complex)#7 (2) { 34 | ["real":"NS_Complex\Complex":private]=> 35 | float(21.2) 36 | ["imag":"NS_Complex\Complex":private]=> 37 | float(-14.6) 38 | } 39 | object(NS_Complex\Complex)#8 (2) { 40 | ["real":"NS_Complex\Complex":private]=> 41 | float(-3.2) 42 | ["imag":"NS_Complex\Complex":private]=> 43 | float(25.4) 44 | } -------------------------------------------------------------------------------- /tests/Classes/__PHP_Incomplete_Class.php: -------------------------------------------------------------------------------- 1 | x = $x; 11 | $this->y = $y; 12 | 13 | echo "\nInside " . __METHOD__ . ", $this\n\n"; 14 | } 15 | 16 | public function __toString(): string { 17 | return '(' . $this->x . ',' . $this->y . ')'; 18 | } 19 | } 20 | 21 | function main(): void { 22 | echo "--- create a Point ---\n\n"; 23 | 24 | $p = new Point(2.0, 5.0); 25 | echo "Point \$p = $p\n"; 26 | 27 | echo "\n--- serialize that Point ---\n\n"; 28 | 29 | $s = serialize($p); // all instance properties get serialized 30 | var_dump($s); 31 | 32 | echo "\n--- unserialize that Point ---\n\n"; 33 | 34 | $v = unserialize($s); 35 | var_dump($v); 36 | 37 | echo "\n--- fake string value ---\n\n"; 38 | 39 | $s[32] = 'J'; // change class name, so an unserialize failure occurs 40 | var_dump($s); 41 | 42 | echo "\n--- unserialize that Point to non-existant class type ---\n\n"; 43 | 44 | $v = unserialize($s); 45 | var_dump($v); 46 | } 47 | 48 | /* HH_FIXME[1002] call to main in strict*/ 49 | main(); 50 | -------------------------------------------------------------------------------- /tests/Lexical_Structure/Tokens/string_literals.php.expect: -------------------------------------------------------------------------------- 1 | string(0) "" 2 | > < 3 | > a B c < 4 | >'.\".\.\$.\eXXX.\f.\n.\r.\t.\v.\101.\x41.\X41.\F.\Q.\S< 5 | >\$x.$x< 6 | >xxx // this comment-like thingy really is part of the string literal 7 | yyy 8 | zzz< 9 | string(2) "\e" 10 | string(0) "" 11 | > < 12 | > a B c < 13 | >\'.".\.$.XXX. . 14 | . . . .A.A.A.\F.\Q.\S< 15 | >$x.123< 16 | >xxx // this comment-like thingy really is part of the string literal 17 | yyy 18 | zzz< 19 | string(1) "" 20 | string(1) "" 21 | string(1) "" 22 | string(1) "" 23 | string(3) "435" 24 | string(10) "-1.234E+24" 25 | string(0) "" 26 | string(1) "1" 27 | string(0) "" 28 | string(8) "blue sky" 29 | >435|-1.234E+24||1||blue sky< 30 | >24.543567891235<--- o/p from string substition 31 | >-2.345E+28<--- o/p from string substition 32 | >6.0E-200<--- o/p from string substition 33 | >NAN<--- o/p from string substition 34 | >INF<--- o/p from string substition 35 | >NAN<--- o/p from string substition 36 | >NaN<--- using o/p from sprintf with hard-coded precision 37 | >-34 X|ABC _|1 3|5.67E+14 +< 38 | >$1|$&< 39 | \colors[1] contains >white< 40 | string(5) "white" 41 | $colors[2] contains >blue< 42 | $myC->p1 = >2< 43 | >-34X|-34 X|ABC_|ABC _|13|1 3|5.67E+14+|5.67E+14 +< 44 | >{}|{q}|}|{< -------------------------------------------------------------------------------- /tests/Functions/conditionally_defined_function.php: -------------------------------------------------------------------------------- 1 | , float) { 14 | return tuple(true, array(99, 88, 77), 10.5); 15 | } 16 | 17 | function ft1((int, int) $p1): void {} 18 | function ft2(): (int, int) { return tuple(10, 20); } 19 | 20 | function main(?int $p1 = 123): void { 21 | // $t1 = tuple(); // must have at least 1 element 22 | $t1 = tuple(10); // while can't declare a tuple type with only 1 element, can create a 1-element tuple 23 | 24 | // $t1 = tuple('a' => 5, 6 => 7); // only (implied) int keys are allowed 25 | 26 | // $t1 = tuple(2 => 5, 6 => 7); // can't specify index numbers 27 | 28 | $t2 = tuple(10, true, 2.3, 10, 'abc', null, $p1, array(2, $p1), Vector {}, new C()); 29 | var_dump($t2); 30 | 31 | // foreach ($t2 => $key as $value) { } // can't iterate over a tuple 32 | 33 | // $i = 0; 34 | // echo "\$t2[0] = " . $t2[$i] . "\n"; // tuple index must be an integer literal 35 | 36 | echo "\$t2[0] = >" . $t2[0] . "<\n"; 37 | echo "\$t2[4] = >" . $t2[4] . "<\n"; 38 | // echo "\$t2[12] = >" . $t2[12] . "<\n"; 39 | // echo "\$t2[-2] = >" . $t2[-2] . "<\n"; 40 | } 41 | 42 | //main(null); -------------------------------------------------------------------------------- /tests/Classes/require_extends_implements.php: -------------------------------------------------------------------------------- 1 | { 6 | private T $real; 7 | private T $imag; 8 | 9 | public function __construct(T $real, T $imag) { 10 | $this->real = $real; 11 | $this->imag = $imag; 12 | } 13 | 14 | public function getReal(): T { 15 | return $this->real; 16 | } 17 | 18 | public function setReal(T $real): void { 19 | $this->real = $real; 20 | } 21 | 22 | public function getImag(): T { 23 | return $this->imag; 24 | } 25 | 26 | public function setImag(T $imag): void { 27 | $this->imag = $imag; 28 | } 29 | 30 | public static function add(Complex $z1, Complex $z2): Complex { 31 | return new Complex($z1->real + $z2->real, $z1->imag + $z2->imag); 32 | } 33 | 34 | public static function subtract(Complex $z1, Complex $z2): Complex { 35 | return new Complex($z1->real - $z2->real, $z1->imag - $z2->imag); 36 | } 37 | 38 | public function __toString(): string { 39 | if ($this->imag < 0.0) { 40 | return "(" . $this->real . " - " . (-$this->imag) . "i)"; 41 | } else if (1.0/$this->imag == -INF) { 42 | return "(" . $this->real . " + " . 0.0 . "i)"; 43 | } else { 44 | return "(" . $this->real . " + " . (+$this->imag) . "i)"; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/Enums/string_int_equality_problem.php: -------------------------------------------------------------------------------- 1 | 'R' (Ready) 30 | break; 31 | case E5::Ready: 32 | echo "Ready: $p4\n"; 33 | break; 34 | } 35 | } 36 | */ 37 | 38 | /* HH_FIXME[1002] call to main in strict*/ 39 | main(E5::Ready); 40 | /* HH_FIXME[1002] call to main in strict*/ 41 | main(E5::Started); 42 | 43 | -------------------------------------------------------------------------------- /tests/Exception_Handling/MyRangeException_test1.php.expectf: -------------------------------------------------------------------------------- 1 | object(NS_MyRangeException\MyRangeException)#1 (10) { 2 | ["badValue":"NS_MyRangeException\MyRangeException":private]=> 3 | int(5) 4 | ["lowerValue":"NS_MyRangeException\MyRangeException":private]=> 5 | int(20) 6 | ["upperValue":"NS_MyRangeException\MyRangeException":private]=> 7 | int(30) 8 | ["message":protected]=> 9 | string(3) "xxx" 10 | ["string":"Exception":private]=> 11 | string(0) "" 12 | ["code":protected]=> 13 | int(0) 14 | ["file":protected]=> 15 | string(%d) "%s/tests/Exception_Handling/MyRangeException_test1.php" 16 | ["line":protected]=> 17 | int(8) 18 | ["trace":"Exception":private]=> 19 | array(1) { 20 | [0]=> 21 | array(4) { 22 | ["file"]=> 23 | string(%d) "%s/tests/Exception_Handling/MyRangeException_test1.php" 24 | ["line"]=> 25 | int(17) 26 | ["function"]=> 27 | string(30) "NS_MyRangeException_test1\main" 28 | ["args"]=> 29 | array(0) { 30 | } 31 | } 32 | } 33 | ["previous":"Exception":private]=> 34 | NULL 35 | } 36 | ======= 37 | $re = >exception 'NS_MyRangeException\MyRangeException' with message 'xxx' in %s/tests/Exception_Handling/MyRangeException_test1.php:8 38 | Stack trace: 39 | #0 %s/tests/Exception_Handling/MyRangeException_test1.php(17): NS_MyRangeException_test1\main() 40 | #1 {main}, badValue: 5, lowerValue: 20, upperValue: 30< 41 | -------------------------------------------------------------------------------- /tests/Types/num.php: -------------------------------------------------------------------------------- 1 | prop = $val; 11 | } 12 | 13 | public function getProp(): num { 14 | return $this->prop; 15 | } 16 | 17 | public function __construct() { 18 | echo "num " . $this->prop . (is_int($this->prop) ? " is int\n" : " is float\n"); 19 | 20 | $this->prop = 1.2; 21 | echo "num " . $this->prop . (is_int($this->prop) ? " is int\n" : " is float\n"); 22 | 23 | $this->prop = 6; 24 | echo "num " . $this->prop . (is_int($this->prop) ? " is int\n" : " is float\n"); 25 | 26 | $this->prop += 0.0; 27 | echo "num " . $this->prop . (is_int($this->prop) ? " is int\n" : " is float\n"); 28 | 29 | $this->prop = 16; 30 | echo "num " . $this->prop . (is_int($this->prop) ? " is int\n" : " is float\n"); 31 | 32 | $this->prop *= 1.0; 33 | echo "num " . $this->prop . (is_int($this->prop) ? " is int\n" : " is float\n"); 34 | 35 | $this->prop = PHP_INT_MAX; 36 | echo "num " . $this->prop . (is_int($this->prop) ? " is int\n" : " is float\n"); 37 | 38 | ++$this->prop; 39 | echo "num " . $this->prop . (is_int($this->prop) ? " is int\n" : " is float\n"); 40 | } 41 | } 42 | 43 | function main (): void { 44 | $c = new C(); 45 | } 46 | 47 | /* HH_FIXME[1002] call to main in strict*/ 48 | main(); 49 | -------------------------------------------------------------------------------- /tests/Namespaces/namespaces1.php: -------------------------------------------------------------------------------- 1 | f(); 43 | } 44 | 45 | function main(): void { 46 | \NS1\f1(); 47 | \NS1\Sub1\f2(); 48 | \NS2\f3(); 49 | \NS3\Sub1\f4(); 50 | \NS3\Sub1\f5(); 51 | } 52 | 53 | /* HH_FIXME[1002] call to main in strict*/ 54 | main(); 55 | -------------------------------------------------------------------------------- /tests/Types/arraykey.php: -------------------------------------------------------------------------------- 1 | prop = $val; 11 | } 12 | 13 | public function getProp(): arraykey { 14 | return $this->prop; 15 | } 16 | 17 | public function __construct() { 18 | echo "arraykey " . $this->prop . (is_int($this->prop) ? " is int\n" : " is string\n"); 19 | 20 | $this->prop = 20; 21 | echo "arraykey " . $this->prop . (is_int($this->prop) ? " is int\n" : " is string\n"); 22 | 23 | $this->prop = 'red'; 24 | echo "arraykey " . $this->prop . (is_int($this->prop) ? " is int\n" : " is string\n"); 25 | } 26 | } 27 | 28 | function main (): void { 29 | $c = new C(); 30 | $val = $c->getProp(); 31 | 32 | // $q = $val + 10; // checker can't be sure teh arraykey is currently an int 33 | 34 | if (is_int($val)) { 35 | $q = $val + 10; 36 | } else { 37 | // Checker reports: This is not a container, this is an array key (int/string) 38 | // It appears to not be able to deduce the type must be string; however, the true of the is_string (below) works. 39 | // echo "First character of string is " . $val[0] . "\n"; 40 | } 41 | 42 | if (is_string($val)) { 43 | echo "First character of string is " . $val[0] . "\n"; 44 | } 45 | } 46 | 47 | /* HH_FIXME[1002] call to main in strict*/ 48 | main(); 49 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/subscripting_2.php: -------------------------------------------------------------------------------- 1 | 33, -1 => -11); 48 | // var_dump($a[] = 991); // creates $a[4] 49 | // var_dump($a); 50 | // echo "------\n"; 51 | 52 | } 53 | 54 | /* HH_FIXME[1002] call to main in strict*/ 55 | main(); 56 | -------------------------------------------------------------------------------- /tests/Exception_Handling/odds_and_ends.php: -------------------------------------------------------------------------------- 1 | prop = " . $o->prop . "\n"; 46 | 47 | try { 48 | echo "In try-block\n"; 49 | throw $o; 50 | echo "End of try-block\n"; 51 | } 52 | catch (Except $e) { 53 | echo "In catch-block Except\n"; 54 | echo "\$e->prop = " . $e->prop . "\n"; 55 | $e->prop = 999; 56 | echo "\$e->prop = " . $e->prop . "\n"; 57 | } 58 | 59 | echo "\$o->prop = " . $o->prop . "\n"; 60 | } 61 | 62 | /* HH_FIXME[1002] call to main in strict*/ 63 | main(); 64 | -------------------------------------------------------------------------------- /tests/Classes/cloning.php.expect: -------------------------------------------------------------------------------- 1 | object(NS_cloning\C)#1 (1) { 2 | ["m":"NS_cloning\C":private]=> 3 | int(10) 4 | } 5 | Inside NS_cloning\C::__clone 6 | object(NS_cloning\C)#2 (1) { 7 | ["m":"NS_cloning\C":private]=> 8 | int(10) 9 | } 10 | ================= Use cloning in Point class ================= 11 | Point count = 0 12 | object(NS_Point2\Point2)#3 (2) { 13 | ["x"]=> 14 | float(-3.5) 15 | ["y"]=> 16 | float(1.4) 17 | } 18 | Point count = 1 19 | Inside NS_Point2\Point2::__clone, point count = 2 20 | object(NS_Point2\Point2)#4 (2) { 21 | ["x"]=> 22 | float(-3.5) 23 | ["y"]=> 24 | float(1.4) 25 | } 26 | Point count = 2 27 | Inside NS_Point2\Point2::__clone, point count = 3 28 | object(NS_Point2\Point2)#5 (2) { 29 | ["x"]=> 30 | float(-3.5) 31 | ["y"]=> 32 | float(1.4) 33 | } 34 | Point count = 3 35 | Inside NS_Point2\Point2::__clone, point count = 4 36 | object(NS_Point2\Point2)#6 (2) { 37 | ["x"]=> 38 | float(-3.5) 39 | ["y"]=> 40 | float(1.4) 41 | } 42 | Point count = 4 43 | ================= use chained cloning in a class heirarchy ================= 44 | object(NS_cloning\Manager)#7 (2) { 45 | ["level":"NS_cloning\Manager":private]=> 46 | int(23) 47 | ["name":"NS_cloning\Employee":private]=> 48 | string(5) "Smith" 49 | } 50 | Inside NS_cloning\Manager::__clone 51 | Inside NS_cloning\Employee::__clone 52 | object(NS_cloning\Manager)#8 (2) { 53 | ["level":"NS_cloning\Manager":private]=> 54 | int(23) 55 | ["name":"NS_cloning\Employee":private]=> 56 | string(5) "Smith" 57 | } -------------------------------------------------------------------------------- /tests/Traits/trait_requirements.php: -------------------------------------------------------------------------------- 1 | cf1(); 18 | $this->if1(); 19 | } 20 | } 21 | 22 | class C2 extends C1 implements I1 { 23 | use T1; 24 | public function if1(): void { } 25 | } 26 | 27 | trait T2 { 28 | public function f(): void { 29 | $this->cf1(); 30 | $this->if1(); 31 | } 32 | require implements I1; 33 | require extends C1; 34 | } 35 | 36 | class C3 extends C1 implements I1 { 37 | use T2; 38 | public function if1(): void { } 39 | } 40 | 41 | /* 42 | class Cx { 43 | use T1; // Error 44 | } 45 | */ 46 | 47 | interface I2 { 48 | public function if2(): void; 49 | } 50 | 51 | trait T3 { 52 | require implements I1; 53 | require extends C1; // redundant, as C3 already extends C1, but permitted 54 | require implements I2; 55 | require implements I2; // redundant, but permitted 56 | require extends C3; 57 | require extends C3; // redundant, but permitted 58 | } 59 | 60 | class C4 extends C3 implements I1, I2 { 61 | use T3; 62 | public function if1(): void { } 63 | public function if2(): void { } 64 | } 65 | 66 | /* 67 | interface Ix { 68 | use Tx; 69 | } 70 | 71 | trait Tx { 72 | require implements Ix; // cyclic definition; not permitted 73 | } 74 | */ 75 | 76 | -------------------------------------------------------------------------------- /tests/Enums/enum_constraints.php: -------------------------------------------------------------------------------- 1 | ===================\n\n"; 9 | 10 | $c1 = new \NS_Complex\Complex(10.5, 5.67); 11 | echo "\$c1 = " . $c1 . "\n"; 12 | 13 | $c2 = new \NS_Complex\Complex(-10.98, -123.45); 14 | echo "\$c2 = " . $c2 . "\n"; 15 | 16 | echo "\$c1 + \$c2 = " . \NS_Complex\Complex::add($c1, $c2) . "\n"; 17 | echo "\$c1 - \$c2 = " . \NS_Complex\Complex::subtract($c1, $c2) . "\n"; 18 | 19 | echo "\n================== Complex ===================\n\n"; 20 | 21 | $c3 = new \NS_Complex\Complex(5, 6); 22 | echo "\$c3 = " . $c3 . "\n"; 23 | 24 | $c4 = new \NS_Complex\Complex(-10, -12); 25 | echo "\$c4 = " . $c4 . "\n"; 26 | 27 | echo "\$c3 + \$c4 = " . \NS_Complex\Complex::add($c3, $c4) . "\n"; 28 | echo "\$c3 - \$c4 = " . \NS_Complex\Complex::subtract($c3, $c4) . "\n"; 29 | 30 | echo "\n================== Complex ===================\n\n"; 31 | 32 | $c5 = new \NS_Complex\Complex(9, 5.4); 33 | echo "\$c5 = " . $c5 . "\n"; 34 | 35 | $c6 = new \NS_Complex\Complex(12.2, -20); 36 | echo "\$c6 = " . $c6 . "\n"; 37 | 38 | echo "\$c5 + \$c6 = " . \NS_Complex\Complex::add($c5, $c6) . "\n"; 39 | echo "\$c5 - \$c6 = " . \NS_Complex\Complex::subtract($c5, $c6) . "\n"; 40 | 41 | var_dump($c5, $c6, \NS_Complex\Complex::add($c5, $c6), \NS_Complex\Complex::subtract($c5, $c6)); 42 | } 43 | 44 | /* HH_FIXME[1002] call to main in strict*/ 45 | main(); -------------------------------------------------------------------------------- /tests/Types/shapes2.php.expectf: -------------------------------------------------------------------------------- 1 | 2 | Inside function NS_shapes2\f1 3 | 10, 20 4 | == is True 5 | != is False 6 | === is True 7 | !== is False 8 | 9 | 10 | Inside function NS_shapes2\f2 11 | 10, 20 12 | == is True 13 | != is False 14 | === is True 15 | !== is False 16 | 17 | 18 | Inside function NS_shapes2\main 19 | == is True 20 | != is False 21 | === is False 22 | !== is True 23 | 24 | == is True 25 | != is False 26 | === is True 27 | !== is False 28 | 29 | == is True 30 | != is False 31 | === is True 32 | !== is False 33 | 34 | 35 | === null fields === 36 | 37 | array(2) { 38 | ["a"]=> 39 | int(10) 40 | ["n"]=> 41 | NULL 42 | } 43 | array(1) { 44 | ["a"]=> 45 | int(10) 46 | } 47 | object(NS_shapes2\C)#1 (2) { 48 | ["p6a"]=> 49 | array(2) { 50 | ["a"]=> 51 | int(10) 52 | ["n"]=> 53 | NULL 54 | } 55 | ["p6b"]=> 56 | array(1) { 57 | ["a"]=> 58 | int(10) 59 | } 60 | } 61 | 62 | 63 | === null field access === 64 | 65 | $p5a['a']: 10 66 | $p5a['n']: 67 | $p5b['a']: 10 68 | 69 | Notice: Undefined index: n in %s/tests/Types/shapes2.php on line 61 70 | $p5b['n']: 71 | $p6a['a']: 10 72 | $p6a['n']: 73 | $p6b['a']: 10 74 | 75 | Notice: Undefined index: n in %s/tests/Types/shapes2.php on line 65 76 | $p6b['n']: 77 | 78 | Inside function NS_shapes2\f3 79 | $p['a']: 10 80 | $p['n']: xyz 81 | 82 | Inside function NS_shapes2\f3 83 | $p['a']: 10 84 | $p['n']: 85 | 86 | Inside function NS_shapes2\f3 87 | $p['a']: 10 88 | 89 | Notice: Undefined index: n in %s/tests/Types/shapes2.php on line 114 90 | $p['n']: -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/nullsafe_member_selection.php: -------------------------------------------------------------------------------- 1 | with an instance method ===================== 6 | 7 | class Bar1 { 8 | public function baz1(): int { 9 | return 5; 10 | } 11 | public static function sbaz1(): int { 12 | return 55; 13 | } 14 | } 15 | 16 | function get_Bar1(): ?Bar1 { 17 | if (rand(0, 10) === 5) { 18 | return null; 19 | } 20 | return new Bar1(); 21 | } 22 | 23 | function foo1(): ?int { 24 | $b = get_Bar1(); 25 | // Use the null-safe operator to access a method of class. 26 | 27 | // return $b?->sbaz1(); // error: method can't be static 28 | 29 | return $b?->baz1(); 30 | } 31 | 32 | // =================== use ?-> with a property ===================== 33 | 34 | class Bar2 { 35 | public function __construct(public string $str = "") {} 36 | public static string $sstr = "xx"; 37 | } 38 | 39 | function get_Bar2(): ?Bar2 { 40 | if (rand(0, 10) < 5) { 41 | return null; 42 | } 43 | return new Bar2("Hello"); 44 | } 45 | 46 | function foo2(): ?string { 47 | $b = get_Bar2(); 48 | // Use the null-safe operator to access a proprety of a class. 49 | 50 | // $b?->str = 'abc'; // error: ?-> syntax is not supported for lvalues 51 | 52 | // return $b?->sstr; // error: property can't be static 53 | 54 | return $b?->str; 55 | } 56 | 57 | function main(): void { 58 | var_dump(foo1()); 59 | var_dump(foo2()); 60 | } 61 | 62 | /* HH_FIXME[1002] call to main in strict*/ 63 | main(); 64 | -------------------------------------------------------------------------------- /tests/Expressions/Multiplicative_Operators/multiplication_division_modulus.php: -------------------------------------------------------------------------------- 1 | $e1< * >$e2<, result: "; var_dump($e1 * $e2); 11 | } 12 | echo "-------------------------------------\n"; 13 | } 14 | */ 15 | 16 | /* 17 | foreach ($oper as $e1) { 18 | foreach ($oper as $e2) { 19 | if (($e2) == 0) continue; // skip divide-by-zeros 20 | 21 | echo ">$e1< / >$e2<, result: "; var_dump($e1 / $e2); 22 | } 23 | echo "-------------------------------------\n"; 24 | } 25 | */ 26 | 27 | ///* 28 | $oper = array(100, -3); 29 | foreach ($oper as $e1) { 30 | foreach ($oper as $e2) { 31 | if (((int)$e2) == 0) continue; // skip divide-by-zeros 32 | 33 | echo ">$e1< % >$e2<, result: "; var_dump($e1 % $e2); 34 | } 35 | echo "-------------------------------------\n"; 36 | } 37 | 38 | // var_dump(10 % 3.0); // % requires int operands 39 | // var_dump(10.0 % 3); // % requires int operands 40 | // var_dump(10 % $p1_num); // % requires int operands 41 | // var_dump($p1_num % 3); // % requires int operands 42 | 43 | if (is_int($p1_num)) { 44 | echo ">$p1_num< % >3<, result: "; var_dump($p1_num % 3); // OK; num contains an int 45 | } 46 | //*/ 47 | } 48 | 49 | function main(): void { 50 | doit(11); 51 | } 52 | 53 | /* HH_FIXME[1002] call to main in strict*/ 54 | main(); 55 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/post-increment_and_decrement_integer_edge_cases.php: -------------------------------------------------------------------------------- 1 | ===========\n"; 54 | 55 | $a = array(10, 20); 56 | var_dump($a[0] ** 2); 57 | var_dump(f() ** 2); 58 | $c = new C; 59 | var_dump($c->prop ** 2); 60 | */ 61 | } 62 | 63 | /* HH_FIXME[1002] call to main in strict*/ 64 | main(); 65 | -------------------------------------------------------------------------------- /tests/Expressions/Postfix_Operators/function_call.php: -------------------------------------------------------------------------------- 1 | isFile() && $test_file->getExtension() === "php") { 15 | $test_contents = file_get_contents($test_file); 16 | $fixme_pattern = "/HH_FIXME\[1002\] call to main in strict/"; 17 | // Already there. Move on 18 | if (preg_match($fixme_pattern, $test_contents) === 1) { 19 | continue; 20 | } 21 | $fmain_pattern = "/function[ ]*main[ ]*\([\$\\A-Za-z0-9:\. ]*\)/"; 22 | if (preg_match($fmain_pattern, $test_contents) === 1) { 23 | $main_call_pattern = "/(\/\/)?[ ]*main[ ]*\(([\$\\A-Za-z0-9:\. ]*)\);/"; 24 | $fixme_str = "/* HH_FIXME[1002] call to main in strict*/" . PHP_EOL 25 | . "main($2);"; // $2 is any parameters in $main_call_pattern 26 | if (preg_match($main_call_pattern, $test_contents) === 1) { 27 | $test_contents = preg_replace($main_call_pattern, $fixme_str, 28 | $test_contents); 29 | } else { 30 | $test_contents .= PHP_EOL . $fixme_str; 31 | } 32 | } 33 | file_put_contents($test_file, $test_contents); 34 | } 35 | } 36 | } 37 | 38 | main(); 39 | -------------------------------------------------------------------------------- /tests/Types/shape_subtyping.php: -------------------------------------------------------------------------------- 1 | Bank); 13 | type Deposit = shape('trtype' => Bank, 'toaccnum' => int, 'amount' => float); 14 | type Withdrawal = shape('trtype' => Bank, 'fromaccnum' => int, 'amount' => float); 15 | type Transfer = shape('trtype' => Bank, 'fromaccnum' => int, 'toaccnum' => int, 'amount' => float); 16 | 17 | function main(): void { 18 | processTransaction(shape('trtype' => Bank::DEPOSIT, 'toaccnum' => 23456, 'amount' => 100.00)); 19 | processTransaction(shape('trtype' => Bank::WITHDRAWAL, 'fromaccnum' => 3157, 'amount' => 100.00)); 20 | processTransaction(shape('trtype' => Bank::TRANSFER, 'fromaccnum' => 23456, 'toaccnum' => 3157, 'amount' => 100.00)); 21 | } 22 | 23 | function processTransaction(Transaction $t): void { 24 | var_dump($t); 25 | 26 | $ary = Shapes::toArray($t); 27 | 28 | switch ($t['trtype']) { 29 | case Bank::TRANSFER: 30 | echo "Transfer: " . ((string)$ary['amount']) . " from Account " . ((string)$ary['fromaccnum']) 31 | . " to Account " . ((string)$ary['toaccnum']) . "\n"; 32 | break; 33 | 34 | case Bank::DEPOSIT: 35 | echo "Deposit: " . ((string)$ary['amount']) . " to Account " . ((string)$ary['toaccnum']) . "\n"; 36 | break; 37 | 38 | case Bank::WITHDRAWAL: 39 | echo "Withdrawal: " . ((string)$ary['amount']) . " from Account " . ((string)$ary['fromaccnum']) . "\n"; 40 | break; 41 | 42 | default: 43 | break; 44 | } 45 | } 46 | 47 | /* HH_FIXME[1002] call to main in strict*/ 48 | main(); -------------------------------------------------------------------------------- /tools/add_language_to_code_blocks.php: -------------------------------------------------------------------------------- 1 | $argv): void { 19 | if (!array_key_exists(1, $argv)) { 20 | die("Specify a language, such as 'Hack'"); 21 | } 22 | 23 | $spec_dir = __DIR__ . "/../spec"; 24 | 25 | $di = new RecursiveDirectoryIterator($spec_dir, 26 | RecursiveDirectoryIterator::SKIP_DOTS); 27 | $it = new RecursiveIteratorIterator($di); 28 | 29 | $code_block_pattern = "/(```)(php)?(\n.*?```\n)/s"; // /s matches newline for . 30 | // $1 = ``` 31 | // $2 = php ... match on php in case we used that before Hack was supported 32 | // $3 = \n.*?```\n 33 | $fix = "$1" . $argv[1] . "$3"; 34 | 35 | foreach($it as $spec_file) { 36 | if ($spec_file->isFile() && $spec_file->getExtension() === "md" && 37 | $spec_file->getFilename() !== "hack-spec-draft.md" && 38 | $spec_file->getFilename() !== "00-specification-for-hack.md") { 39 | $contents = file_get_contents($spec_file); 40 | $matches = array(); 41 | preg_match_all($code_block_pattern, $contents, $matches); 42 | $contents = preg_replace($code_block_pattern, $fix, $contents); 43 | file_put_contents($spec_file, $contents); 44 | } 45 | } 46 | } 47 | 48 | main($argv); 49 | -------------------------------------------------------------------------------- /tests/Functions/basics.php: -------------------------------------------------------------------------------- 1 | $e) { 17 | echo "\targ[$k] = >$e<\n"; 18 | } 19 | } 20 | 21 | // function having 2 declared parameters 22 | 23 | function f2(int $p1, int $p2): void { 24 | // A null value doesn't prove the argument wasn't passed; find a better test 25 | 26 | echo "f2: \$p1 = ".($p1 == null ? "null" : $p1). 27 | ", \$p2 = ".($p2 == null ? "null" : $p2)."\n"; 28 | } 29 | 30 | function square(num $v): num { 31 | return $v * $v; 32 | } 33 | 34 | function addVector(Vector $v1, Vector $v2): Vector { 35 | $result = Vector{}; 36 | 37 | // ... 38 | 39 | return $result; 40 | } 41 | 42 | function main(): void { 43 | // var_dump(f1()); // call f1, default return value is null 44 | // $f = f1; // PHP: assign this string to a variable; Hack disallows 45 | // $f(); // PHP: call f1 indirectly via $f; Hack disallows 46 | 47 | f1(); 48 | f1(10); 49 | f1(true, "green"); 50 | f1(23.45, null, array(1,2,3)); 51 | 52 | f2(10, 20); 53 | 54 | // some simple examples of function calls 55 | 56 | echo "5 squared = " . square(5) . "\n"; 57 | echo strlen("abcedfg")."\n"; 58 | 59 | $v = addVector(Vector {10, 20}, Vector {60, 30, 10}); 60 | var_dump($v); 61 | } 62 | 63 | /* HH_FIXME[1002] call to main in strict*/ 64 | main(); 65 | -------------------------------------------------------------------------------- /tools/toc.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | #Specification for Hack 10 | Facebook has dedicated all copyright to this specification to the public 11 | domain worldwide under the CC0 Public Domain Dedication located at 12 | . This specification 13 | is distributed without any warranty. 14 | 15 | (Initially written by Facebook, Inc., February 2015) 16 | 17 | **Table of Contents** 18 | EOS; 19 | 20 | $files = scandir($dir); 21 | $output = ""; 22 | 23 | foreach ($files as $file) { 24 | if ($file == '00-specification-for-hack.md' || $file == 'hack-spec-draft.md') { 25 | continue; 26 | } 27 | 28 | $anchors = []; 29 | 30 | $lines = file($dir . $file); 31 | foreach ($lines as $line) { 32 | if (!preg_match('/^(#+)\s*(.+)/', $line, $matches)) { 33 | continue; 34 | } 35 | 36 | list(, $hashes, $title) = $matches; 37 | $level = strlen($hashes) - 1; 38 | $indent = str_repeat(' ', $level); 39 | 40 | $anchor = strtr(strtolower($title), ' ', '-'); 41 | $anchor = preg_replace('/[^\w-]/', '', $anchor); 42 | 43 | if (isset($anchors[$anchor])) { 44 | $anchors[$anchor]++; 45 | $anchor .= '-' . $anchors[$anchor]; 46 | } else { 47 | $anchors[$anchor] = 0; 48 | } 49 | 50 | $output .= "$indent- [$title]($file#$anchor)\n"; 51 | } 52 | } 53 | 54 | file_put_contents($tocFile, "$prefix\n$output"); 55 | 56 | -------------------------------------------------------------------------------- /tests/Generics/constraints.php: -------------------------------------------------------------------------------- 1 | int, 'y' => int); 12 | 13 | class C1a { public function __construct(private T $p1) {} } 14 | class C1b {} 15 | class C1c {} 16 | class C1d {} 17 | class C1e {} 18 | class C1f {} 19 | class C1g {} 20 | class C1h> {} 21 | class C1i {} 22 | class C1j {} 23 | class C1k {} 24 | class C1l {} 25 | class C1m {} 26 | class C1n {} 27 | class C1o {} 28 | class C1p> {} 29 | 30 | class C2 { 31 | public function __construct(T1 $p1, T2 $p2) { 32 | echo "Inside " . __METHOD__ . "\n"; 33 | } 34 | } 35 | 36 | function maxVal(T $p1, T $p2): T { 37 | return $p1 > $p2 ? $p1 : $p2; 38 | } 39 | 40 | function main(): void { 41 | $c1a = new C1a(true); // OK 42 | var_dump($c1a); 43 | $c1a = new C1a(false); // OK 44 | var_dump($c1a); 45 | // $c1a = new C1a(123); // rejected; violates the constraint 46 | 47 | $c2 = new C2(new D1(), new CX()); 48 | $c2 = new C2(new D2(), new C()); 49 | 50 | echo "=============== maxVal ==================\n\n"; 51 | 52 | echo "maxVal(10, 20) = " . maxVal(10, 20) . "\n"; 53 | echo "maxVal(15.6, -20.78) = " . maxVal(15.6, -20.78) . "\n"; 54 | // echo "maxVal('red', 'green') = " . maxVal('red', 'green') . "\n"; 55 | } 56 | 57 | /* HH_FIXME[1002] call to main in strict*/ 58 | main(); 59 | -------------------------------------------------------------------------------- /tests/Expressions/Bitwise_Shift_Operators/bitwise_shift.php: -------------------------------------------------------------------------------- 1 | > %2d = %08X\t<< %2d = %08X\n", $v, $v, $i, $v >> $i, $i, $v << $i); 14 | } 15 | 16 | // Shift a negative value right and left using both in- and out-of-range counts 17 | 18 | $v = -1000; 19 | for ($i = -$NumBitsPerInt - 1; $i <= $NumBitsPerInt + 1; ++$i) { 20 | printf("%d(%08X): >> %2d = %08X\t<< %2d = %08X\n", $v, $v, $i, $v >> $i, $i, $v << $i); 21 | } 22 | 23 | // Figure out the algorithm the implementations use for negative and too-large shift counts 24 | 25 | for ($i = -129; $i <= 129; ++$i) { 26 | $rem = $i % $NumBitsPerInt; 27 | if ($rem == 0 || $i > 0) { 28 | echo "$i, ".$rem."\n"; 29 | } else { // have a negative shift 30 | $r = $NumBitsPerInt - (-$i % $NumBitsPerInt); 31 | echo "$i, ".$r."\n"; 32 | } 33 | } 34 | 35 | // Shift all kinds of scalar values 36 | 37 | $v = 10 << 2; 38 | // $v = 1.234 << 2; // non-numeric operand not allowed 39 | // $v = true << 2; // ... 40 | // $v = null << 2; // ... 41 | // $v = "123" << 2; // ... 42 | // $v = 10 << 2.0; // non-numeric operand not allowed 43 | 44 | $v = 10 >> 2; 45 | // $v = 1.234 >> 2; // non-numeric operand not allowed 46 | // $v = true >> 2; // ... 47 | // $v = null >> 2; // ... 48 | // $v = "123" >> 2; // ... 49 | } 50 | 51 | /* HH_FIXME[1002] call to main in strict*/ 52 | main(); 53 | -------------------------------------------------------------------------------- /tests/Expressions/Null_safe_method_call/null_safe_calls.php: -------------------------------------------------------------------------------- 1 | operator] 33 | */ 34 | 35 | function hello(int $j): int { 36 | echo "Inside " . __METHOD__ . "; \$j = $j\n"; 37 | return $j; 38 | } 39 | 40 | function test(?C $x): void { 41 | $i = 5; 42 | 43 | echo "------------ \$x?->f1(++\$i, hello(\$i))\n"; 44 | 45 | $res1 = $x?->f1(++$i, hello($i)); 46 | var_dump($res1); 47 | 48 | echo "------------ \$x?->f2(++\$i, hello(\$i))\n"; 49 | 50 | $res2 = $x?->f2(++$i, hello($i)); 51 | var_dump($res2); 52 | 53 | echo "------------ \$x?->f3(++\$i, hello(\$i))\n"; 54 | 55 | $res3 = $x?->f3(++$i, hello($i)); // allows >-> to call a void function thus producing a ?void result 56 | var_dump($res3); 57 | } 58 | 59 | function main(): void { 60 | echo "------------ test(new C())\n"; 61 | 62 | test(new C()); 63 | 64 | echo "------------ test(null)\n"; 65 | 66 | test(null); // the expressions in the method argument list DO GET CALLED ANYWAY 67 | } 68 | 69 | /* HH_FIXME[1002] call to main in strict*/ 70 | main(); 71 | --------------------------------------------------------------------------------