From fcb6c5caeb2cec9b56151fdc14a1808a97b67855 Mon Sep 17 00:00:00 2001 From: Shimenkov Mikhail Date: Fri, 14 Feb 2025 19:20:50 +0300 Subject: [PATCH 01/12] Remove primitive types Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/IBZQDX Reason: Need a more consistent type system Description: Remove primitive types from user-visible language (boxed types remain). Primitive types are reintroduced in a lowering at the end of the pipeline, just before code generation. Tests: all the tests are passed Signed-off-by: Georgy Bronnikov Signed-off-by: Shimenkov Mikhail Signed-off-by: Lirisman Karina Signed-off-by: Ermolaeva Varvara Signed-off-by: Kaskov Mikhail Signed-off-by: Kofanov Daniil Signed-off-by: Zelentsov Dmitry Signed-off-by: Xu Xinjie Signed-off-by: Afanasyev Vadim Signed-off-by: Kopyl Vasily Signed-off-by: Sergey Andreev Signed-off-by: Artemyev Andrey Signed-off-by: Khramov Maxim Change-Id: Icfba321cd153d8b7f3d3e9f379c99b20ef47f625 --- ets2panda/BUILD.gn | 2 + ets2panda/CMakeLists.txt | 2 + ets2panda/checker/ETSAnalyzer.cpp | 126 +- ets2panda/checker/ETSAnalyzerHelpers.cpp | 32 +- ets2panda/checker/ETSAnalyzerHelpers.h | 3 + ets2panda/checker/ETSchecker.cpp | 61 +- ets2panda/checker/ETSchecker.h | 48 +- ets2panda/checker/ets/aliveAnalyzer.cpp | 7 +- ets2panda/checker/ets/arithmetic.cpp | 448 +++-- ets2panda/checker/ets/arithmetic.h | 215 +-- ets2panda/checker/ets/assignAnalyzer.cpp | 4 +- ets2panda/checker/ets/castingContext.cpp | 7 +- ets2panda/checker/ets/function.cpp | 158 +- ets2panda/checker/ets/helpers.cpp | 95 +- ets2panda/checker/ets/narrowingConverter.h | 48 +- ets2panda/checker/ets/object.cpp | 146 +- ets2panda/checker/ets/typeCheckingHelpers.cpp | 46 +- ets2panda/checker/ets/typeRelationContext.cpp | 20 +- ets2panda/checker/ets/typeRelationContext.h | 7 +- ets2panda/checker/ets/validateHelpers.cpp | 10 +- ets2panda/checker/types/ets/byteType.h | 7 +- ets2panda/checker/types/ets/charType.h | 7 +- ets2panda/checker/types/ets/doubleType.h | 8 +- ets2panda/checker/types/ets/etsArrayType.cpp | 2 +- ets2panda/checker/types/ets/etsArrayType.h | 5 - .../types/ets/etsAsyncFuncReturnType.cpp | 9 + .../types/ets/etsAsyncFuncReturnType.h | 1 + ets2panda/checker/types/ets/etsBooleanType.h | 7 +- ets2panda/checker/types/ets/etsEnumType.h | 89 +- ets2panda/checker/types/ets/etsFunctionType.h | 5 - ets2panda/checker/types/ets/etsNeverType.h | 7 +- ets2panda/checker/types/ets/etsNullishTypes.h | 12 +- ets2panda/checker/types/ets/etsObjectType.cpp | 21 + ets2panda/checker/types/ets/etsObjectType.h | 5 - ets2panda/checker/types/ets/etsStringType.h | 5 - ets2panda/checker/types/ets/etsTupleType.h | 5 - .../checker/types/ets/etsTypeAliasType.h | 5 - ets2panda/checker/types/ets/etsUnionType.cpp | 60 +- ets2panda/checker/types/ets/etsUnionType.h | 5 +- ets2panda/checker/types/ets/etsVoidType.cpp | 7 +- ets2panda/checker/types/ets/etsVoidType.h | 3 +- ets2panda/checker/types/ets/floatType.h | 8 +- ets2panda/checker/types/ets/intType.h | 7 +- ets2panda/checker/types/ets/longType.h | 7 +- ets2panda/checker/types/ets/shortType.h | 7 +- ets2panda/checker/types/ets/types.h | 1 + ets2panda/checker/types/globalTypesHolder.cpp | 6 + ets2panda/checker/types/globalTypesHolder.h | 2 + ets2panda/checker/types/signature.cpp | 4 +- ets2panda/checker/types/signature.h | 6 + ets2panda/checker/types/type.h | 19 +- ets2panda/checker/types/typeRelation.cpp | 48 +- ets2panda/checker/types/typeRelation.h | 4 +- ets2panda/compiler/base/condition.cpp | 1 + ets2panda/compiler/core/ETSCompiler.cpp | 6 + .../compiler/core/ETSCompilerUnrechable.cpp | 5 - ets2panda/compiler/core/ETSGen.cpp | 41 +- ets2panda/compiler/core/ETSemitter.cpp | 251 +-- ets2panda/compiler/core/ETSemitter.h | 3 - ets2panda/compiler/core/compilerImpl.cpp | 7 +- ets2panda/compiler/lowering/checkerPhase.h | 4 +- .../lowering/ets/asyncMethodLowering.cpp | 1 + .../compiler/lowering/ets/boxingForLocals.cpp | 11 + .../ets/constantExpressionLowering.cpp | 1594 +++++++++++------ .../lowering/ets/constantExpressionLowering.h | 75 +- .../compiler/lowering/ets/enumLowering.cpp | 17 +- .../compiler/lowering/ets/enumLowering.h | 22 +- .../lowering/ets/enumPostCheckLowering.cpp | 25 +- .../lowering/ets/enumPostCheckLowering.h | 2 +- .../enumPropertiesInAnnotationsLowering.cpp | 85 + .../ets/enumPropertiesInAnnotationsLowering.h | 35 + .../lowering/ets/genericBridgesLowering.cpp | 18 +- .../lowering/ets/genericBridgesLowering.h | 2 +- .../compiler/lowering/ets/lambdaLowering.cpp | 8 +- .../compiler/lowering/ets/opAssignment.cpp | 18 +- .../compiler/lowering/ets/opAssignment.h | 5 +- .../compiler/lowering/ets/recordLowering.cpp | 30 +- .../compiler/lowering/ets/recordLowering.h | 4 +- .../compiler/lowering/ets/spreadLowering.cpp | 9 +- .../ets/topLevelStmts/globalClassHandler.cpp | 129 +- .../ets/topLevelStmts/globalClassHandler.h | 35 +- .../ets/topLevelStmts/topLevelStmts.cpp | 4 +- .../compiler/lowering/ets/unboxLowering.cpp | 1373 ++++++++++++++ .../compiler/lowering/ets/unboxLowering.h | 36 + ets2panda/compiler/lowering/phase.cpp | 6 + ets2panda/compiler/lowering/util.cpp | 17 + ets2panda/compiler/lowering/util.h | 1 + ets2panda/compiler/scripts/signatures.yaml | 7 + ets2panda/compiler/templates/signatures.h.erb | 11 + ets2panda/evaluate/irCheckHelper.cpp | 10 +- ets2panda/ir/ets/etsFunctionType.cpp | 4 - ets2panda/ir/ets/etsPrimitiveType.cpp | 16 +- ets2panda/ir/ets/etsTuple.cpp | 6 +- ets2panda/ir/expressions/binaryExpression.h | 3 - ets2panda/ir/expressions/identifier.cpp | 3 +- .../ir/expressions/literals/charLiteral.cpp | 17 +- .../ir/expressions/literals/numberLiteral.cpp | 18 + ets2panda/ir/expressions/memberExpression.cpp | 40 +- ets2panda/ir/expressions/unaryExpression.h | 7 +- ets2panda/ir/srcDump.cpp | 12 +- ets2panda/ir/srcDump.h | 2 + ets2panda/ir/statements/annotationUsage.cpp | 2 +- ets2panda/ir/statements/ifStatement.h | 5 + .../ir/statements/switchCaseStatement.cpp | 2 +- ets2panda/ir/statements/whileStatement.h | 5 + ets2panda/lexer/lexer.h | 1 + ets2panda/lexer/token/number.h | 94 +- ets2panda/parser/ETSparserExpressions.cpp | 1 + ets2panda/public/public.h | 2 +- .../ast/compiler/ets/DeclareCheckAssign.ets | 3 +- .../annotationDecl_bad_initializer08.ets | 8 +- .../annotationUsage_bad_param09.ets | 8 +- ..._specific_method_with_empty_rest_param.ets | 2 +- .../overload_signature_pos_2.ets | 5 +- .../FixedArray/spreadMultiArrayInTuple.ets | 29 + .../ets/FixedArray/tuple_types_5_neg.ets | 2 - .../ets/FixedArray/tuple_types_9_neg.ets | 2 - .../ets/FixedArray/unionCommonMember_neg.ets | 3 +- .../test/ast/compiler/ets/FunctionType10.ets | 2 +- .../test/ast/compiler/ets/FunctionType3.ets | 2 +- .../ets/TypeError_recursive_parameter_1.ets | 2 +- .../ets/TypeError_recursive_parameter_2.ets | 2 +- .../annotationDecl_bad_initializer08.ets | 8 +- .../annotationUsage_as_type10.ets | 4 +- .../annotationUsage_bad_param07.ets | 4 +- .../annotationUsage_bad_param09.ets | 8 +- .../annotationUsage_unordered_params.ets | 4 +- .../annotation_as_negative_case.ets | 6 +- .../test/ast/compiler/ets/assert_bad.ets | 4 +- .../test/ast/compiler/ets/async_import_3.ets | 2 +- .../ets/boxed_primitives_overloading.sts | 30 + .../ast/compiler/ets/boxingConversion1.ets | 2 +- .../ast/compiler/ets/boxingConversion4.ets | 6 +- .../cast_NonNullishType_to_PrimitiveType1.ets | 2 - .../cast_NonNullishType_to_PrimitiveType2.ets | 2 - .../cast_NonNullishType_to_PrimitiveType3.ets | 1 - .../cast_TypeParameter_to_PrimitiveType1.ets | 1 - .../cast_TypeParameter_to_PrimitiveType2.ets | 1 - .../cast_TypeParameter_to_PrimitiveType3.ets | 1 - .../ets/cast_UnionType_to_PrimitiveType1.ets | 2 - .../ets/cast_UnionType_to_PrimitiveType2.ets | 1 - .../ets/cast_UnionType_to_PrimitiveType3.ets | 1 - ...d_primitives_invoke_context_and_unions.sts | 35 + .../compiler/ets/circular_variable_init.ets | 2 +- ...n_call-context_Int-to-Double_typeerror.ets | 4 +- .../ast/compiler/ets/division-by-zero.ets | 26 + .../compiler/ets/enum-to-int-conversion.ets | 2 +- .../compiler/ets/enum_not_constant_var.ets | 1 - .../ast/compiler/ets/etsObjectToString0.ets | 2 +- .../ast/compiler/ets/etsObjectToString4.ets | 2 +- ...sorNameDuplicatedWithExtensionFunction.ets | 11 +- ...sionAccessorNameDuplicatedWithFunction.ets | 11 +- ...ension_function_access_protected_field.ets | 2 +- ...function_duplicated_with_private_field.ets | 2 +- .../extension_function_miss_signature.ets | 6 +- .../extension_function_return_this_neg.ets | 2 +- .../ets/genericObjectLiteral_neg_1.ets | 2 +- .../ets/genericObjectLiteral_neg_2.ets | 2 +- .../ets/genericObjectLiteral_neg_3.ets | 2 +- .../compiler/ets/generic_typealias_5_neg.ets | 2 +- .../generics_primitive_type_param_neg_1.ets | 3 +- .../compiler/ets/identifierReference10.ets | 2 +- .../compiler/ets/identifierReference12.ets | 2 +- .../compiler/ets/identifierReference16.ets | 2 +- .../ast/compiler/ets/identifierReference3.ets | 2 +- .../ast/compiler/ets/identifierReference9.ets | 2 +- .../package_test_6/package_module_1.ets | 2 +- .../package_test_6/package_module_2.ets | 2 +- .../package_test_9/package_module.ets | 2 +- .../package_module_with_semantic_error.ets | 2 +- .../package_module_with_syntax_error.ets | 2 +- .../package_with_both_errors.ets | 2 +- .../import_chain_with_errors/import_1.ets | 4 +- .../import_chain_with_errors/import_2.ets | 2 +- .../import_chain_with_errors/master_file.ets | 8 +- .../ast/compiler/ets/infinityNarrowing.ets | 9 +- .../invalidIndirectInheritanceFromClass.ets | 2 +- ...nvalidIndirectInheritanceFromInterface.ets | 2 +- .../ets/invalidInheritanceFromClass.ets | 2 +- .../ets/invalidInheritanceFromInterface.ets | 2 +- ...tBlockStatementDifferentTypeInfunction.ets | 2 +- .../test/ast/compiler/ets/lambdaFunction5.ets | 2 +- ...on-class-and-interface-in-signatures_6.ets | 2 +- ...pace_access_violation_import_conflicts.ets | 2 +- .../namespace_tests/namespace_as_type10.ets | 4 +- .../ets/objectLiteralPrimitiveContextType.ets | 2 +- .../ets/objectLiteralWrongValueType.ets | 2 +- .../ets/objectLiteral_abstract_class.ets | 2 +- .../test/ast/compiler/ets/override11.ets | 4 +- .../test/ast/compiler/ets/override14.ets | 2 - .../test/ast/compiler/ets/override15.ets | 4 +- ets2panda/test/ast/compiler/ets/override3.ets | 4 +- ets2panda/test/ast/compiler/ets/override7.ets | 4 +- .../ets/overrideModifierNotOverriding.ets | 2 +- .../ast/compiler/ets/recursive_class_neg.ets | 6 +- .../ets/recursive_interface_neg_1.ets | 2 +- .../ets/recursive_interface_neg_2.ets | 2 +- .../compiler/ets/recursive_union_neg_1.ets | 2 +- .../overload_signature_neg_1.ets | 3 +- .../overload_signature_neg_2.ets | 4 +- .../overload_signature_pos_1.ets | 5 +- .../overload_signature_pos_2.ets | 5 +- .../ast/compiler/ets/switchcaseDuplicate.ets | 6 +- .../ast/compiler/ets/tuple_types_10_neg.ets | 2 +- .../ast/compiler/ets/tuple_types_11_neg.ets | 2 +- .../ast/compiler/ets/tuple_types_1_neg.ets | 2 +- .../ast/compiler/ets/tuple_types_6_neg.ets | 3 +- .../ast/compiler/ets/tuple_types_9_neg.ets | 2 +- .../type_error_processing/type_handlers.ets | 3 - .../validate_signatures_throw_type_error.ets | 2 +- ...signatures_throw_type_error_more_param.ets | 2 +- .../ets/voidTypeInBinaryOperation.ets | 2 +- .../ast/parser/ets/FixedArray/StringFasta.ets | 34 +- .../ets_never_type_without_affect_other.ets | 2 +- .../ast/parser/ets/FixedArray/for_of_02.ets | 2 +- .../FixedArray/illegal_union_member_exp.ets | 2 + .../ets/FixedArray/nonIntegralIndex.ets | 2 +- .../predefined_non_primitive_types.ets | 2 +- .../ets/FixedArray/record_object_value.ets | 4 +- .../ast/parser/ets/MultipleClassErrors.ets | 2 +- ets2panda/test/ast/parser/ets/StringFasta.ets | 34 +- .../test/ast/parser/ets/UnexpectedToken.ets | 1 - .../test/ast/parser/ets/accessor_call.ets | 2 +- .../test/ast/parser/ets/ambiguous_call_2.ets | 4 +- .../annotationUsage_bad_param04.ets | 2 +- .../ets/assert_with_not_boolean_type_1.ets | 2 +- .../ets/assert_with_not_boolean_type_2.ets | 4 +- ...nctional_variable_to_functional_type_1.ets | 2 +- ...all_expression_for_non_functional_type.ets | 3 +- .../parser/ets/class_optional_property.ets | 2 +- .../ets/constant_expression_divide_zero.ets | 4 +- .../test/ast/parser/ets/cycle_constructor.ets | 2 +- .../ast/parser/ets/declare_class_bad_1.ets | 2 +- .../ast/parser/ets/declare_class_bad_3.ets | 2 +- .../ast/parser/ets/declare_namespace_5.ets | 1 + .../ast/parser/ets/differentTypeCompare.ets | 2 +- .../dynamic_class_ctor_decl_import_bad.ets | 4 +- .../dynamic_class_field_decl_import_bad_1.ets | 2 +- .../dynamic_class_field_decl_import_bad_2.ets | 2 +- ...dynamic_class_method_decl_import_bad_1.ets | 2 +- ...dynamic_class_method_decl_import_bad_2.ets | 2 +- ets2panda/test/ast/parser/ets/enum15.ets | 3 +- .../ast/parser/ets/enum_default_negative1.ets | 3 +- .../ets_never_type_without_affect_other.ets | 2 +- .../test/ast/parser/ets/for_await_of_loop.ets | 1 - ets2panda/test/ast/parser/ets/for_of_02.ets | 2 +- .../ast/parser/ets/for_of_loop_variable.ets | 8 +- .../ets/function_implicit_return_type4.ets | 4 +- .../test/ast/parser/ets/generic_error.ets | 2 +- .../ets/generics_type_param_constraint_8.ets | 2 +- .../ets/getter_setter_access_modifiers_2.ets | 8 +- .../parser/ets/illegal_union_member_exp.ets | 3 + .../imported_module_2.ets | 2 +- .../test/ast/parser/ets/keyof_constraint.ets | 2 +- .../parser/ets/lambda-type-inference-neg.ets | 3 +- .../lambda-type-inference-overloaded-1.ets | 4 +- ets2panda/test/ast/parser/ets/loops.ets | 1 - .../Readonly-with-ArrayType-test2.ets | 4 +- .../Readonly-with-ArrayType-test3.ets | 2 +- .../readonly-parameter-test2.ets | 2 +- .../readonly-parameter-test5.ets | 4 +- .../ast/parser/ets/recordKeyTypeCheck01.ets | 1 - .../ast/parser/ets/recordKeyTypeCheck02.ets | 2 +- .../ast/parser/ets/recordKeyTypeCheck03.ets | 2 +- .../test/ast/parser/ets/rest_parameter_06.ets | 2 +- .../test/ast/parser/ets/rest_parameter_07.ets | 4 +- .../test/ast/parser/ets/rest_parameter_08.ets | 6 +- .../ets/type_decution_unnecessary_boxing.ets | 3 +- .../ast/parser/ets/unexpected_token_43.ets | 11 +- .../ets/boxingConversion2-expected.txt | 6 +- .../test/compiler/ets/boxingConversion2.ets | 2 +- .../boxingUnboxingExpressions-expected.txt | 12 +- .../ets/boxingUnboxingExpressions.ets | 4 +- .../ets/conversion-w-ASExpr-expected.txt | 442 +---- .../ets/dynamicLambdaJSValue-expected.txt | 2 +- .../ets/dynamic_instanceof_error-expected.txt | 1 - ...as_class_member_getValue_call-expected.txt | 4 +- .../ets/generic_arrayaslist-expected.txt | 19 +- .../ets/import_tests/enum_export-expected.txt | 6 +- ...rted_function_return_type_lib-expected.txt | 2 +- .../ets/instanceof_object_long-expected.txt | 1 - .../lambda_infer_type_param2-expected.txt | 34 +- .../ets/switchStatementBoxing-expected.txt | 5 +- ...tchStatementCorrectConversion-expected.txt | 5 +- .../compiler/ets/tuple_types_1-expected.txt | 2 +- .../compiler/ets/tuple_types_15-expected.txt | 2 +- .../parser/ets/AccessBinaryTrees-expected.txt | 160 +- .../test/parser/ets/AccessNBody-expected.txt | 1008 ++--------- .../test/parser/ets/AccessNSieve-expected.txt | 289 +-- .../ets/Bitops3BitBitsInByte-expected.txt | 39 +- .../parser/ets/BitopsBitsInByte-expected.txt | 39 +- .../parser/ets/BitopsBitwiseAnd-expected.txt | 39 +- .../parser/ets/BitopsNSieveBits-expected.txt | 43 +- .../ets/ControlFlowRecursive-expected.txt | 121 +- .../test/parser/ets/MathCordic-expected.txt | 117 +- .../parser/ets/MathPartialSums-expected.txt | 159 +- .../parser/ets/MathSpectralNorm-expected.txt | 39 +- .../test/parser/ets/Morph3d-expected.txt | 557 +----- .../test/parser/ets/StringBase64-expected.txt | 470 +---- ...s_expression_unary_expression-expected.txt | 34 +- ets2panda/test/parser/ets/assert-expected.txt | 2 +- ets2panda/test/parser/ets/assign-expected.txt | 5 +- .../test/parser/ets/binary_op-expected.txt | 52 +- .../parser/ets/binary_operations-expected.txt | 1354 +------------- .../test/parser/ets/binary_operations.ets | 4 +- .../test/parser/ets/boolean_cond-expected.txt | 36 +- .../parser/ets/cast_expressions-expected.txt | 242 +-- .../test/parser/ets/class_init-expected.txt | 36 +- .../conditionalExpressionType-expected.txt | 818 +-------- .../parser/ets/conditionalExpressionType.ets | 2 +- .../test/parser/ets/conversions-expected.txt | 34 +- .../test/parser/ets/declare_enum-expected.txt | 2 +- .../ets/default_parameter5-expected.txt | 2 +- .../ets/default_parameter8-expected.txt | 34 +- ..._implicitly_typed_return_void-expected.txt | 132 +- .../test/parser/ets/field_decl-expected.txt | 4 +- ets2panda/test/parser/ets/field_decl.ets | 2 +- .../ets/float_pont_format_2-expected.txt | 36 +- .../ets/float_pont_format_3-expected.txt | 36 +- .../ets/float_pont_format_4-expected.txt | 36 +- .../ets/float_pont_format_5-expected.txt | 36 +- .../ets/float_pont_format_6-expected.txt | 36 +- .../ets/float_pont_format_7-expected.txt | 166 +- .../ets/float_pont_format_8-expected.txt | 548 +----- .../parser/ets/float_separator_1-expected.txt | 6 +- .../test/parser/ets/float_separator_1.ets | 2 +- .../parser/ets/for_with_break-expected.txt | 2 +- .../parser/ets/forofUnboxing-expected.txt | 102 +- ...unction_implicit_return_type8-expected.txt | 6 +- ...unction_implicit_return_type9-expected.txt | 6 +- .../imported_module_2-expected.txt | 4 +- .../imported_module_2.ets | 2 +- .../packages/package_module_1-expected.txt | 4 +- .../packages/package_module_2-expected.txt | 8 +- .../packages/package_module_2.ets | 2 +- .../ets/labeledDoWhileStatement-expected.txt | 2 +- .../ets/labeledForStatement-expected.txt | 2 +- .../ets/labeledWhileStatement-expected.txt | 2 +- ...bda-type-inference-overloaded-expected.txt | 1 - .../test/parser/ets/null_valid-expected.txt | 5 +- .../parentheses_expression_value-expected.txt | 2 +- .../parser/ets/rest_parameter_02-expected.txt | 34 +- .../parser/ets/rethrow-func-1-expected.txt | 37 +- .../parser/ets/string_template_1-expected.txt | 2 +- .../parser/ets/string_template_2-expected.txt | 108 +- .../parser/ets/string_template_3-expected.txt | 133 +- .../parser/ets/string_template_4-expected.txt | 97 +- .../test/parser/ets/switch2-expected.txt | 3 + .../ets/switch_char_compare_num-expected.txt | 1 + .../ets/switch_enum_string_case-expected.txt | 2 +- .../ets/switch_readonly_member-expected.txt | 78 +- ..._readonly_member_compare_char-expected.txt | 78 +- ...eadonly_member_compare_char_2-expected.txt | 78 +- .../parser/ets/test_type_alias6-expected.txt | 2 +- .../parser/ets/this_cmp_object-expected.txt | 50 +- .../ets/tupleIndexWithNumbers-expected.txt | 10 +- .../test/parser/ets/tuple_type_1-expected.txt | 34 +- .../test/parser/ets/unary_op-expected.txt | 86 +- .../test/parser/ets/var_declare-expected.txt | 6 +- ets2panda/test/parser/ets/var_declare.ets | 2 +- ets2panda/test/runtime/ets/AliasPrimitive.ets | 19 +- ets2panda/test/runtime/ets/ArrayLiteral.ets | 4 +- ets2panda/test/runtime/ets/CastPrimitive.ets | 2 +- .../runtime/ets/ConditionalExpression_01.ets | 8 +- .../test/runtime/ets/RecordKeyTypeCheck.ets | 4 - .../test/runtime/ets/RegisterSpiller.ets | 2 +- ...1.ets => boxed_primitives_overloading.ets} | 24 +- .../test/runtime/ets/boxingUnboxingCalls.ets | 12 +- ...d_primitives_invoke_context_and_unions.sts | 35 + .../runtime/ets/conditionalExpressionLUB.ets | 16 +- .../test/runtime/ets/division-by-zero.ets | 36 +- .../ets/local-class-capture-boxing.ets | 2 +- .../ets/local-class-capture-not-boxing.ets | 2 +- ets2panda/test/runtime/ets/skippedTest.ets | 2 +- .../test/runtime/ets/tuple_types_runtime.ets | 2 +- .../test/runtime/ets/visible_signatures.ets | 24 +- .../astchecker/astchecker-ets-ignored.txt | 97 + .../ets-runtime/ets-runtime-ignored.txt | 26 + .../test-lists/parser/parser-ets-ignored.txt | 18 + .../test-lists/parser/parser-js-ignored.txt | 17 + .../mutiple_annotations_for_function.cpp | 29 +- ets2panda/test/unit/lsp/get_diagnostics.cpp | 4 +- .../get_type_of_symbol_at_location_test.cpp | 32 +- ets2panda/test/unit/lsp/inlay_hints_test.cpp | 2 +- ...plugin_proceed_to_state_ast_node_check.cpp | 4 +- ...st_node_transform_children_recursively.cpp | 1 + ..._proceed_to_state_create_as_expression.cpp | 4 +- ..._state_create_ets_parameter_expression.cpp | 2 + ...gin_proceed_to_state_member_expression.cpp | 8 +- ...ugin_proceed_to_state_this_into_method.cpp | 4 +- .../test/unit/rest_parameter_flag_test.cpp | 4 +- ets2panda/util/diagnostic/semantic.yaml | 22 +- ets2panda/util/diagnostic/syntax.yaml | 2 +- ets2panda/util/helpers.cpp | 54 + ets2panda/util/helpers.h | 9 + ets2panda/varbinder/scope.cpp | 5 +- ets2panda/varbinder/variable.cpp | 4 +- 397 files changed, 5535 insertions(+), 10000 deletions(-) create mode 100644 ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp create mode 100644 ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.h create mode 100644 ets2panda/compiler/lowering/ets/unboxLowering.cpp create mode 100644 ets2panda/compiler/lowering/ets/unboxLowering.h create mode 100644 ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets create mode 100644 ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts create mode 100644 ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.sts create mode 100644 ets2panda/test/ast/compiler/ets/division-by-zero.ets rename ets2panda/test/runtime/ets/{most_specific_method_with_rest_param_1.ets => boxed_primitives_overloading.ets} (60%) create mode 100644 ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index c4886adedc..22a8026b70 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -217,6 +217,7 @@ libes2panda_sources = [ "compiler/lowering/ets/dynamicImportLowering.cpp", "compiler/lowering/ets/enumLowering.cpp", "compiler/lowering/ets/enumPostCheckLowering.cpp", + "compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp", "compiler/lowering/ets/expandBrackets.cpp", "compiler/lowering/ets/expressionLambdaLowering.cpp", "compiler/lowering/ets/extensionAccessorLowering.cpp", @@ -248,6 +249,7 @@ libes2panda_sources = [ "compiler/lowering/ets/topLevelStmts/importExportDecls.cpp", "compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp", "compiler/lowering/ets/typeFromLowering.cpp", + "compiler/lowering/ets/unboxLowering.cpp", "compiler/lowering/ets/unionLowering.cpp", "compiler/lowering/phase.cpp", "compiler/lowering/plugin_phase.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index b4a4c0c06b..b75743efaa 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -293,7 +293,9 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/typeFromLowering.cpp compiler/lowering/ets/enumLowering.cpp compiler/lowering/ets/enumPostCheckLowering.cpp + compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp compiler/lowering/ets/setJumpTarget.cpp + compiler/lowering/ets/unboxLowering.cpp ir/astDump.cpp ir/srcDump.cpp ir/astNode.cpp diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 65b83520da..331c9b6048 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1018,7 +1018,7 @@ checker::Type *ETSAnalyzer::GetSmartType(ir::AssignmentExpression *expr, checker if (expr->Left()->IsIdentifier() && expr->Target() != nullptr) { // Now try to define the actual type of Identifier so that smart cast can be used in further checker // processing - smartType = checker->ResolveSmartType(rightType, leftType); + smartType = checker->ResolveSmartType(rightType, leftType, expr->Right()->IsLiteral()); auto const *const variable = expr->Target(); // Add/Remove/Modify smart cast for identifier @@ -1488,6 +1488,45 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const return expr->TsType(); } +static bool IsNumericType(ETSChecker *checker, Type *type) +{ + return checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), type); +} + +static Type *BiggerNumericType(ETSChecker *checker, Type *t1, Type *t2) +{ + ES2PANDA_ASSERT(IsNumericType(checker, t1)); + ES2PANDA_ASSERT(IsNumericType(checker, t2)); + + auto *rel = checker->Relation(); + + if (rel->IsSupertypeOf(checker->GlobalDoubleBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalDoubleBuiltinType(), t2)) { + return checker->GlobalDoubleBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalFloatBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalFloatBuiltinType(), t2)) { + return checker->GlobalFloatBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalLongBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalLongBuiltinType(), t2)) { + return checker->GlobalLongBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalIntBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalIntBuiltinType(), t2)) { + return checker->GlobalIntBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalShortBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalShortBuiltinType(), t2)) { + return checker->GlobalShortBuiltinType(); + } + if (rel->IsSupertypeOf(checker->GlobalByteBuiltinType(), t1) || + rel->IsSupertypeOf(checker->GlobalByteBuiltinType(), t2)) { + return checker->GlobalByteBuiltinType(); + } + ES2PANDA_UNREACHABLE(); +} + checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const { if (expr->TsType() != nullptr) { @@ -1525,21 +1564,10 @@ checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const if (checker->IsTypeIdenticalTo(consequentType, alternateType)) { expr->SetTsType(checker->GetNonConstantType(consequentType)); + } else if (IsNumericType(GetETSChecker(), consequentType) && IsNumericType(GetETSChecker(), alternateType)) { + expr->SetTsType(BiggerNumericType(GetETSChecker(), consequentType, alternateType)); } else { - // If possible and required update number literal type to the proper value (identical to left-side type) - if (alternate->IsNumberLiteral() && - checker->AdjustNumberLiteralType(alternate->AsNumberLiteral(), alternateType, consequentType)) { - expr->SetTsType(consequentType); - } else if (consequent->IsNumberLiteral() && - checker->AdjustNumberLiteralType(consequent->AsNumberLiteral(), consequentType, alternateType)) { - expr->SetTsType(alternateType); - } else { - expr->SetTsType(checker->CreateETSUnionType({consequentType, alternateType})); - if (expr->TsType()->IsETSReferenceType()) { - checker->MaybeBoxExpression(expr->Consequent()); - checker->MaybeBoxExpression(expr->Alternate()); - } - } + expr->SetTsType(checker->CreateETSUnionType({consequentType, alternateType})); } return expr->TsType(); @@ -1646,7 +1674,7 @@ checker::Type *ETSAnalyzer::ResolveMemberExpressionByBaseType(ETSChecker *checke if (baseType->IsETSArrayType()) { if (expr->Property()->AsIdentifier()->Name().Is("length")) { - return expr->AdjustType(checker, checker->GlobalIntType()); + return expr->AdjustType(checker, checker->GlobalIntBuiltinType()); } return expr->SetAndAdjustType(checker, checker->GlobalETSObjectType()); @@ -2056,8 +2084,6 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const auto argType = expr->argument_->Check(checker); const auto isCondExpr = expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK; checker::Type *operandType = checker->ApplyUnaryOperatorPromotion(argType, true, true, isCondExpr); - auto unboxedOperandType = - isCondExpr ? checker->MaybeUnboxConditionalInRelation(argType) : checker->MaybeUnboxInRelation(argType); if (argType != nullptr && argType->IsETSBigIntType() && argType->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL)) { switch (expr->OperatorType()) { @@ -2090,11 +2116,6 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const } } - if ((argType != nullptr) && argType->IsETSObjectType() && (unboxedOperandType != nullptr) && - unboxedOperandType->IsETSPrimitiveType()) { - expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedOperandType)); - } - SetTsTypeForUnaryExpression(checker, expr, operandType); checker->Context().CheckUnarySmartCastCondition(expr); @@ -2146,11 +2167,6 @@ checker::Type *ETSAnalyzer::Check(ir::UpdateExpression *expr) const return expr->SetTsType(checker->GlobalTypeError()); } - if (operandType->IsETSObjectType()) { - expr->Argument()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(unboxedType) | - checker->GetBoxingFlag(unboxedType)); - } - return expr->SetTsType(operandType); } @@ -2166,7 +2182,9 @@ checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const { ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { - expr->SetTsType(checker->CreateETSBooleanType(expr->Value())); + auto type = checker->GlobalETSBooleanBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); } return expr->TsType(); } @@ -2175,7 +2193,9 @@ checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const { ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { - expr->SetTsType(checker->Allocator()->New(expr->Char())); + auto type = checker->GlobalCharBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); } return expr->TsType(); } @@ -2192,23 +2212,52 @@ checker::Type *ETSAnalyzer::Check(ir::NullLiteral *expr) const checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const { ETSChecker *checker = GetETSChecker(); + if (expr->TsType() != nullptr) { + return expr->TsType(); + } if (expr->Number().IsInt()) { - expr->SetTsType(checker->CreateIntType(expr->Number().GetInt())); + auto type = checker->GlobalIntBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); return expr->TsType(); } if (expr->Number().IsLong()) { - expr->SetTsType(checker->CreateLongType(expr->Number().GetLong())); + auto type = checker->GlobalLongBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); return expr->TsType(); } if (expr->Number().IsFloat()) { - expr->SetTsType(checker->CreateFloatType(expr->Number().GetFloat())); + auto type = checker->GlobalFloatBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); return expr->TsType(); } - expr->SetTsType(checker->CreateDoubleType(expr->Number().GetDouble())); - return expr->TsType(); + if (expr->Number().IsDouble()) { + auto type = checker->GlobalDoubleBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); + return expr->TsType(); + } + + if (expr->Number().IsShort()) { + auto type = checker->GlobalShortBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); + return expr->TsType(); + } + + if (expr->Number().IsByte()) { + auto type = checker->GlobalByteBuiltinType()->Clone(GetChecker()); + type->AddTypeFlag(TypeFlag::CONSTANT); + expr->SetTsType(type); + return expr->TsType(); + } + + return checker->GlobalTypeError(); } checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const @@ -2463,7 +2512,7 @@ static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, relation->SetNode(ident); if (auto ctx = checker::AssignmentContext(checker->Relation(), ident, elemType, iterType, ident->Start(), std::nullopt, TypeRelationFlag::NO_THROW); - !ctx.IsAssignable()) { + !ctx.IsAssignable() && !relation->IsLegalBoxedPrimitiveConversion(iterType, elemType)) { checker->LogError(diagnostic::ITERATOR_ELEMENT_TYPE_MISMATCH, {elemType, iterType}, st->Start()); return false; } @@ -2474,7 +2523,7 @@ static bool ValidateAndProcessIteratorType(ETSChecker *checker, Type *elemType, const auto variable = ident->Variable(); if (variable != nullptr) { // Set smart type for variable of 'for-of' statement - const auto smartType = checker->ResolveSmartType(elemType, variable->TsType()); + const auto smartType = checker->ResolveSmartType(elemType, variable->TsType(), false); checker->Context().SetSmartCast(variable, smartType); } @@ -2769,6 +2818,7 @@ checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const checker::TypeRelationFlag::NONE); auto *comparedExprType = checker->CheckSwitchDiscriminant(st->Discriminant()); + // may have no meaning to unbox comparedExprType auto unboxedDiscType = (st->Discriminant()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U ? checker->MaybeUnboxInRelation(comparedExprType) : comparedExprType; @@ -2895,7 +2945,7 @@ checker::Type *ETSAnalyzer::Check(ir::VariableDeclarator *st) const // NOTE: T_S and K_o_t_l_i_n don't act in such way, but we can try - why not? :) auto *smartType = variableType; if (auto *const initType = st->Init() != nullptr ? st->Init()->TsType() : nullptr; initType != nullptr) { - smartType = checker->ResolveSmartType(initType, variableType); + smartType = checker->ResolveSmartType(initType, variableType, st->Init()->IsLiteral()); // Set smart type for identifier if it differs from annotated type // Top-level and captured variables are not processed here! if (!checker->Relation()->IsIdenticalTo(variableType, smartType)) { diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index a663a854b8..b9368223e8 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -522,7 +522,7 @@ void ProcessExclamationMark(ETSChecker *checker, ir::UnaryExpression *expr, chec return; } - auto exprRes = operandType->ResolveConditionExpr(); + auto exprRes = IsConstantTestValue(expr->Argument()); if (std::get<0>(exprRes)) { auto tsType = checker->CreateETSBooleanType(!std::get<1>(exprRes)); tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); @@ -559,7 +559,8 @@ void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, break; } - expr->Argument()->SetTsType(expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType))); + expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType)); + expr->Argument()->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType)); break; } case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { @@ -618,7 +619,8 @@ bool CheckArgumentVoidType(checker::Type *&funcReturnType, ETSChecker *checker, ir::ReturnStatement *st) { if (name.find(compiler::Signatures::ETS_MAIN_WITH_MANGLE_BEGIN) != std::string::npos) { - if (!funcReturnType->IsETSVoidType() && !funcReturnType->IsIntType()) { + if (!funcReturnType->IsETSVoidType() && + !checker->Relation()->IsSupertypeOf(checker->GlobalIntBuiltinType(), funcReturnType)) { checker->LogError(diagnostic::MAIN_BAD_RETURN, {}, st->Start()); } } @@ -813,4 +815,28 @@ void CheckAllConstPropertyInitialized(checker::ETSChecker *checker, ir::ETSModul } } } + +// NOLINTBEGIN(readability-else-after-return) +std::tuple IsConstantTestValue(ir::Expression const *expr) +{ + if (expr->IsNullLiteral() || expr->IsUndefinedLiteral()) { + return {true, false}; + } else if (expr->IsBooleanLiteral()) { + return {true, expr->AsBooleanLiteral()->Value()}; + } else if (expr->IsStringLiteral()) { + return {true, expr->AsStringLiteral()->Str().Length() != 0}; + } else if (expr->IsCharLiteral()) { + return {true, expr->AsCharLiteral()->Char() != 0}; + } else if (expr->IsBigIntLiteral()) { + return {true, expr->AsBigIntLiteral()->Str() != "0"}; + } else if (expr->IsNumberLiteral()) { + auto num = expr->AsNumberLiteral()->Number(); + return {true, !num.IsZero()}; + } else if (expr->TsType()->IsETSEnumType() && expr->TsType()->IsConstantType()) { + // NOTE(gogabr): Should handle enum constants + return {false, false}; + } + return {false, false}; +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ETSAnalyzerHelpers.h b/ets2panda/checker/ETSAnalyzerHelpers.h index 979d6413ac..1b5e9a814f 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.h +++ b/ets2panda/checker/ETSAnalyzerHelpers.h @@ -63,7 +63,10 @@ void CastPossibleTupleOnRHS(ETSChecker *checker, ir::AssignmentExpression *expr) void ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction *containingFunc, checker::Type *&funcReturnType, ir::ReturnStatement *st, ir::Expression *stArgument); bool CheckReturnTypeNecessity(ir::MethodDefinition *node); + void CheckAllConstPropertyInitialized(checker::ETSChecker *checker, ir::ETSModule *pkg); + +std::tuple IsConstantTestValue(ir::Expression const *expr); } // namespace ark::es2panda::checker #endif // ES2PANDA_CHECKER_ETSANALYZERHELPERS_H diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index 24b38be959..93db5d483b 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -376,41 +376,80 @@ Type *ETSChecker::GlobalByteType() const return GetGlobalTypesHolder()->GlobalByteType(); } +Type *ETSChecker::GlobalByteBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalByteBuiltinType(); +} + Type *ETSChecker::GlobalShortType() const { return GetGlobalTypesHolder()->GlobalShortType(); } +Type *ETSChecker::GlobalShortBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalShortBuiltinType(); +} + Type *ETSChecker::GlobalIntType() const { return GetGlobalTypesHolder()->GlobalIntType(); } +Type *ETSChecker::GlobalIntBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); +} + Type *ETSChecker::GlobalLongType() const { return GetGlobalTypesHolder()->GlobalLongType(); } +Type *ETSChecker::GlobalLongBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalLongBuiltinType(); +} + Type *ETSChecker::GlobalFloatType() const { return GetGlobalTypesHolder()->GlobalFloatType(); } +Type *ETSChecker::GlobalFloatBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalFloatBuiltinType(); +} + Type *ETSChecker::GlobalDoubleType() const { return GetGlobalTypesHolder()->GlobalDoubleType(); } +Type *ETSChecker::GlobalDoubleBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalDoubleBuiltinType(); +} + Type *ETSChecker::GlobalCharType() const { return GetGlobalTypesHolder()->GlobalCharType(); } +Type *ETSChecker::GlobalCharBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalCharBuiltinType(); +} Type *ETSChecker::GlobalETSBooleanType() const { return GetGlobalTypesHolder()->GlobalETSBooleanType(); } +Type *ETSChecker::GlobalETSBooleanBuiltinType() const +{ + return GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); +} + Type *ETSChecker::GlobalVoidType() const { return GetGlobalTypesHolder()->GlobalETSVoidType(); @@ -574,6 +613,22 @@ ETSObjectType *ETSChecker::GlobalBuiltinBoxType(Type *contents) } } +void ETSChecker::SetFlagsForLegalBoxedPrimitiveConversion(TypeRelation *relation, Type *source, Type *target) +{ + if ((relation->GetTypeRelationFlags() & TypeRelationFlag::OVERLOADING_CONTEXT) != 0 || + (relation->GetTypeRelationFlags() & TypeRelationFlag::ONLY_CHECK_BOXING_UNBOXING) != 0) { + return; + } + Type *sourceUnboxedType = MaybeUnboxType(source); + relation->GetNode()->AddBoxingUnboxingFlags(GetUnboxingFlag(sourceUnboxedType)); + if (target->IsETSUnionType()) { + auto *boxedPrimitive = target->AsETSUnionType()->FindUnboxableType(); + relation->GetNode()->AddBoxingUnboxingFlags(GetBoxingFlag(boxedPrimitive)); + } else { + relation->GetNode()->AddBoxingUnboxingFlags(GetBoxingFlag(target)); + } +} + GlobalArraySignatureMap &ETSChecker::GlobalArrayTypes() { return globalArraySignatures_; @@ -631,13 +686,13 @@ Type *ETSChecker::SelectGlobalIntegerTypeForNumeric(Type *type) { switch (ETSType(type)) { case checker::TypeFlag::FLOAT: { - return GlobalIntType(); + return GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); } case checker::TypeFlag::DOUBLE: { - return GlobalLongType(); + return GetGlobalTypesHolder()->GlobalLongBuiltinType(); } default: { - return type; + return MaybeBoxType(type); } } } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 7be80417df..bc4e8b0a22 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -24,6 +24,7 @@ #include "checker/types/ets/etsResizableArrayType.h" #include "checker/types/ets/types.h" #include "checker/resolveResult.h" +#include "checker/types/globalTypesHolder.h" #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/visitor/AstVisitor.h" #include "util/helpers.h" @@ -129,6 +130,15 @@ public: Type *GlobalETSBigIntType() const; Type *GlobalWildcardType() const; + Type *GlobalByteBuiltinType() const; + Type *GlobalShortBuiltinType() const; + Type *GlobalIntBuiltinType() const; + Type *GlobalLongBuiltinType() const; + Type *GlobalFloatBuiltinType() const; + Type *GlobalDoubleBuiltinType() const; + Type *GlobalCharBuiltinType() const; + Type *GlobalETSBooleanBuiltinType() const; + ETSObjectType *GlobalETSObjectType() const; ETSUnionType *GlobalETSNullishType() const; ETSUnionType *GlobalETSNullishObjectType() const; @@ -196,8 +206,7 @@ public: void ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set *extendsSet, const lexer::SourcePosition &pos); void ResolveDeclaredMembersOfObject(const Type *type); - lexer::Number ExtractNumericValue(Type const *const indexType); - std::optional GetTupleElementAccessValue(const Type *type); + std::optional GetTupleElementAccessValue(const ir::Expression *expr); bool ValidateArrayIndex(ir::Expression *expr, bool relaxed = false); bool ValidateTupleIndex(const ETSTupleType *tuple, ir::MemberExpression *expr, bool reportError = true); bool ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple, ir::MemberExpression *expr); @@ -348,6 +357,8 @@ public: checker::Type *CheckBinaryOperatorMulDivMod( std::tuple op, bool isEqualOp, std::tuple types); + + bool CheckType(const checker::Type *type, ETSChecker *checker); checker::Type *CheckBinaryOperatorForIntEnums(const checker::Type *const leftType, const checker::Type *const rightType); checker::Type *CheckBinaryBitwiseOperatorForIntEnums(const checker::Type *const leftType, @@ -379,15 +390,13 @@ public: checker::Type *rightType); checker::Type *CheckBinaryOperatorNullishCoalescing(ir::Expression *left, ir::Expression *right, lexer::SourcePosition pos); + bool CheckIfNumeric(Type *type); bool AdjustNumberLiteralType(ir::NumberLiteral *literal, Type *literalType, Type *otherType); Type *HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); - Type *HandleBitwiseOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); + void SetUnboxingFlagsForBinaryExpression(std::tuple types, + std::tuple nodes, bool isBoxed); void FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression); - template - Type *PerformArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); - - Type *HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); template Type *PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); @@ -475,6 +484,7 @@ public: Signature *ResolvePotentialTrailingLambdaWithReceiver(ir::CallExpression *callExpr, ArenaVector const &signatures, ArenaVector &arguments); + Signature *MakeSignatureInvocable(Signature *sig, ir::CallExpression *callExpr); Signature *ResolveCallExpressionAndTrailingLambda(ArenaVector &signatures, ir::CallExpression *callExpr, const lexer::SourcePosition &pos, TypeRelationFlag reportFlag = TypeRelationFlag::NONE); @@ -495,8 +505,8 @@ public: Signature *CheckEveryAbstractSignatureIsOverridden(ETSFunctionType *target, ETSFunctionType *source); static Signature *GetSignatureFromMethodDefinition(const ir::MethodDefinition *methodDef); bool CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload, - const ir::MethodDefinition *currentFunc, bool omitSameAsm = false); - static bool CmpAssemblerTypesWithRank(Signature const *const sig1, Signature const *const sig2) noexcept; + const ir::MethodDefinition *currentFunc, bool omitSameAsm = false, + TypeRelationFlag relationFlags = TypeRelationFlag::NO_RETURN_TYPE_CHECK); static bool HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept; static bool HasSameAssemblySignatures(ETSFunctionType const *const func1, ETSFunctionType const *const func2) noexcept; @@ -587,6 +597,7 @@ public: checker::Type *unboxedR); Type *ApplyUnaryOperatorPromotion(Type *type, bool createConst = true, bool doPromotion = true, bool isCondExpr = false); + Type *GetUnaryOperatorPromotedType(Type *type, const bool doPromotion = true, const bool isCondExpr = false); Type *HandleBooleanLogicalOperators(Type *leftType, Type *rightType, lexer::TokenType tokenType); bool HandleLogicalPotentialResult(ir::Expression *left, ir::Expression *right, ir::BinaryExpression *expr, @@ -628,6 +639,7 @@ public: void AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxingUnboxingType); ir::BoxingUnboxingFlags GetBoxingFlag(Type *boxingType); ir::BoxingUnboxingFlags GetUnboxingFlag(Type const *unboxingType) const; + void SetFlagsForLegalBoxedPrimitiveConversion(TypeRelation *relation, Type *source, Type *target); Type *MaybeBoxExpression(ir::Expression *expr); Type *MaybeUnboxExpression(ir::Expression *expr); Type *MaybeBoxType(Type *type) const; @@ -639,7 +651,6 @@ public: bool CompareIdentifiersValuesAreDifferent(ir::Expression *compareValue, const std::string &caseValue); void CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expression *compareCase, const lexer::SourcePosition &pos); - std::string GetStringFromLiteral(ir::Expression *caseTest) const; varbinder::Variable *FindVariableInFunctionScope(util::StringView name); std::pair FindVariableInClassOrEnclosing( util::StringView name, const ETSObjectType *classType); @@ -755,7 +766,8 @@ public: static NamedAccessMeta FormNamedAccessMetadata(varbinder::Variable const *prop); // Smart cast support - [[nodiscard]] checker::Type *ResolveSmartType(checker::Type *sourceType, checker::Type *targetType); + [[nodiscard]] checker::Type *ResolveSmartType(checker::Type *sourceType, checker::Type *targetType, + bool narrowingAllowed); [[nodiscard]] std::pair CheckTestNullishCondition(Type *testedType, Type *actualType, bool strict); [[nodiscard]] std::pair CheckTestObjectCondition(ETSObjectType *testedType, Type *actualType, bool strict); @@ -866,6 +878,11 @@ public: return overloadSigContainer_; } + void ClearApparentTypes() noexcept + { + apparentTypes_.clear(); + } + void CleanUp() override { Checker::CleanUp(); @@ -968,15 +985,6 @@ private: bool ComputeSuperType(ETSObjectType *type); - template - UType HandleModulo(UType leftValue, UType rightValue); - - template - Type *HandleBitWiseArithmetic(Type *leftValue, Type *rightValue, lexer::TokenType operationType); - - template - typename TargetType::UType GetOperand(Type *type); - template ETSObjectType *AsETSObjectType(Type *(GlobalTypesHolder::*typeFunctor)(Args...), Args... args) const; Signature *GetMostSpecificSignature(ArenaVector &compatibleSignatures, diff --git a/ets2panda/checker/ets/aliveAnalyzer.cpp b/ets2panda/checker/ets/aliveAnalyzer.cpp index 7c9a9142ba..59cf64d557 100644 --- a/ets2panda/checker/ets/aliveAnalyzer.cpp +++ b/ets2panda/checker/ets/aliveAnalyzer.cpp @@ -44,6 +44,7 @@ #include "ir/ets/etsNewClassInstanceExpression.h" #include "ir/ets/etsStructDeclaration.h" #include "ir/ts/tsInterfaceDeclaration.h" +#include "checker/ETSAnalyzerHelpers.h" #include "checker/types/globalTypesHolder.h" #include "varbinder/variable.h" #include "varbinder/declaration.h" @@ -282,7 +283,7 @@ void AliveAnalyzer::AnalyzeDoLoop(const ir::DoWhileStatement *doWhile) status_ = Or(status_, ResolveContinues(doWhile)); AnalyzeNode(doWhile->Test()); ES2PANDA_ASSERT(doWhile->Test()->TsType() && doWhile->Test()->TsType()->IsConditionalExprType()); - const auto exprRes = doWhile->Test()->TsType()->ResolveConditionExpr(); + const auto exprRes = IsConstantTestValue(doWhile->Test()); status_ = And(status_, static_cast(!std::get<0>(exprRes) || !std::get<1>(exprRes))); status_ = Or(status_, ResolveBreaks(doWhile)); } @@ -292,7 +293,7 @@ void AliveAnalyzer::AnalyzeWhileLoop(const ir::WhileStatement *whileStmt) SetOldPendingExits(PendingExits()); AnalyzeNode(whileStmt->Test()); ES2PANDA_ASSERT(whileStmt->Test()->TsType() && whileStmt->Test()->TsType()->IsConditionalExprType()); - const auto exprRes = whileStmt->Test()->TsType()->ResolveConditionExpr(); + const auto exprRes = IsConstantTestValue(whileStmt->Test()); status_ = And(status_, static_cast(!std::get<0>(exprRes) || std::get<1>(exprRes))); AnalyzeStat(whileStmt->Body()); status_ = Or(status_, ResolveContinues(whileStmt)); @@ -311,7 +312,7 @@ void AliveAnalyzer::AnalyzeForLoop(const ir::ForUpdateStatement *forStmt) AnalyzeNode(forStmt->Test()); ES2PANDA_ASSERT(forStmt->Test()->TsType() && forStmt->Test()->TsType()->IsConditionalExprType()); condType = forStmt->Test()->TsType(); - std::tie(resolveType, res) = forStmt->Test()->TsType()->ResolveConditionExpr(); + std::tie(resolveType, res) = IsConstantTestValue(forStmt->Test()); status_ = From(!resolveType || res); } else { status_ = LivenessStatus::ALIVE; diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index b0b3e32efd..5b4759a23d 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -16,7 +16,9 @@ #include "arithmetic.h" #include "checker/types/ts/nullType.h" +#include "checker/types/globalTypesHolder.h" #include "lexer/token/token.h" +#include "checker/types/ets/etsEnumType.h" namespace ark::es2panda::checker { @@ -48,20 +50,6 @@ static void LogOperatorCannotBeApplied(ETSChecker *checker, BinaryArithmOperands LogOperatorCannotBeApplied(checker, ops.expr->OperatorType(), ops.typeL, ops.typeR, ops.expr->Start()); } -static inline void UnboxOperands(ETSChecker *checker, BinaryArithmOperands const &ops) -{ - auto const unbox = [checker](ir::Expression *expr, Type *type, Type *reducedType) { - if (type != reducedType) { - expr->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(reducedType)); - } - if (reducedType->IsETSEnumType()) { - expr->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - } - }; - unbox(ops.expr->Left(), ops.typeL, ops.reducedL); - unbox(ops.expr->Right(), ops.typeR, ops.reducedR); -} - static inline void RepairTypeErrorsInOperands(Type **left, Type **right) { if (IsTypeError(*left)) { @@ -87,11 +75,31 @@ static inline void RepairTypeErrorWithDefault(Type **type, Type *dflt) } } -static Type *EffectiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *right) +static bool CheckOpArgsTypeEq(ETSChecker *checker, Type *left, Type *right, Type *type) +{ + return ((left != nullptr) && (right != nullptr) && checker->IsTypeIdenticalTo(left, type) && + checker->IsTypeIdenticalTo(right, type)); +} + +static bool FindOpArgsType(ETSChecker *checker, Type *left, Type *right, Type *target) +{ + return (checker->Relation()->IsSupertypeOf(target, left) || checker->Relation()->IsSupertypeOf(target, right)); +} + +bool ETSChecker::CheckIfNumeric(Type *type) { - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); + if (type == nullptr) { + return false; + } + if (type->IsETSPrimitiveType()) { + return type->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); + } + auto *unboxed = MaybeUnboxInRelation(type); + return (unboxed != nullptr) && unboxed->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); +} +static Type *EffectivePrimitiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *right) +{ if (left->IsDoubleType() || right->IsDoubleType()) { return checker->GlobalDoubleType(); } @@ -101,7 +109,10 @@ static Type *EffectiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *rig if (left->IsLongType() || right->IsLongType()) { return checker->GlobalLongType(); } - return checker->GlobalIntType(); + if (left->IsCharType() && right->IsCharType()) { + return checker->GlobalCharType(); + } + return checker->GlobalIntType(); // return int in case of primitive types by default } static Type *TryConvertToPrimitiveType(ETSChecker *checker, Type *type) @@ -110,35 +121,70 @@ static Type *TryConvertToPrimitiveType(ETSChecker *checker, Type *type) return nullptr; } - if (type->IsETSIntEnumType()) { - return checker->GlobalIntType(); - } if (type->IsETSStringEnumType()) { return checker->GlobalETSStringLiteralType(); } return checker->MaybeUnboxInRelation(type); } -static std::pair BinaryCoerceToPrimitives(ETSChecker *checker, Type *left, Type *right, - bool const promote) +static Type *EffectiveTypeOfNumericOp(ETSChecker *checker, Type *left, Type *right) +{ + ES2PANDA_ASSERT(checker->CheckIfNumeric(left) && checker->CheckIfNumeric(right)); + + auto bothBoxed = left->IsETSUnboxableObject() && right->IsETSUnboxableObject(); + if (!bothBoxed) { + return EffectivePrimitiveTypeOfNumericOp(checker, left, right); + } + + auto globalTypesHolder = checker->GetGlobalTypesHolder(); + if (FindOpArgsType(checker, left, right, globalTypesHolder->GlobalDoubleBuiltinType())) { + return globalTypesHolder->GlobalDoubleBuiltinType(); + } + if (FindOpArgsType(checker, left, right, globalTypesHolder->GlobalFloatBuiltinType())) { + return globalTypesHolder->GlobalFloatBuiltinType(); + } + if (FindOpArgsType(checker, left, right, globalTypesHolder->GlobalLongBuiltinType())) { + return globalTypesHolder->GlobalLongBuiltinType(); + } + return globalTypesHolder->GlobalIntegerBuiltinType(); // return Int for Byte, Short, Int +} + +static Type *BinaryGetPromotedType(ETSChecker *checker, Type *left, Type *right, bool const promote) { Type *const unboxedL = TryConvertToPrimitiveType(checker, left); Type *const unboxedR = TryConvertToPrimitiveType(checker, right); if (unboxedL == nullptr || unboxedR == nullptr) { - return {nullptr, false}; + return nullptr; } - bool const bothConst = unboxedL->IsConstantType() && unboxedR->IsConstantType(); + Type *typeL = left; + Type *typeR = right; + + bool const bothBoxed = !typeL->IsETSPrimitiveType() && !typeR->IsETSPrimitiveType(); if (!promote) { - return {unboxedR, bothConst}; + return typeR; } - if (unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - return {EffectiveTypeOfNumericOp(checker, unboxedL, unboxedR), bothConst}; + if (!bothBoxed) { + if (unboxedL->IsETSEnumType() || unboxedR->IsETSEnumType()) { + return nullptr; + } + if (!typeL->IsETSPrimitiveType()) { + typeL = checker->MaybeUnboxType(typeL); + } + if (!typeR->IsETSPrimitiveType()) { + typeR = checker->MaybeUnboxType(typeR); + } + } + + if (checker->CheckIfNumeric(typeL) && checker->CheckIfNumeric(typeR)) { + return EffectiveTypeOfNumericOp(checker, typeL, typeR); + } + if (checker->CheckIfNumeric(typeR)) { + return typeR; } - return {unboxedR, bothConst}; + return typeL; } Type *ETSChecker::NegateNumericType(Type *type, ir::Expression *node) @@ -186,26 +232,6 @@ Type *ETSChecker::NegateNumericType(Type *type, ir::Expression *node) return result; } -Type *ETSChecker::HandleRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); - - if (left->IsDoubleType() || right->IsDoubleType()) { - return PerformRelationOperationOnTypes(left, right, operationType); - } - - if (left->IsFloatType() || right->IsFloatType()) { - return PerformRelationOperationOnTypes(left, right, operationType); - } - - if (left->IsLongType() || right->IsLongType()) { - return PerformRelationOperationOnTypes(left, right, operationType); - } - - return PerformRelationOperationOnTypes(left, right, operationType); -} - bool ETSChecker::CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::TokenType op) { if ((left == nullptr) || (right == nullptr)) { @@ -250,6 +276,20 @@ bool ETSChecker::CheckBinaryPlusMultDivOperandsForUnionType(const Type *leftType return true; } +void ETSChecker::SetUnboxingFlagsForBinaryExpression(std::tuple types, + std::tuple nodes, bool isBoxed) +{ + auto [leftType, rightType, unboxedL, unboxedR] = types; + auto [left, right] = nodes; + if (isBoxed) { + FlagExpressionWithUnboxing(leftType, nullptr, left); + FlagExpressionWithUnboxing(rightType, nullptr, right); + } else { + FlagExpressionWithUnboxing(leftType, unboxedL, left); + FlagExpressionWithUnboxing(rightType, unboxedR, right); + } +} + checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( std::tuple op, bool isEqualOp, std::tuple types) @@ -264,17 +304,12 @@ checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( return GlobalTypeError(); } - checker::Type *tsType {}; - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); if (!CheckBinaryPlusMultDivOperandsForUnionType(leftType, rightType, left, right)) { return GlobalTypeError(); } - if (promotedType == nullptr || !unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - !unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (promotedType == nullptr || !CheckIfNumeric(leftType) || !CheckIfNumeric(rightType)) { auto type = CheckBinaryOperatorForIntEnums(leftType, rightType); if (type != nullptr) { return type; @@ -283,31 +318,32 @@ checker::Type *ETSChecker::CheckBinaryOperatorMulDivMod( return GlobalTypeError(); } - if (bothConst) { - tsType = HandleArithmeticOperationOnTypes(leftType, rightType, operationType); - } + return promotedType; +} - return (tsType != nullptr) ? tsType : promotedType; +bool ETSChecker::CheckType(const checker::Type *type, [[maybe_unused]] ETSChecker *checker) +{ + return type->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || + Relation()->IsSupertypeOf(GetGlobalTypesHolder()->GlobalNumericBuiltinType(), type); } checker::Type *ETSChecker::CheckBinaryOperatorForIntEnums(const checker::Type *const leftType, const checker::Type *const rightType) { - if (leftType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - rightType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (CheckType(leftType, this) && CheckType(rightType, this)) { if (leftType->IsETSIntEnumType() && rightType->IsETSIntEnumType()) { - return GlobalIntType(); + return GlobalIntBuiltinType(); } if (leftType->IsFloatType() || rightType->IsFloatType()) { - return GlobalFloatType(); + return GlobalFloatBuiltinType(); } if (leftType->IsDoubleType() || rightType->IsDoubleType()) { - return GlobalDoubleType(); + return GlobalDoubleBuiltinType(); } if (leftType->IsLongType() || rightType->IsLongType()) { - return GlobalLongType(); + return GlobalLongBuiltinType(); } - return GlobalIntType(); + return GlobalIntBuiltinType(); } return nullptr; } @@ -315,21 +351,20 @@ checker::Type *ETSChecker::CheckBinaryOperatorForIntEnums(const checker::Type *c checker::Type *ETSChecker::CheckBinaryBitwiseOperatorForIntEnums(const checker::Type *const leftType, const checker::Type *const rightType) { - if (leftType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - rightType->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (CheckType(leftType, this) && CheckType(rightType, this)) { if (leftType->IsETSIntEnumType() && rightType->IsETSIntEnumType()) { - return GlobalIntType(); + return GlobalIntBuiltinType(); } if (leftType->IsFloatType() || rightType->IsFloatType()) { - return GlobalIntType(); + return GlobalIntBuiltinType(); } if (leftType->IsDoubleType() || rightType->IsDoubleType()) { - return GlobalLongType(); + return GlobalLongBuiltinType(); } if (leftType->IsLongType() || rightType->IsLongType()) { - return GlobalLongType(); + return GlobalLongBuiltinType(); } - return GlobalIntType(); + return GlobalIntBuiltinType(); } return nullptr; } @@ -337,6 +372,10 @@ checker::Type *ETSChecker::CheckBinaryBitwiseOperatorForIntEnums(const checker:: checker::Type *ETSChecker::CheckBinaryOperatorPlusForEnums(const checker::Type *const leftType, const checker::Type *const rightType) { + if (!leftType->IsETSEnumType() || !rightType->IsETSEnumType()) { + return nullptr; + } + if (auto numericType = CheckBinaryOperatorForIntEnums(leftType, rightType); numericType != nullptr) { return numericType; } @@ -374,29 +413,20 @@ checker::Type *ETSChecker::CheckBinaryOperatorPlus( if (!CheckBinaryPlusMultDivOperandsForUnionType(leftType, rightType, left, right)) { return GlobalTypeError(); } + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - - if (promotedType == nullptr || !unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - !unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (promotedType == nullptr || !CheckIfNumeric(rightType) || !CheckIfNumeric(leftType)) { auto type = CheckBinaryOperatorPlusForEnums(leftType, rightType); if (type != nullptr) { return type; } LogError(diagnostic::BINOP_NONARITHMETIC_TYPE, {}, pos); - return GlobalTypeError(); - } - - if (bothConst) { - return HandleArithmeticOperationOnTypes(leftType, rightType, operationType); } return promotedType; } -static checker::Type *GetBitwiseCompatibleType(ETSChecker *checker, Type *const type) +[[maybe_unused]] static checker::Type *GetBitwiseCompatibleType(ETSChecker *checker, Type *const type) { switch (checker->ETSType(type)) { case TypeFlag::BYTE: { @@ -430,8 +460,8 @@ checker::Type *ETSChecker::CheckBinaryOperatorShift( auto [left, right, operationType, pos] = op; auto [leftType, rightType, unboxedL, unboxedR] = types; - RepairTypeErrorWithDefault(&leftType, GlobalIntType()); - RepairTypeErrorWithDefault(&rightType, GlobalIntType()); + RepairTypeErrorWithDefault(&leftType, GlobalIntBuiltinType()); + RepairTypeErrorWithDefault(&rightType, GlobalIntBuiltinType()); RepairTypeErrorWithDefault(&unboxedL, GlobalIntType()); RepairTypeErrorWithDefault(&unboxedR, GlobalIntType()); @@ -440,15 +470,10 @@ checker::Type *ETSChecker::CheckBinaryOperatorShift( return GlobalTypeError(); } - auto promotedLeftType = ApplyUnaryOperatorPromotion(unboxedL, false, !isEqualOp); - auto promotedRightType = ApplyUnaryOperatorPromotion(unboxedR, false, !isEqualOp); - - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - - if (promotedLeftType == nullptr || !promotedLeftType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - promotedRightType == nullptr || - !promotedRightType->HasTypeFlag(checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + auto promotedLeftType = GetUnaryOperatorPromotedType(leftType, !isEqualOp); + auto promotedRightType = GetUnaryOperatorPromotedType(rightType, !isEqualOp); + if (promotedLeftType == nullptr || promotedRightType == nullptr || !CheckIfNumeric(promotedLeftType) || + !CheckIfNumeric(promotedRightType)) { auto type = CheckBinaryBitwiseOperatorForIntEnums(leftType, rightType); if (type != nullptr) { return type; @@ -457,10 +482,22 @@ checker::Type *ETSChecker::CheckBinaryOperatorShift( return GlobalTypeError(); } - if (promotedLeftType->HasTypeFlag(TypeFlag::CONSTANT) && promotedRightType->HasTypeFlag(TypeFlag::CONSTANT)) { - return HandleBitwiseOperationOnTypes(promotedLeftType, promotedRightType, operationType); + auto isPrim = promotedLeftType->IsETSPrimitiveType(); + auto unboxedProm = MaybeUnboxType(promotedLeftType); + if (unboxedProm->IsFloatType() || unboxedProm->IsIntType()) { + return isPrim ? GlobalIntType() : GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); } - return GetBitwiseCompatibleType(this, promotedLeftType); + + if (unboxedProm->IsLongType() || unboxedProm->IsDoubleType()) { + return isPrim ? GlobalLongType() : GetGlobalTypesHolder()->GlobalLongBuiltinType(); + } + + if (unboxedProm->IsByteType() || unboxedProm->IsShortType() || unboxedProm->IsCharType()) { + return promotedLeftType; + } + + ES2PANDA_UNREACHABLE(); + return nullptr; } checker::Type *ETSChecker::CheckBinaryOperatorBitwise( @@ -481,19 +518,12 @@ checker::Type *ETSChecker::CheckBinaryOperatorBitwise( return GlobalTypeError(); } - if (unboxedL != nullptr && unboxedL->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN) && unboxedR != nullptr && - unboxedR->HasTypeFlag(checker::TypeFlag::ETS_BOOLEAN)) { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - return HandleBooleanLogicalOperators(unboxedL, unboxedR, operationType); + if (CheckOpArgsTypeEq(this, unboxedL, unboxedR, GlobalETSBooleanType())) { + return GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); } - auto const [promotedType, bothConst] = BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - - if (promotedType == nullptr || !unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) || - !unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); + if (promotedType == nullptr || !CheckIfNumeric(rightType) || !CheckIfNumeric(leftType)) { auto type = CheckBinaryBitwiseOperatorForIntEnums(leftType, rightType); if (type != nullptr) { return type; @@ -501,12 +531,22 @@ checker::Type *ETSChecker::CheckBinaryOperatorBitwise( LogError(diagnostic::OP_NONNUMERIC, {}, pos); return GlobalTypeError(); } + SetUnboxingFlagsForBinaryExpression(types, {left, right}, promotedType->IsETSUnboxableObject()); + + auto isPrim = promotedType->IsETSPrimitiveType(); + auto unboxedProm = MaybeUnboxType(promotedType); + if (unboxedProm->IsFloatType() || unboxedProm->IsIntType()) { + return isPrim ? GlobalIntType() : GetGlobalTypesHolder()->GlobalIntegerBuiltinType(); + } - if (bothConst) { - return HandleBitwiseOperationOnTypes(leftType, rightType, operationType); + if (unboxedProm->IsLongType() || unboxedProm->IsDoubleType()) { + return isPrim ? GlobalLongType() : GetGlobalTypesHolder()->GlobalLongBuiltinType(); } - return SelectGlobalIntegerTypeForNumeric(promotedType); + if (unboxedProm->IsByteType() || unboxedProm->IsShortType() || unboxedProm->IsCharType()) { + return promotedType; + } + return nullptr; } checker::Type *ETSChecker::CheckBinaryOperatorLogical(ir::Expression *left, ir::Expression *right, @@ -540,25 +580,39 @@ checker::Type *ETSChecker::CheckBinaryOperatorLogical(ir::Expression *left, ir:: return GetNonConstantType(leftType); } - if (IsTypeIdenticalTo(unboxedL, unboxedR)) { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - return GetNonConstantType(unboxedL); - } - if (unboxedL != nullptr && unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && unboxedR != nullptr && unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); - return EffectiveTypeOfNumericOp(this, unboxedL, unboxedR); + SetUnboxingFlagsForBinaryExpression({leftType, rightType, unboxedL, unboxedR}, {left, right}, + (leftType->IsETSUnboxableObject() || rightType->IsETSUnboxableObject())); + return EffectiveTypeOfNumericOp(this, leftType, rightType); } return CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)}); } +static bool ContainsNumbers(ETSChecker *checker, Type *tp) +{ + auto isSubtypeOfNumeric = [checker](Type *tp2) { + return checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), tp2); + }; + if (isSubtypeOfNumeric(tp)) { + return true; + } + if (tp->IsETSUnionType()) { + for (auto *constituent : tp->AsETSUnionType()->ConstituentTypes()) { + if (isSubtypeOfNumeric(constituent)) { + return true; + } + } + } + + return false; +} + +// CC-OFFNXT(huge_cyclomatic_complexity) solid logic bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, checker::Type *const rightType) { - auto isGlobalObjectType {[](checker::Type *const type) -> bool { + auto isGlobalObjectType {[&](checker::Type *const type) -> bool { return type->IsETSObjectType() && type->AsETSObjectType()->IsGlobalETSObjectType(); }}; @@ -568,6 +622,18 @@ bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, che return true; } + // Any two types that can be numeric are comparable + if (ContainsNumbers(this, leftType) && ContainsNumbers(this, rightType)) { + return true; + } + + // Boolean and any type that can be numeric or char are not comparable + if ((FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalNumericBuiltinType()) || + FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalCharBuiltinType())) && + FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType())) { + return false; + } + // NOTE (mxlgv): Skip for unions. Required implementation of the specification section: // 7.25.6 Reference Equality Based on Actual Type (Union Equality Operators) if (leftType->IsETSUnionType()) { @@ -594,6 +660,11 @@ bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, che } } + if (FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalIntegerBuiltinType()) && + (leftType->IsETSEnumType() || rightType->IsETSEnumType())) { + return true; + } + // 7.24.5 Enumeration Relational Operators return leftType->IsETSEnumType() == rightType->IsETSEnumType(); } @@ -666,10 +737,11 @@ static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOper } if (typeL->IsETSEnumType() && typeR->IsETSEnumType()) { - if (checker->Relation()->IsIdenticalTo(typeL, typeR)) { - return typeL; + if (!checker->Relation()->IsIdenticalTo(typeL, typeR)) { + checker->LogError(diagnostic::BINOP_INCOMPARABLE, {}, expr->Start()); + return checker->GlobalTypeError(); } - return nullptr; + return typeL; } if (typeL->IsETSReferenceType() && typeR->IsETSReferenceType()) { @@ -709,12 +781,13 @@ static Type *CheckBinaryOperatorEqual(ETSChecker *checker, BinaryArithmOperands if (reducedL->IsETSBooleanType() && reducedR->IsETSBooleanType()) { if (reducedL->IsConstantType() && reducedR->IsConstantType()) { - bool res = reducedL->AsETSBooleanType()->GetValue() == reducedR->AsETSBooleanType()->GetValue(); - res = ((expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EQUAL) == res); - return checker->CreateETSBooleanType(res); + return checker->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(); + } + if (checker->CheckIfNumeric(typeL) && checker->CheckIfNumeric(typeR) && typeL->IsETSUnboxableObject() && + typeR->IsETSUnboxableObject()) { + return typeL; } - UnboxOperands(checker, ops); - return checker->GlobalETSBooleanType(); + return reducedL; } return HandelReferenceBinaryEquality(checker, ops); @@ -763,15 +836,14 @@ std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expres return {GlobalETSBooleanType(), leftType}; } - auto *const promotedType = std::get<0>(BinaryCoerceToPrimitives(this, unboxedL, unboxedR, !isEqualOp)); - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); + auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); if (leftType->IsETSUnionType() || rightType->IsETSUnionType()) { return {GlobalETSBooleanType(), CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)})}; } - if (promotedType != nullptr && (unboxedL->IsETSBooleanType() != unboxedR->IsETSBooleanType())) { + if (promotedType != nullptr && unboxedL != nullptr && unboxedR != nullptr && + unboxedL->IsETSBooleanType() != unboxedR->IsETSBooleanType()) { LogOperatorCannotBeApplied(this, operationType, leftType, rightType, pos); return {GlobalETSBooleanType(), leftType}; } @@ -783,7 +855,7 @@ std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expres return {GlobalETSBooleanType(), GlobalETSBooleanType()}; } - return {GlobalETSBooleanType(), promotedType}; + return {GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(), promotedType}; } std::tuple ETSChecker::CheckBinaryOperatorInstanceOf(lexer::SourcePosition pos, checker::Type *leftType, @@ -903,6 +975,7 @@ struct TypeParams { Type *unboxedR; }; +// CC-OFFNXT(G.FUN.01, huge_method) solid logic static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, const BinaryOperatorParams &binaryParams, const TypeParams &typeParams) @@ -927,8 +1000,8 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - if (Type *res = CheckBinaryOperatorEqual(checker, opsRepaired); res != nullptr) { - return {checker->GlobalETSBooleanType(), res}; + if (auto res = CheckBinaryOperatorEqual(checker, opsRepaired); res != nullptr) { + return {checker->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(), res}; } [[fallthrough]]; } @@ -957,6 +1030,21 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, } namespace { + +bool IsEnum(const ir::Expression *expr) +{ + if (expr == nullptr) { + return false; + } + + auto type = expr->TsType(); + if (type == nullptr) { + return false; + } + + return type->IsETSEnumType(); +} + bool IsStringEnum(const ir::Expression *expr) { if (expr == nullptr) { @@ -1026,26 +1114,35 @@ void CheckStringOperatorContext(ir::Expression *expression, checker::Type *other } } -bool CheckRelationalOperatorsBetweenEnums(ir::Expression *left, ir::Expression *right, lexer::TokenType op) +bool CheckRelationalOperatorsBetweenEnums(ETSChecker *checker, ir::BinaryExpression *expr) { + auto left = expr->Left(); + auto right = expr->Right(); + auto op = expr->OperatorType(); + + if (!IsEnum(left) || !IsEnum(right)) { + return false; + } + + if (!checker->Relation()->IsIdenticalTo(left->TsType(), right->TsType())) { + checker->LogError(diagnostic::BINOP_INCOMPARABLE, {}, expr->Start()); + return false; + } + const bool isRelational = op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - if (((IsStringEnum(left) && IsStringEnum(right)) || - (IsIntEnum(left) && IsIntEnum(right)))) { // NOTE(psiket) In case of int enums it has been already checked in - // the CheckNumericOperatorContext function - if (isRelational || isEquality) { - left->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - right->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - return true; - } + if (isRelational || isEquality) { + left->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + right->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + return true; } return false; } -void CheckNeedToGenerateGetValueForBinaryExpression(ir::Expression *expression) +void CheckNeedToGenerateGetValueForBinaryExpression(ir::Expression *expression, ETSChecker *checker) { if (!expression->IsBinaryExpression()) { return; @@ -1068,7 +1165,7 @@ void CheckNeedToGenerateGetValueForBinaryExpression(ir::Expression *expression) CheckStringOperatorContext(rightExp, leftExp->TsType(), op); // Relational operators if both are enumeration Types - if (CheckRelationalOperatorsBetweenEnums(leftExp, rightExp, op)) { + if (CheckRelationalOperatorsBetweenEnums(checker, expression->AsBinaryExpression())) { return; } } @@ -1094,6 +1191,13 @@ std::tuple ETSChecker::CheckArithmeticOperations( auto check = checkMap[operationType]; auto tsType = check(this, std::make_tuple(left, right, operationType, pos), isEqualOp, std::make_tuple(leftType, rightType, unboxedL, unboxedR)); + if (tsType == nullptr) { + return {leftType, rightType}; + } + if (tsType->IsETSPrimitiveType()) { + tsType = MaybeBoxType(tsType); + expr->AddBoxingUnboxingFlags(GetBoxingFlag(tsType)); + } return {tsType, tsType}; } @@ -1146,7 +1250,7 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, return {leftType, leftType}; } - CheckNeedToGenerateGetValueForBinaryExpression(expr); + CheckNeedToGenerateGetValueForBinaryExpression(expr, this); const bool isLogicalExtendedOperator = (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) || (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR); @@ -1167,46 +1271,6 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, std::make_tuple(leftType, rightType, unboxedL, unboxedR)); } -Type *ETSChecker::HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); - - if (left->IsDoubleType() || right->IsDoubleType()) { - return PerformArithmeticOperationOnTypes(left, right, operationType); - } - - if (left->IsFloatType() || right->IsFloatType()) { - return PerformArithmeticOperationOnTypes(left, right, operationType); - } - - if (left->IsLongType() || right->IsLongType()) { - return PerformArithmeticOperationOnTypes(left, right, operationType); - } - - return PerformArithmeticOperationOnTypes(left, right, operationType); -} - -Type *ETSChecker::HandleBitwiseOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - ES2PANDA_ASSERT(left->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && - right->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); - - if (left->IsDoubleType() || right->IsDoubleType()) { - return HandleBitWiseArithmetic(left, right, operationType); - } - - if (left->IsFloatType() || right->IsFloatType()) { - return HandleBitWiseArithmetic(left, right, operationType); - } - - if (left->IsLongType() || right->IsLongType()) { - return HandleBitWiseArithmetic(left, right, operationType); - } - - return HandleBitWiseArithmetic(left, right, operationType); -} - void ETSChecker::FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression) { if (type->IsETSEnumType()) { diff --git a/ets2panda/checker/ets/arithmetic.h b/ets2panda/checker/ets/arithmetic.h index 9e08b1e46e..6ca03978bb 100644 --- a/ets2panda/checker/ets/arithmetic.h +++ b/ets2panda/checker/ets/arithmetic.h @@ -18,167 +18,9 @@ #include "checker/ETSchecker.h" #include "checker/ETSAnalyzer.h" +#include "checker/types/globalTypesHolder.h" namespace ark::es2panda::checker { - -template -typename TargetType::UType ETSChecker::GetOperand(Type *type) -{ - switch (ETSType(type)) { - case TypeFlag::BYTE: { - return type->AsByteType()->GetValue(); - } - case TypeFlag::CHAR: { - return type->AsCharType()->GetValue(); - } - case TypeFlag::SHORT: { - return type->AsShortType()->GetValue(); - } - case TypeFlag::INT: { - return type->AsIntType()->GetValue(); - } - case TypeFlag::LONG: { - return type->AsLongType()->GetValue(); - } - case TypeFlag::FLOAT: { - return type->AsFloatType()->GetValue(); - } - case TypeFlag::DOUBLE: { - return type->AsDoubleType()->GetValue(); - } - case TypeFlag::ETS_BOOLEAN: { - return type->AsETSBooleanType()->GetValue(); - } - default: { - ES2PANDA_UNREACHABLE(); - } - } -} - -template -Type *ETSChecker::PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - using UType = typename TargetType::UType; - - UType leftValue = GetOperand(left); - UType rightValue = GetOperand(right); - - bool result {}; - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_LESS_THAN: { - result = leftValue < rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: { - result = leftValue <= rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { - result = leftValue > rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: { - result = leftValue >= rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: - case lexer::TokenType::PUNCTUATOR_EQUAL: { - result = leftValue == rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: - case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - result = leftValue != rightValue; - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - return CreateETSBooleanType(result); -} - -template -Type *ETSChecker::PerformArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType) -{ - using UType = typename TargetType::UType; - - UType leftValue = GetOperand(left); - UType rightValue = GetOperand(right); - auto result = leftValue; - auto isForbiddenZeroDivision = [&rightValue]() { return std::is_integral::value && rightValue == 0; }; - - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_PLUS: - case lexer::TokenType::PUNCTUATOR_PLUS_EQUAL: { - result = leftValue + rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_MINUS: - case lexer::TokenType::PUNCTUATOR_MINUS_EQUAL: { - result = leftValue - rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_DIVIDE: - case lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL: { - if (isForbiddenZeroDivision()) { - return nullptr; - } - result = leftValue / rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_MULTIPLY: - case lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL: { - result = leftValue * rightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_MOD: - case lexer::TokenType::PUNCTUATOR_MOD_EQUAL: { - if (isForbiddenZeroDivision()) { - return nullptr; - } - result = HandleModulo(leftValue, rightValue); - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - return Allocator()->New(result); -} - -template <> -inline IntType::UType ark::es2panda::checker::ETSChecker::HandleModulo(IntType::UType leftValue, - IntType::UType rightValue) -{ - ES2PANDA_ASSERT(rightValue != 0); - return leftValue % rightValue; -} - -template <> -inline LongType::UType ark::es2panda::checker::ETSChecker::HandleModulo(LongType::UType leftValue, - LongType::UType rightValue) -{ - ES2PANDA_ASSERT(rightValue != 0); - return leftValue % rightValue; -} - -template <> -inline FloatType::UType ark::es2panda::checker::ETSChecker::HandleModulo(FloatType::UType leftValue, - FloatType::UType rightValue) -{ - return std::fmod(leftValue, rightValue); -} - -template <> -inline DoubleType::UType ark::es2panda::checker::ETSChecker::HandleModulo( - DoubleType::UType leftValue, DoubleType::UType rightValue) -{ - return std::fmod(leftValue, rightValue); -} - template inline IntegerUType CastIfFloat(FloatOrIntegerUType num) { @@ -188,61 +30,6 @@ inline IntegerUType CastIfFloat(FloatOrIntegerUType num) return num; } } - -template -Type *ETSChecker::HandleBitWiseArithmetic(Type *left, Type *right, lexer::TokenType operationType) -{ - using IntegerUType = typename IntegerType::UType; - using UnsignedUType = std::make_unsigned_t; - - UnsignedUType result = 0; - UnsignedUType unsignedLeftValue = CastIfFloat(GetOperand(left)); - UnsignedUType unsignedRightValue = CastIfFloat(GetOperand(right)); - - auto mask = std::numeric_limits::digits - 1U; - auto shift = unsignedRightValue & mask; - - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: - case lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL: { - result = unsignedLeftValue & unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: - case lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL: { - result = unsignedLeftValue | unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL: { - result = unsignedLeftValue ^ unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: - case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT_EQUAL: { - static_assert(sizeof(UnsignedUType) == 4 || sizeof(UnsignedUType) == 8); - result = unsignedLeftValue << shift; - break; - } - case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT_EQUAL: { - static_assert(sizeof(IntegerUType) == 4 || sizeof(IntegerUType) == 8); - result = static_cast(unsignedLeftValue) >> shift; // NOLINT(hicpp-signed-bitwise) - break; - } - case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT_EQUAL: { - static_assert(sizeof(UnsignedUType) == 4 || sizeof(UnsignedUType) == 8); - result = unsignedLeftValue >> shift; - break; - } - default: { - ES2PANDA_UNREACHABLE(); - } - } - - return Allocator()->New(result); -} } // namespace ark::es2panda::checker #endif diff --git a/ets2panda/checker/ets/assignAnalyzer.cpp b/ets2panda/checker/ets/assignAnalyzer.cpp index 21d8514aec..59cddd1ff9 100644 --- a/ets2panda/checker/ets/assignAnalyzer.cpp +++ b/ets2panda/checker/ets/assignAnalyzer.cpp @@ -1343,8 +1343,10 @@ bool AssignAnalyzer::VariableHasDefaultValue(const ir::AstNode *node) ES2PANDA_UNREACHABLE(); } + bool isPrimitive = type->IsETSPrimitiveType(); + bool isBoxedPrimitive = type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive(); return type != nullptr && - (type->IsETSPrimitiveType() || + ((isPrimitive || isBoxedPrimitive) || (type->PossiblyETSUndefined() && (!type->HasTypeFlag(checker::TypeFlag::GENERIC) || (isNonReadonlyField && !CHECK_GENERIC_NON_READONLY_PROPERTIES)))); } diff --git a/ets2panda/checker/ets/castingContext.cpp b/ets2panda/checker/ets/castingContext.cpp index 0f1c377aaa..1f8d508164 100644 --- a/ets2panda/checker/ets/castingContext.cpp +++ b/ets2panda/checker/ets/castingContext.cpp @@ -39,11 +39,8 @@ CastingContext::CastingContext(TypeRelation *relation, const diagnostic::Diagnos } } - if (isLegalBoxedPrimitiveConversion && !relation->IsTrue()) { - auto *const checker = relation->GetChecker()->AsETSChecker(); - Type *sourceUnboxedType = checker->MaybeUnboxType(data.source); - relation->GetNode()->AddBoxingUnboxingFlags(checker->GetUnboxingFlag(sourceUnboxedType)); - relation->GetNode()->AddBoxingUnboxingFlags(checker->GetBoxingFlag(data.target)); + if (isLegalBoxedPrimitiveConversion) { + relation->Result(true); } uncheckedCast_ = relation->UncheckedCast(); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index c314bd252b..8d6d6b8eac 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -16,6 +16,7 @@ #include "checker/types/ets/etsResizableArrayType.h" #include "checker/types/ets/etsTupleType.h" #include "generated/signatures.h" +#include "checker/ets/wideningConverter.h" #include "varbinder/ETSBinder.h" #include "checker/ETSchecker.h" #include "checker/ets/function_helpers.h" @@ -341,11 +342,13 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, // #22952: infer optional parameter heuristics auto const paramType = GetNonNullishType(substitutedSig->Params()[index]->TsType()); if (argument->IsObjectExpression()) { - if (paramType->IsETSObjectType()) { - // No chance to check the argument at this point - continue; + if (!paramType->IsETSObjectType()) { + return false; } - return false; + if (paramType->AsETSObjectType()->IsBoxedPrimitive()) { + return false; + } + argument->AsObjectExpression()->SetPreferredType(paramType); } if (argument->IsMemberExpression()) { @@ -392,7 +395,7 @@ bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, i // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) Type *argumentType = argument->Check(this); - flags |= TypeRelationFlag::ONLY_CHECK_WIDENING; + flags |= (TypeRelationFlag::ONLY_CHECK_WIDENING); auto const invocationCtx = checker::InvocationContext(Relation(), argument, argumentType, targetType, argument->Start(), @@ -404,12 +407,13 @@ bool ETSChecker::ValidateSignatureInvocationContext(Signature *substitutedSig, i bool ETSChecker::IsValidRestArgument(ir::Expression *const argument, Signature *const substitutedSig, const TypeRelationFlag flags, const std::size_t index) { + auto *restParam = substitutedSig->RestVar()->TsType(); if (argument->IsObjectExpression()) { + argument->AsObjectExpression()->SetPreferredType(restParam->AsETSArrayType()->ElementType()); // Object literals should be checked separately afterwards after call resolution return true; } const auto argumentType = argument->Check(this); - auto *restParam = substitutedSig->RestVar()->TsType(); if (restParam->IsETSTupleType()) { return false; } @@ -585,6 +589,7 @@ std::array GetFlagVariants() }; } +// CC-OFFNXT(huge_method) solid logic ArenaVector ETSChecker::CollectSignatures(ArenaVector &signatures, const ir::TSTypeParameterInstantiation *typeArguments, const ArenaVector &arguments, @@ -594,12 +599,20 @@ ArenaVector ETSChecker::CollectSignatures(ArenaVector std::vector argTypeInferenceRequired = FindTypeInferenceArguments(arguments); Signature *notVisibleSignature = nullptr; + if (signatures.size() > 1) { + resolveFlags |= TypeRelationFlag::OVERLOADING_CONTEXT; + } + auto collectSignatures = [&](TypeRelationFlag relationFlags) { for (auto *sig : signatures) { if (notVisibleSignature != nullptr && !IsSignatureAccessible(sig, Context().ContainingClass(), Relation())) { continue; } + if (sig->HasSignatureFlag(SignatureFlags::BRIDGE)) { + // Bridges are never invoked direcly + continue; + } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *concreteSig = ValidateSignature(std::make_tuple(sig, typeArguments, relationFlags), arguments, pos, argTypeInferenceRequired, signatures.size() == 1); @@ -757,6 +770,8 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector return true; }; + auto isGeneric = [](const Signature *sig) { return sig->TypeParams().empty(); }; + Signature *result = nullptr; size_t currentMinLength = SIZE_MAX; @@ -780,8 +795,14 @@ Signature *ETSChecker::FindMostSpecificSignature(const ArenaVector if (candidateLength < currentLength) { result = candidate; // Shorter parameter count wins currentMinLength = result->Function()->Params().size(); - } else if (candidateLength == currentLength) { - // Ambiguous resolution for same-length params + } else if (candidateLength >= currentLength) { + continue; + } else if (!isGeneric(candidate) && isGeneric(result)) { + result = candidate; + } else if (isGeneric(candidate) && !isGeneric(result)) { + continue; + } else { + // Ambiguous resolution for same-length params, same genericity if (result->Owner() == candidate->Owner()) { result = nullptr; } @@ -797,16 +818,42 @@ static Type *GetParatmeterTypeOrRestAtIdx(checker::ETSChecker *checker, Signatur : checker->GetElementTypeOfArray(sig->RestVar()->TsType()); } -static void InitMostSpecificType(checker::ETSChecker *checker, const ArenaVector &signatures, +static void InitMostSpecificType(TypeRelation *relation, const ArenaVector &signatures, [[maybe_unused]] Type *&mostSpecificType, [[maybe_unused]] Signature *&prevSig, const size_t idx) { + // different result for primitive and boxed types + // ex: func(Double); func(Int) -> call func(a where a is Byte) -> mostSpecificType will be last ETSObjectType (Int) + // ex: func(double); func(int) -> call func(a where a is byte) -> mostSpecificType will be just the first one in the + // list (double) and the second one contradicts spec!!! + // + // Attempt to choose the widest type of available ones + SavedTypeRelationFlagsContext ctx {relation, TypeRelationFlag::WIDENING | TypeRelationFlag::ONLY_CHECK_WIDENING}; + auto checker = relation->GetChecker()->AsETSChecker(); for (auto *sig : signatures) { - if (Type *sigType = GetParatmeterTypeOrRestAtIdx(checker, sig, idx); - sigType->IsETSObjectType() && !sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { + Type *sigType = GetParatmeterTypeOrRestAtIdx(checker, sig, idx); + if (sigType->IsETSObjectType()) { + if (sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { + continue; + } + if (!sigType->AsETSObjectType()->IsBoxedPrimitive()) { + // Found "non-primitive" ref type + mostSpecificType = sigType; + prevSig = sig; + return; + } + relation->SetNode(prevSig->Function()->Params()[idx]->AsETSParameterExpression()); + if (relation->IsLegalBoxedPrimitiveConversion(sigType, mostSpecificType)) { + mostSpecificType = sigType; + prevSig = sig; + continue; + } + } + WideningConverter(checker, relation, sigType, mostSpecificType); + if (relation->IsTrue()) { mostSpecificType = sigType; prevSig = sig; - return; + continue; } } } @@ -817,17 +864,34 @@ void ETSChecker::SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature { auto [pos, idx, sig] = info; Type *sigType = GetParatmeterTypeOrRestAtIdx(this, sig, idx); + if (prevSig->Function()->Params()[idx]->IsETSParameterExpression()) { + Relation()->SetNode(prevSig->Function()->Params()[idx]->AsETSParameterExpression()); + } const bool isClassType = sigType->IsETSObjectType() && !sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE); if (isClassType == lookForClassType) { if (Relation()->IsIdenticalTo(sigType, mostSpecificType)) { + Relation()->SetNode(nullptr); return; } + if (isClassType && sigType->AsETSObjectType()->IsBoxedPrimitive() && mostSpecificType->IsETSObjectType() && + mostSpecificType->AsETSObjectType()->IsBoxedPrimitive()) { + TypeRelationFlag flags = TypeRelationFlag::NO_THROW | TypeRelationFlag::UNBOXING | + TypeRelationFlag::BOXING | TypeRelationFlag::WIDENING; + Relation()->SetFlags(flags); + if (Relation()->IsLegalBoxedPrimitiveConversion(mostSpecificType, sigType)) { + Relation()->Result(true); + mostSpecificType = sigType; + prevSig = sig; + return; + } + } if (Relation()->IsAssignableTo(sigType, mostSpecificType)) { mostSpecificType = sigType; prevSig = sig; } else if (sigType->IsETSObjectType() && mostSpecificType->IsETSObjectType() && - !Relation()->IsAssignableTo(mostSpecificType, sigType)) { + !Relation()->IsAssignableTo(mostSpecificType, sigType) && + !Relation()->IsLegalBoxedPrimitiveConversion(sigType, mostSpecificType)) { auto funcName = sig->Function()->Id()->Name(); LogError(diagnostic::AMBIGUOUS_CALL, {funcName, funcName, funcName, prevSig, funcName, sig}, pos); } @@ -864,7 +928,9 @@ ArenaMultiMap ETSChecker::GetSuitableSignaturesForParameter Type *mostSpecificType = signatures.front()->Params().at(i)->TsType(); Signature *prevSig = signatures.front(); - InitMostSpecificType(this, signatures, mostSpecificType, prevSig, i); + // NOTE: first we choose the some signature with possibly widest argumetns' types + // Then we search for the most specific signature + InitMostSpecificType(Relation(), signatures, mostSpecificType, prevSig, i); for (auto *sig : signatures) { SearchAmongMostSpecificTypes(mostSpecificType, prevSig, std::make_tuple(pos, i, sig), true); } @@ -1012,6 +1078,31 @@ void ETSChecker::UpdateDeclarationFromSignature(ir::CallExpression *expr, checke callIdentifier->SetVariable(newVar); } +Signature *ETSChecker::MakeSignatureInvocable(Signature *sig, ir::CallExpression *callExpr) +{ + if (sig == nullptr) { + return nullptr; + } + std::size_t const argumentCount = callExpr->Arguments().size(); + std::size_t const parameterCount = sig->Params().size(); + auto count = std::min(parameterCount, argumentCount); + for (std::size_t idx = 0; idx < count; ++idx) { + // Kludge to make promise code compile + if (callExpr->Arguments().at(idx)->IsArrowFunctionExpression()) { + continue; + } + + auto ctx = checker::AssignmentContext( + Relation(), callExpr->Arguments().at(idx), callExpr->Arguments().at(idx)->TsType(), + sig->Params().at(idx)->TsType(), callExpr->Arguments().at(idx)->Start(), + {{diagnostic::INVALID_ASSIGNMNENT, {sig->Params().at(idx)->TsType(), sig->Params().at(idx)->TsType()}}}); + if (!ctx.IsAssignable()) { + return nullptr; + } + } + return sig; +} + Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVector &signatures, ir::CallExpression *callExpr, const lexer::SourcePosition &pos, @@ -1021,6 +1112,7 @@ Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVectorTypeParams(), callExpr->Arguments(), pos, "call", reportFlag); + sig = MakeSignatureInvocable(sig, callExpr); UpdateDeclarationFromSignature(callExpr, sig); return sig; } @@ -1040,6 +1132,7 @@ Signature *ETSChecker::ResolveCallExpressionAndTrailingLambda(ArenaVectorTypeParams(), callExpr->Arguments(), pos, "call", reportFlag); + sig = MakeSignatureInvocable(sig, callExpr); if (sig != nullptr) { EnsureValidCurlyBrace(callExpr); } @@ -1164,7 +1257,8 @@ checker::Type *ETSChecker::BuildMethodSignature(ir::MethodDefinition *method) } bool ETSChecker::CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload, - const ir::MethodDefinition *const currentFunc, bool omitSameAsm) + const ir::MethodDefinition *const currentFunc, bool omitSameAsm, + TypeRelationFlag relationFlags) { // Don't necessary to check overload for invalid functions if (func->Name().Is(ERROR_LITERAL)) { @@ -1172,7 +1266,7 @@ bool ETSChecker::CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType return false; } - SavedTypeRelationFlagsContext savedFlagsCtx(Relation(), TypeRelationFlag::NO_RETURN_TYPE_CHECK); + SavedTypeRelationFlagsContext savedFlagsCtx(Relation(), relationFlags); Relation()->SignatureIsIdenticalTo(func->CallSignatures()[0], overload->CallSignatures()[0]); if (Relation()->IsTrue() && func->CallSignatures()[0]->GetSignatureInfo()->restVar == @@ -2122,30 +2216,23 @@ size_t &ETSChecker::ConstraintCheckScopesCount() return constraintCheckScopesCount_; } -bool ETSChecker::CmpAssemblerTypesWithRank(Signature const *const sig1, Signature const *const sig2) noexcept +bool ETSChecker::HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept { - for (size_t ix = 0U; ix < sig1->Params().size(); ++ix) { - std::stringstream s1; - std::stringstream s2; - sig1->Params()[ix]->TsType()->ToAssemblerTypeWithRank(s1); - sig2->Params()[ix]->TsType()->ToAssemblerTypeWithRank(s2); - if (s1.str() != s2.str()) { - return false; - break; - } + if (sig1->ReturnType()->ToAssemblerTypeWithRank() != sig2->ReturnType()->ToAssemblerTypeWithRank()) { + return false; } - return true; -} -bool ETSChecker::HasSameAssemblySignature(Signature const *const sig1, Signature const *const sig2) noexcept -{ if (sig1->ArgCount() != sig2->ArgCount()) { return false; } - if (!CmpAssemblerTypesWithRank(sig1, sig2)) { - return false; + for (size_t ix = 0U; ix < sig1->Params().size(); ++ix) { + if (sig1->Params()[ix]->TsType()->ToAssemblerTypeWithRank() != + sig2->Params()[ix]->TsType()->ToAssemblerTypeWithRank()) { + return false; + } } + auto *rv1 = sig1->RestVar(); auto *rv2 = sig2->RestVar(); if (rv1 == nullptr && rv2 == nullptr) { @@ -2154,11 +2241,8 @@ bool ETSChecker::HasSameAssemblySignature(Signature const *const sig1, Signature if (rv1 == nullptr || rv2 == nullptr) { // exactly one of them is null return false; } - std::stringstream s1; - std::stringstream s2; - rv1->TsType()->ToAssemblerTypeWithRank(s1); - rv2->TsType()->ToAssemblerTypeWithRank(s2); - return s1.str() == s2.str(); + + return (rv1->TsType()->ToAssemblerTypeWithRank() == rv2->TsType()->ToAssemblerTypeWithRank()); } bool ETSChecker::HasSameAssemblySignatures(ETSFunctionType const *const func1, diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index b144fbcb54..f5412482ab 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -16,6 +16,8 @@ #include "checker/ETSchecker.h" #include "checker/types/globalTypesHolder.h" +#include "checker/checkerContext.h" +#include "checker/ETSAnalyzerHelpers.h" #include "checker/types/ets/etsTupleType.h" #include "checker/ets/typeRelationContext.h" #include "checker/ets/typeConverter.h" @@ -367,6 +369,27 @@ checker::Type *ETSChecker::ApplyConditionalOperatorPromotion(checker::ETSChecker ES2PANDA_UNREACHABLE(); } +Type *ETSChecker::GetUnaryOperatorPromotedType(Type *type, const bool doPromotion, const bool isCondExpr) +{ + auto globalTypesHolder = GetGlobalTypesHolder(); + + if (doPromotion) { + if (type == globalTypesHolder->GlobalByteBuiltinType() || type == globalTypesHolder->GlobalShortBuiltinType() || + type == globalTypesHolder->GlobalCharBuiltinType() || + type == globalTypesHolder->GlobalIntegerBuiltinType()) { + return globalTypesHolder->GlobalIntegerBuiltinType(); + } + + Type *unboxedType = isCondExpr ? MaybeUnboxConditionalInRelation(type) : MaybeUnboxInRelation(type); + + if (type->IsIntType() || type->IsByteType() || type->IsShortType() || type->IsCharType()) { + return CreateIntTypeFromType(unboxedType); + } + } + + return type; +} + Type *ETSChecker::ApplyUnaryOperatorPromotion(Type *type, const bool createConst, const bool doPromotion, const bool isCondExpr) { @@ -403,7 +426,7 @@ bool ETSChecker::IsNullLikeOrVoidExpression(const ir::Expression *expr) const std::tuple ETSChecker::IsResolvedAndValue(const ir::Expression *expr, Type *type) const { auto [isResolve, isValue] = - IsNullLikeOrVoidExpression(expr) ? std::make_tuple(true, false) : type->ResolveConditionExpr(); + IsNullLikeOrVoidExpression(expr) ? std::make_tuple(true, false) : IsConstantTestValue(expr); const Type *tsType = expr->TsType(); if (tsType->DefinitelyNotETSNullish() && !type->IsETSPrimitiveOrEnumType()) { @@ -453,15 +476,6 @@ Type *ETSChecker::HandleBooleanLogicalOperators(Type *leftType, Type *rightType, bool ETSChecker::HandleLogicalPotentialResult(ir::Expression *left, ir::Expression *right, ir::BinaryExpression *expr, checker::Type *leftType) { - if (leftType->IsConstantType() && leftType->IsETSBooleanType()) { - if (expr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) { - expr->SetResult(leftType->AsETSBooleanType()->GetValue() ? right : left); - return true; - } - expr->SetResult(leftType->AsETSBooleanType()->GetValue() ? left : right); - return true; - } - if (!leftType->IsETSPrimitiveType() && !leftType->PossiblyETSValueTyped()) { expr->SetResult(expr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND ? right : left); return true; @@ -534,7 +548,6 @@ checker::Type *ETSChecker::CheckArrayElements(ir::ArrayExpression *init) for (auto *typeFromTuple : elementType->AsETSTupleType()->GetTupleTypesList()) { elementTypes.emplace_back(typeFromTuple); } - continue; } @@ -542,22 +555,30 @@ checker::Type *ETSChecker::CheckArrayElements(ir::ArrayExpression *init) elementType = elementType->AsETSArrayType()->ElementType(); } - elementTypes.push_back(GetNonConstantType(elementType)); + elementTypes.emplace_back(elementType); } if (elementTypes.empty()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return Allocator()->New(GlobalETSObjectType()); } - auto const isNumeric = [](checker::Type *ct) { return ct->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC); }; - auto const isChar = [](checker::Type *ct) { return ct->HasTypeFlag(TypeFlag::CHAR); }; - auto *const arrayElementType = - std::all_of(elementTypes.begin(), elementTypes.end(), isNumeric) - ? std::all_of(elementTypes.begin(), elementTypes.end(), isChar) ? GlobalCharType() : GlobalDoubleType() - : CreateETSUnionType(std::move(elementTypes)); + auto const isNumericLiteral = [this](checker::Type *&ct) { + auto const rc = + ct->IsConstantType() && Relation()->IsSupertypeOf(GetGlobalTypesHolder()->GlobalNumericBuiltinType(), ct); + ct = GetNonConstantType(ct); + return rc; + }; + auto const isChar = [this](checker::Type *ct) { + return Relation()->IsSupertypeOf(GetGlobalTypesHolder()->GlobalCharBuiltinType(), ct); + }; + auto const elementType = std::all_of(elementTypes.begin(), elementTypes.end(), isNumericLiteral) + ? std::all_of(elementTypes.begin(), elementTypes.end(), isChar) + ? GlobalCharBuiltinType() + : GlobalDoubleBuiltinType() + : CreateETSUnionType(std::move(elementTypes)); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return CreateETSResizableArrayType(arrayElementType); + return CreateETSResizableArrayType(elementType); } void ETSChecker::InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::ArrowFunctionExpression *init) @@ -995,7 +1016,7 @@ checker::Type *ETSChecker::GetExtensionAccessorReturnType(ir::MemberExpression * // Smart cast support //==============================================================================// -checker::Type *ETSChecker::ResolveSmartType(checker::Type *sourceType, checker::Type *targetType) +checker::Type *ETSChecker::ResolveSmartType(checker::Type *sourceType, checker::Type *targetType, bool narrowingAllowed) { // For left-hand variable of primitive type leave it as is. if (targetType->IsETSPrimitiveType()) { @@ -1035,7 +1056,7 @@ checker::Type *ETSChecker::ResolveSmartType(checker::Type *sourceType, checker:: // Because now we have logging of errors we have to continue analyze incorrect program, for // this case we change typeError to source type. if (targetType->IsETSUnionType()) { - auto component = targetType->AsETSUnionType()->GetAssignableType(this, sourceType); + auto component = targetType->AsETSUnionType()->GetAssignableType(this, sourceType, narrowingAllowed); return component->IsTypeError() ? MaybeBoxType(sourceType) : component; } @@ -1809,7 +1830,9 @@ void ETSChecker::ConcatConstantString(util::UString &target, Type *type) { switch (ETSType(type)) { case TypeFlag::ETS_OBJECT: { - ES2PANDA_ASSERT(type->IsETSStringType()); + if (!type->IsETSStringType()) { + break; + } target.Append(type->AsETSStringType()->GetValue()); break; } @@ -2123,7 +2146,7 @@ void ETSChecker::CheckItemCasesConstant(ArenaVector c if (caseTest == nullptr) { continue; } - auto *caseType = caseTest->TsType(); + auto *caseType = MaybeUnboxType(caseTest->TsType()); if (caseType->HasTypeFlag(TypeFlag::TYPE_ERROR)) { continue; } @@ -2201,7 +2224,7 @@ void ETSChecker::CheckItemCasesDuplicate(ArenaVector } if (caseTest->IsLiteral() && compareCaseTest->IsLiteral() && - GetStringFromLiteral(caseTest) != GetStringFromLiteral(compareCaseTest)) { + caseTest->AsLiteral()->ToString() != compareCaseTest->AsLiteral()->ToString()) { continue; } @@ -2231,7 +2254,7 @@ bool ETSChecker::CompareIdentifiersValuesAreDifferent(ir::Expression *compareVal return caseValue != compareCaseValue; } - return caseValue != GetStringFromLiteral(compareValue); + return caseValue != compareValue->ToString(); } void ETSChecker::CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expression *compareCase, @@ -2255,23 +2278,6 @@ void ETSChecker::CheckIdentifierSwitchCase(ir::Expression *currentCase, ir::Expr } } -std::string ETSChecker::GetStringFromLiteral(ir::Expression *caseTest) const -{ - switch (caseTest->Type()) { - case ir::AstNodeType::CHAR_LITERAL: { - return std::to_string(caseTest->AsCharLiteral()->Char()); - } - case ir::AstNodeType::STRING_LITERAL: - case ir::AstNodeType::NULL_LITERAL: - case ir::AstNodeType::UNDEFINED_LITERAL: - case ir::AstNodeType::NUMBER_LITERAL: { - return util::Helpers::LiteralToPropName(caseTest).Mutf8(); - } - default: - ES2PANDA_UNREACHABLE(); - } -} - bool ETSChecker::IsSameDeclarationType(varbinder::LocalVariable *target, varbinder::LocalVariable *compare) { return target->Declaration()->Type() == compare->Declaration()->Type(); @@ -2624,6 +2630,7 @@ ir::ClassProperty *ETSChecker::ClassPropToImplementationProp(ir::ClassProperty * return classProp; } +// CC-OFFNXT(huge_method) solid logic void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, ArenaVector ¶ms, ir::ClassProperty *const field, varbinder::FunctionParamScope *paramScope, bool isSetter) @@ -2685,6 +2692,7 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto ident = AllocNode(paramExpression->Ident()->Name(), Allocator()); ident->SetVariable(paramExpression->Variable()); + ident->SetTsTypeAnnotation(nullptr); auto *assignmentExpression = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) AllocNode(memberExpression, ident, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); @@ -2720,6 +2728,7 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty functionScope->BindParamScope(paramScope); paramScope->BindFunctionScope(functionScope); + auto classCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), classScope); ArenaVector params(checker->Allocator()->Adapter()); ArenaVector stmts(checker->Allocator()->Adapter()); @@ -2775,7 +2784,6 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty paramScope->BindNode(func); functionScope->BindNode(func); - auto classCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), classScope); checker->VarBinder()->AsETSBinder()->ResolveMethodDefinition(method); functionScope->BindName(classScope->Node()->AsClassDefinition()->InternalName()); @@ -2894,6 +2902,7 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin getter->Variable()->TsType()->AsETSFunctionType()->AddCallSignature( setter->TsType()->AsETSFunctionType()->CallSignatures()[0]); getter->AddOverload(setter); + setter->SetParent(getter); } } diff --git a/ets2panda/checker/ets/narrowingConverter.h b/ets2panda/checker/ets/narrowingConverter.h index f42051d88b..483c72aa61 100644 --- a/ets2panda/checker/ets/narrowingConverter.h +++ b/ets2panda/checker/ets/narrowingConverter.h @@ -173,27 +173,49 @@ private: using SType = typename SourceType::UType; using TType = typename TargetType::UType; + // in case of + // let d: Char; + // const s: Short = -129 + // d = s + // we have to check for NumberLiteral too, because after ConstantExpressionLowering src will look like + // let d: Char; + // const s: Short = -129 + // d = -129 + // And NumberLiteral "-129" will have type Short. It should be CTE: value out of range + // NOTE: The same situation with CharLiteral + // NOTE: After complete removing primitive types refactor is needed + if (!Source()->HasTypeFlag(TypeFlag::CONSTANT) && !Relation()->GetNode()->IsNumberLiteral() && + !Relation()->GetNode()->IsCharLiteral()) { + Relation()->Result(true); + return; + } + + SType value; if (Source()->HasTypeFlag(TypeFlag::CONSTANT)) { - SType value = reinterpret_cast(Source())->GetValue(); - if (!Relation()->InCastingContext() && Source()->HasTypeFlag(TypeFlag::ETS_FLOATING_POINT) && - Target()->HasTypeFlag(TypeFlag::ETS_INTEGRAL)) { - auto narrowedValue = CalculateNarrowedValue(Target(), Source(), value); - if (narrowedValue != value) { - Relation()->Result(RelationResult::ERROR); - return; - } - } + value = reinterpret_cast(Source())->GetValue(); + } else if (Relation()->GetNode()->IsNumberLiteral()) { + // NumberLiteral + value = Relation()->GetNode()->AsNumberLiteral()->Number().GetValueAndCastTo(); + } else { + // CharLiteral + value = static_cast(Relation()->GetNode()->AsCharLiteral()->Char()); + } - if (Relation()->InCastingContext() || util::Helpers::IsTargetFitInSourceRange(value)) { - Relation()->Result(true); + if (!Relation()->InCastingContext() && Source()->HasTypeFlag(TypeFlag::ETS_FLOATING_POINT) && + Target()->HasTypeFlag(TypeFlag::ETS_INTEGRAL)) { + auto narrowedValue = CalculateNarrowedValue(Target(), Source(), value); + if (narrowedValue != value) { + Relation()->Result(RelationResult::ERROR); return; } + } - Relation()->Result(RelationResult::ERROR); + if (Relation()->InCastingContext() || util::Helpers::IsTargetFitInSourceRange(value)) { + Relation()->Result(true); return; } - Relation()->Result(true); + Relation()->Result(RelationResult::ERROR); } }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 4c1bd6ba8b..35ac9d8ae2 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -1467,37 +1467,6 @@ void ETSChecker::CheckInnerClassMembers(const ETSObjectType *classType) } } -lexer::Number ETSChecker::ExtractNumericValue(Type const *const indexType) -{ - TypeFlag typeKind = ETSType(indexType); - lexer::Number resNum; - switch (typeKind) { - case TypeFlag::BYTE: { - resNum = lexer::Number(indexType->AsByteType()->GetValue()); - break; - } - case TypeFlag::SHORT: { - resNum = lexer::Number(indexType->AsShortType()->GetValue()); - break; - } - case TypeFlag::INT: { - resNum = lexer::Number(indexType->AsIntType()->GetValue()); - break; - } - case TypeFlag::FLOAT: { - resNum = lexer::Number(indexType->AsFloatType()->GetValue()); - break; - } - case TypeFlag::DOUBLE: { - resNum = lexer::Number(indexType->AsDoubleType()->GetValue()); - break; - } - default: - break; - } - return resNum; -} - bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) { auto const expressionType = expr->Check(this); @@ -1510,28 +1479,8 @@ bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) expr->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxedExpressionType)); } - Type const *const indexType = ApplyUnaryOperatorPromotion(expressionType); - - if (relaxed && indexType != nullptr) { - lexer::Number resNum = ExtractNumericValue(indexType); - double value = resNum.GetDouble(); - double intpart; - if (std::modf(value, &intpart) != 0.0) { - LogError(diagnostic::INDEX_NONINTEGRAL_FLOAT, {}, expr->Start()); - return false; - } - bool tildeFlag = false; - if (expr->IsUnaryExpression() && - expr->AsUnaryExpression()->OperatorType() == lexer::TokenType::PUNCTUATOR_TILDE) { - tildeFlag = true; - } - if ((tildeFlag && value > 0) || (!tildeFlag && value < 0)) { - LogError(diagnostic::NEGATIVE_INDEX, {}, expr->Start()); - return false; - } - } - - if (indexType == nullptr || + if (Type const *const indexType = ApplyUnaryOperatorPromotion(expressionType); + indexType == nullptr || (!indexType->HasTypeFlag(relaxed ? (TypeFlag::ETS_ARRAY_INDEX | TypeFlag::ETS_FLOATING_POINT) : TypeFlag::ETS_ARRAY_INDEX))) { std::stringstream message(""); @@ -1541,11 +1490,51 @@ bool ETSChecker::ValidateArrayIndex(ir::Expression *const expr, bool relaxed) return false; } + if (!relaxed || !expressionType->IsConstantType()) { + return true; + } + + ASSERT(expr->IsNumberLiteral()); + double value = expr->AsNumberLiteral()->Number().GetDouble(); + + double intPart; + if (std::modf(value, &intPart) != 0.0) { + LogError(diagnostic::INDEX_NONINTEGRAL_FLOAT, {}, expr->Start()); + return false; + } + + if (intPart < 0.0) { + LogError(diagnostic::NEGATIVE_INDEX, {}, expr->Start()); + return false; + } + return true; } -std::optional ETSChecker::GetTupleElementAccessValue(const Type *const type) +std::optional ETSChecker::GetTupleElementAccessValue(const ir::Expression *expr) { + auto checkLongValBounds = [this](int64_t val, const lexer::SourcePosition &p) -> std::optional { + if (val < 0) { + LogError(diagnostic::TUPLE_INDEX_OOB, {}, p); + return std::nullopt; + } + return static_cast(val); + }; + + if (expr->IsNumberLiteral()) { + auto num = expr->AsNumberLiteral()->Number(); + if (num.IsInt()) { + return checkLongValBounds(num.GetInt(), expr->Start()); + } + if (num.IsLong()) { + return checkLongValBounds(num.GetLong(), expr->Start()); + } + ES2PANDA_UNREACHABLE(); + } + + // Below code should be unreachable after removing primitives + auto type = expr->TsType(); + ES2PANDA_ASSERT(type->HasTypeFlag(TypeFlag::CONSTANT | TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)); switch (ETSType(type)) { @@ -1574,14 +1563,9 @@ std::optional ETSChecker::GetTupleElementAccessValue(const Type *co bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberExpression *const expr, const bool reportError) { - auto const expressionType = expr->Property()->Check(this); - auto const *const unboxedExpressionType = MaybeUnboxInRelation(expressionType); - - if (expressionType->IsETSObjectType() && (unboxedExpressionType != nullptr)) { - expr->Property()->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxedExpressionType)); - } + auto const exprType = expr->Property()->Check(this); + auto const *const unboxedExpressionType = MaybeUnboxInRelation(exprType); - const auto *const exprType = expr->Property()->TsType(); ES2PANDA_ASSERT(exprType != nullptr); if (!exprType->HasTypeFlag(TypeFlag::CONSTANT)) { @@ -1594,14 +1578,13 @@ bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberE return false; } - if (!exprType->HasTypeFlag(TypeFlag::ETS_ARRAY_INDEX | TypeFlag::LONG)) { - if (reportError) { - LogError(diagnostic::TUPLE_INDEX_NOT_INT, {}, expr->Property()->Start()); - } + if (!Relation()->IsSupertypeOf(GlobalIntBuiltinType(), exprType) && + !Relation()->IsSupertypeOf(GlobalLongBuiltinType(), exprType)) { + LogError(diagnostic::TUPLE_INDEX_NOT_INT, {}, expr->Property()->Start()); return false; } - auto exprValue = GetTupleElementAccessValue(exprType); + auto exprValue = GetTupleElementAccessValue(expr->Property()); if (!exprValue.has_value() || (*exprValue >= tuple->GetTupleSize())) { if (reportError) { LogError(diagnostic::TUPLE_INDEX_OOB, {}, expr->Property()->Start()); @@ -1614,6 +1597,13 @@ bool ETSChecker::ValidateTupleIndex(const ETSTupleType *const tuple, ir::MemberE bool ETSChecker::ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple, ir::MemberExpression *const expr) { + if (expr->Property() == nullptr || expr->Property()->Variable() == nullptr || + expr->Property()->Variable()->Declaration() == nullptr || + expr->Property()->Variable()->Declaration()->Node() == nullptr || + expr->Property()->Variable()->Declaration()->Node()->AsClassElement() == nullptr) { + LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Start()); + return false; + } auto *value = expr->Property()->Variable()->Declaration()->Node()->AsClassElement()->Value(); if (value == nullptr) { LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Property()->Start()); @@ -1631,7 +1621,7 @@ bool ETSChecker::ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple return false; } - auto exprValue = GetTupleElementAccessValue(exprType); + auto exprValue = GetTupleElementAccessValue(expr); if (!exprValue.has_value() || (*exprValue >= tuple->GetTupleSize())) { LogError(diagnostic::TUPLE_INDEX_OOB, {}, expr->Property()->Start()); return false; @@ -1917,6 +1907,9 @@ static bool ShouldRemoveStaticSearchFlag(const ir::MemberExpression *const membe if (object->IsMemberExpression()) { object = object->AsMemberExpression()->Property(); } + if (object->IsTypeNode()) { + return false; + } if (!object->IsIdentifier() || (object->AsIdentifier()->Variable() == nullptr) || object->AsIdentifier()->Variable()->HasFlag(varbinder::VariableFlags::INITIALIZED)) { return true; @@ -1957,6 +1950,9 @@ const varbinder::Variable *ETSChecker::GetTargetRef(const ir::MemberExpression * if (memberExpr->Object()->IsMemberExpression()) { return memberExpr->Object()->AsMemberExpression()->PropVar(); } + if (memberExpr->Object()->IsTypeNode() && memberExpr->Object()->TsType()->IsETSObjectType()) { + return memberExpr->Object()->TsType()->Variable(); + } return nullptr; } @@ -2466,21 +2462,7 @@ Type *ETSChecker::GetApparentType(Type *type) Type const *ETSChecker::GetApparentType(Type const *type) const { - if (auto it = apparentTypes_.find(type); LIKELY(it != apparentTypes_.end())) { - return it->second; - } - // Relaxed for some types - if (type->IsETSTypeParameter()) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - return GetApparentType(type->AsETSTypeParameter()->GetConstraintType()); - } - if (type->IsETSArrayType()) { - return type; - } - if (type->IsETSUnionType() || type->IsETSNonNullishType() || type->IsETSPartialTypeParameter()) { - ASSERT_PRINT(false, std::string("Type ") + type->ToString() + " was not found in apparent_types_"); - } - return type; + return const_cast(const_cast(this)->GetApparentType(const_cast(type))); } ETSObjectType *ETSChecker::GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target) diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index e65e3567b0..92cbd276d8 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -387,6 +387,9 @@ Type *ETSChecker::GetNonConstantType(Type *type) } if (!type->IsETSPrimitiveType()) { + if (type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive()) { + type->RemoveTypeFlag(TypeFlag::CONSTANT); + } return type; } @@ -1076,6 +1079,36 @@ void ETSChecker::CheckStandardAnnotation(ir::AnnotationUsage *anno) } } +static auto IsNonArrayLiteral(ir::Expression *init) +{ + if ((init == nullptr) || init->IsLiteral()) { + return true; + } + + if (init->TsType()->IsETSEnumType() && init->TsType()->AsETSEnumType()->NodeIsEnumLiteral(init)) { + init->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + return true; + } + return false; +} + +static auto IsValidAnnotationPropInitializer(ir::Expression *init) +{ + if (IsNonArrayLiteral(init)) { + return true; + } + + if (init->IsArrayExpression()) { + for (auto elem : init->AsArrayExpression()->Elements()) { + if (!IsValidAnnotationPropInitializer(elem)) { + return false; + } + } + return true; + } + return false; +} + void ETSChecker::CheckAnnotationPropertyType(ir::ClassProperty *property) { // typeAnnotation check @@ -1083,14 +1116,11 @@ void ETSChecker::CheckAnnotationPropertyType(ir::ClassProperty *property) LogError(diagnostic::ANNOT_FIELD_INVALID_TYPE, {}, property->Start()); } - // The type of the Initializer has been check in the parser, - // except for the enumeration type, because it is a member expression, - // so here is an additional check to the enumeration type. - if (property->Value() != nullptr && - ((property->Value()->IsMemberExpression() && !property->TsType()->IsETSEnumType()) || - property->Value()->IsIdentifier())) { - LogError(diagnostic::ANNOTATION_FIELD_NONLITERAL, {}, property->Value()->Start()); + if (IsValidAnnotationPropInitializer(property->Value())) { + return; } + + LogError(diagnostic::ANNOTATION_FIELD_NONLITERAL, {}, property->Value()->Start()); } void ETSChecker::CheckSinglePropertyAnnotation(ir::AnnotationUsage *st, ir::AnnotationDeclaration *annoDecl) @@ -1119,6 +1149,7 @@ void ETSChecker::ProcessRequiredFields(ArenaUnorderedMapClone(checker->Allocator(), st); st->AddProperty(clone); + clone->Check(checker); } } @@ -1452,6 +1483,7 @@ bool ETSChecker::CheckLambdaTypeAnnotation(ir::AstNode *typeAnnotation, // #22952: infer optional parameter heuristics auto nonNullishParam = param->IsOptional() ? GetNonNullishType(parameterType) : parameterType; if (!nonNullishParam->IsETSFunctionType()) { + arrowFuncExpr->Check(this); return true; } // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index 039b1ce024..6b94d2fe42 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -78,19 +78,7 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ir::TSTypeParame result_ = paramType; return; } - - if (paramType->IsETSPrimitiveType()) { - checker_->Relation()->SetNode(it); - - auto *const boxedTypeArg = checker_->MaybeBoxInRelation(paramType); - if (boxedTypeArg != nullptr) { - paramType = boxedTypeArg->Instantiate(checker_->Allocator(), checker_->Relation(), - checker_->GetGlobalTypesHolder()); - } else { - ES2PANDA_UNREACHABLE(); - } - } - + ES2PANDA_ASSERT(!paramType->IsETSPrimitiveType()); typeArgTypes.push_back(paramType); } } @@ -137,10 +125,10 @@ static void CheckInstantiationConstraints(ETSChecker *checker, ArenaVectorIsETSReferenceType() || typeArg->IsETSVoidType()); + auto maybeIrrelevantTypeArg = typeArg->IsETSVoidType() ? checker->GlobalETSUndefinedType() : typeArg; auto constraint = typeParam->GetConstraintType()->Substitute(relation, substitution); - if (!relation->IsAssignableTo(typeArg, constraint)) { - // NOTE(vpukhov): refine message - checker->LogError(diagnostic::INIT_NOT_ASSIGNABLE, {typeArg, constraint}, pos); + if (!relation->IsSupertypeOf(constraint, maybeIrrelevantTypeArg)) { + checker->LogError(diagnostic::TYPEARG_TYPEPARAM_SUBTYPING, {typeArg, constraint}, pos); } } } diff --git a/ets2panda/checker/ets/typeRelationContext.h b/ets2panda/checker/ets/typeRelationContext.h index ef6c5017f9..9a97781e87 100644 --- a/ets2panda/checker/ets/typeRelationContext.h +++ b/ets2panda/checker/ets/typeRelationContext.h @@ -55,9 +55,7 @@ public: if (!relation->IsAssignableTo(source, target)) { if (relation->IsLegalBoxedPrimitiveConversion(target, source)) { - Type *sourceUnboxedType = etsChecker->MaybeUnboxType(source); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetUnboxingFlag(sourceUnboxedType)); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetBoxingFlag(target)); + relation->Result(true); } if (((flags_ & TypeRelationFlag::UNBOXING) != 0) && !relation->IsTrue() && source->IsETSObjectType() && !target->IsETSObjectType()) { @@ -107,6 +105,9 @@ public: relation->SetFlags(flags_ | initialFlags); if (!relation->IsAssignableTo(source, target)) { + if (relation->IsLegalBoxedPrimitiveConversion(target, source)) { + relation->Result(true); + } if (((flags_ & TypeRelationFlag::UNBOXING) != 0U) && !relation->IsTrue() && source->IsETSObjectType() && !target->IsETSObjectType()) { etsChecker->CheckUnboxedSourceTypeWithWideningAssignable(relation, source, target); diff --git a/ets2panda/checker/ets/validateHelpers.cpp b/ets2panda/checker/ets/validateHelpers.cpp index c8d7e269c9..a99d8ef1e6 100644 --- a/ets2panda/checker/ets/validateHelpers.cpp +++ b/ets2panda/checker/ets/validateHelpers.cpp @@ -191,8 +191,14 @@ bool ETSChecker::ValidateAnnotationPropertyType(checker::Type *type) return ValidateAnnotationPropertyType(MaybeUnboxType(GetElementTypeOfArray(type))); } - return type->HasTypeFlag(TypeFlag::ETS_NUMERIC | TypeFlag::ETS_ENUM | TypeFlag::ETS_BOOLEAN) || - type->IsETSStringType(); + return type->IsETSEnumType() || type->IsETSStringType() || + (type->IsETSObjectType() && (Relation()->IsSupertypeOf(GlobalETSBooleanBuiltinType(), type) || + Relation()->IsSupertypeOf(GlobalByteBuiltinType(), type) || + Relation()->IsSupertypeOf(GlobalShortBuiltinType(), type) || + Relation()->IsSupertypeOf(GlobalIntBuiltinType(), type) || + Relation()->IsSupertypeOf(GlobalLongBuiltinType(), type) || + Relation()->IsSupertypeOf(GlobalFloatBuiltinType(), type) || + Relation()->IsSupertypeOf(GlobalDoubleBuiltinType(), type))); } void ETSChecker::ValidateUnaryOperatorOperand(varbinder::Variable *variable) diff --git a/ets2panda/checker/types/ets/byteType.h b/ets2panda/checker/types/ets/byteType.h index a92f1f637d..a622ebc4e2 100644 --- a/ets2panda/checker/types/ets/byteType.h +++ b/ets2panda/checker/types/ets/byteType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_BYTE; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/charType.h b/ets2panda/checker/types/ets/charType.h index 9ddb9054ff..793a64ea4e 100644 --- a/ets2panda/checker/types/ets/charType.h +++ b/ets2panda/checker/types/ets/charType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_CHAR; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != '\0'}; - } - private: UType value_ {'\0'}; }; diff --git a/ets2panda/checker/types/ets/doubleType.h b/ets2panda/checker/types/ets/doubleType.h index e7e7dde792..fa3d5de326 100644 --- a/ets2panda/checker/types/ets/doubleType.h +++ b/ets2panda/checker/types/ets/doubleType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,12 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_DOUBLE; } - std::tuple ResolveConditionExpr() const override - { - // isNan = !(value_ == value_) - return {IsConstantType(), (value_ != 0) && (value_ == value_)}; - } - private: UType value_ {0.0}; }; diff --git a/ets2panda/checker/types/ets/etsArrayType.cpp b/ets2panda/checker/types/ets/etsArrayType.cpp index 2f0573d664..79d9cc3983 100644 --- a/ets2panda/checker/types/ets/etsArrayType.cpp +++ b/ets2panda/checker/types/ets/etsArrayType.cpp @@ -111,7 +111,7 @@ void ETSArrayType::AssignmentTarget(TypeRelation *relation, Type *source) source->AsETSArrayType()->ElementType()->IsETSPrimitiveOrEnumType()) { return; } - relation->IsAssignableTo(source->AsETSArrayType()->ElementType(), element_); + relation->IsSupertypeOf(element_, source->AsETSArrayType()->ElementType()); } } diff --git a/ets2panda/checker/types/ets/etsArrayType.h b/ets2panda/checker/types/ets/etsArrayType.h index 9794adb54f..c9dd00904f 100644 --- a/ets2panda/checker/types/ets/etsArrayType.h +++ b/ets2panda/checker/types/ets/etsArrayType.h @@ -38,11 +38,6 @@ public: element_ = element; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - void ToString(std::stringstream &ss, bool precise) const override; void ToAssemblerType(std::stringstream &ss) const override; diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp index 46308e495d..599a503b43 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp @@ -39,6 +39,15 @@ void ETSAsyncFuncReturnType::Identical(TypeRelation *relation, Type *other) relation->Result(false); } +void ETSAsyncFuncReturnType::IsSupertypeOf(TypeRelation *relation, Type *source) +{ + GetPromiseTypeArg()->IsSupertypeOf(relation, source); + if (relation->IsTrue()) { + return; + } + promiseType_->IsSupertypeOf(relation, source); +} + bool ETSAsyncFuncReturnType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) { return false; diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h index e1ede4842b..1cdc68d389 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.h @@ -33,6 +33,7 @@ public: void ToString(std::stringstream &ss, bool precise) const override; void Identical(TypeRelation *relation, Type *other) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; diff --git a/ets2panda/checker/types/ets/etsBooleanType.h b/ets2panda/checker/types/ets/etsBooleanType.h index 421ae63e3b..2bc7ccaddc 100644 --- a/ets2panda/checker/types/ets/etsBooleanType.h +++ b/ets2panda/checker/types/ets/etsBooleanType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -51,11 +51,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_BOOLEAN; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_}; - } - private: UType value_ {false}; }; diff --git a/ets2panda/checker/types/ets/etsEnumType.h b/ets2panda/checker/types/ets/etsEnumType.h index a5c6bdf33d..ad1fc07d26 100644 --- a/ets2panda/checker/types/ets/etsEnumType.h +++ b/ets2panda/checker/types/ets/etsEnumType.h @@ -19,6 +19,10 @@ #include "checker/types/ets/etsObjectType.h" #include "checker/types/ets/etsObjectTypeConstants.h" #include "checker/types/typeFlag.h" +#include "ir/base/classProperty.h" +#include "ir/expressions/arrayExpression.h" +#include "ir/expressions/literals/stringLiteral.h" +#include "ir/expressions/memberExpression.h" namespace ark::es2panda::checker { @@ -27,8 +31,10 @@ public: explicit ETSEnumType(ArenaAllocator *allocator, util::StringView name, util::StringView internalName, ir::AstNode *declNode, TypeRelation *relation) : ETSObjectType(allocator, name, internalName, - std::make_tuple(declNode, ETSObjectFlags::CLASS | ETSObjectFlags::ENUM_OBJECT, relation)) + std::make_tuple(declNode, ETSObjectFlags::CLASS | ETSObjectFlags::ENUM_OBJECT, relation)), + memberNameToOrdinal_(allocator->Adapter()) { + InitElementsShortcuts(declNode->AsClassDefinition()); } NO_COPY_SEMANTIC(ETSEnumType); @@ -37,14 +43,79 @@ public: ETSEnumType() = delete; ~ETSEnumType() override = default; - static constexpr std::string_view const TO_STRING_METHOD_NAME {"toString"}; - static constexpr std::string_view const VALUE_OF_METHOD_NAME {"valueOf"}; - static constexpr std::string_view const GET_NAME_METHOD_NAME {"getName"}; - static constexpr std::string_view const GET_VALUE_OF_METHOD_NAME {"getValueOf"}; - static constexpr std::string_view const FROM_VALUE_METHOD_NAME {"fromValue"}; - static constexpr std::string_view const VALUES_METHOD_NAME {"values"}; - static constexpr std::string_view const GET_ORDINAL_METHOD_NAME {"getOrdinal"}; - static constexpr std::string_view const DOLLAR_GET_METHOD_NAME {"$_get"}; + static constexpr std::string_view TO_STRING_METHOD_NAME {"toString"}; + static constexpr std::string_view VALUE_OF_METHOD_NAME {"valueOf"}; + static constexpr std::string_view GET_NAME_METHOD_NAME {"getName"}; + static constexpr std::string_view GET_VALUE_OF_METHOD_NAME {"getValueOf"}; + static constexpr std::string_view FROM_VALUE_METHOD_NAME {"fromValue"}; + static constexpr std::string_view VALUES_METHOD_NAME {"values"}; + static constexpr std::string_view GET_ORDINAL_METHOD_NAME {"getOrdinal"}; + static constexpr std::string_view DOLLAR_GET_METHOD_NAME {"$_get"}; + + static constexpr std::string_view STRING_VALUES_ARRAY_NAME {"#StringValuesArray"}; + static constexpr std::string_view VALUES_ARRAY_NAME {"#ValuesArray"}; + static constexpr std::string_view NAMES_ARRAY_NAME {"#NamesArray"}; + + auto *Underlying() + { + ES2PANDA_ASSERT(membersValues_->TsType() != nullptr); + return membersValues_->TsType()->AsETSArrayType()->ElementType(); + } + + auto GetOrdinalFromMemberName(std::string_view name) const + { + return memberNameToOrdinal_.at(name); + } + + auto GetValueLiteralFromOrdinal(size_t ord) const + { + ES2PANDA_ASSERT(ord < membersValues_->Elements().size()); + return membersValues_->Elements()[ord]; + } + + bool NodeIsEnumLiteral(ir::Expression *node) const + { + ES2PANDA_ASSERT(node->TsType() == this); + if (!node->IsMemberExpression()) { + return false; + } + + auto mobj = node->AsMemberExpression()->Object(); + if (mobj->TsType() == this) { + // No need to search properties since enum-literals are the only enum-type properties + // NOTE(dkofanov): For some reason, 'enumLowering' changes 'CLASS' to 'ENUM_LITERAL', instead of 'ENUM'. + ES2PANDA_ASSERT(mobj->Variable()->HasFlag(varbinder::VariableFlags::ENUM_LITERAL)); + ES2PANDA_ASSERT(GetDeclNode()->AsClassDefinition()->IsEnumTransformed()); + return true; + } + return false; + } + +private: + void InitElementsShortcuts(ir::ClassDefinition *declNode) + { + Span membersNames {}; + for (auto elem : declNode->Body()) { + auto elemName = elem->AsClassElement()->Key()->AsIdentifier()->Name(); + if (elemName == NAMES_ARRAY_NAME) { + membersNames = Span(elem->AsClassProperty()->Value()->AsArrayExpression()->Elements()); + } else if (elemName == VALUES_ARRAY_NAME) { + membersValues_ = elem->AsClassProperty()->Value()->AsArrayExpression(); // int-enum + } else if ((elemName == STRING_VALUES_ARRAY_NAME) && (membersValues_ == nullptr)) { + membersValues_ = elem->AsClassProperty()->Value()->AsArrayExpression(); // string-enum + } + } + auto membersValues = Span {membersValues_->Elements()}; + ES2PANDA_ASSERT(membersValues.size() == membersNames.size()); + for (size_t i = 0; i < membersNames.size(); i++) { + memberNameToOrdinal_.insert({membersNames[i]->AsStringLiteral()->Str(), i}); + ES2PANDA_ASSERT(membersValues[i]->IsStringLiteral() || membersValues[i]->IsNumberLiteral()); + } + } + +private: + ArenaMap memberNameToOrdinal_; + ir::ArrayExpression *membersValues_; }; class ETSIntEnumType : public ETSEnumType { diff --git a/ets2panda/checker/types/ets/etsFunctionType.h b/ets2panda/checker/types/ets/etsFunctionType.h index f59b65c709..49d1a17d3a 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.h +++ b/ets2panda/checker/types/ets/etsFunctionType.h @@ -134,11 +134,6 @@ public: void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - void SetHelperSignature(Signature *signature) noexcept { helperSignature_ = signature; diff --git a/ets2panda/checker/types/ets/etsNeverType.h b/ets2panda/checker/types/ets/etsNeverType.h index 06904ce058..7e998eb6b6 100644 --- a/ets2panda/checker/types/ets/etsNeverType.h +++ b/ets2panda/checker/types/ets/etsNeverType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -38,11 +38,6 @@ public: TypeFacts GetTypeFacts() const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), false}; - } }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsNullishTypes.h b/ets2panda/checker/types/ets/etsNullishTypes.h index 195332ffd2..ff11033e5d 100644 --- a/ets2panda/checker/types/ets/etsNullishTypes.h +++ b/ets2panda/checker/types/ets/etsNullishTypes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -37,11 +37,6 @@ public: void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), false}; - } }; class ETSUndefinedType : public Type { @@ -60,11 +55,6 @@ public: void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; - - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), false}; - } }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 1bbd08c262..243851bea7 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -483,6 +483,12 @@ bool ETSObjectType::CheckIdenticalFlags(ETSObjectType *other) const bool ETSObjectType::AssignmentSource(TypeRelation *const relation, [[maybe_unused]] Type *const target) { + if (target->IsETSStringType() && IsETSCharType()) { + if (relation->GetNode() != nullptr) { + relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); + } + return relation->Result(true); + } // NOTE: do not modify, to be implied by the relation return relation->IsSupertypeOf(target, this); } @@ -492,6 +498,9 @@ bool ETSObjectType::IsBoxedPrimitive() const if (this->IsETSDynamicType()) { return false; } + if (this->IsETSEnumType()) { + return false; + } return this->IsETSUnboxableObject(); } @@ -624,6 +633,12 @@ bool ETSObjectType::TryCastUnboxable(TypeRelation *const relation, Type *const t conversion::WideningReference(relation, this, target->AsETSObjectType()); return true; } + + if (target->IsETSEnumType()) { + auto unboxedThis = relation->GetChecker()->AsETSChecker()->MaybeUnboxInRelation(this); + return relation->IsCastableTo(unboxedThis, target); + } + conversion::Forbidden(relation); return true; } @@ -678,6 +693,12 @@ void ETSObjectType::Cast(TypeRelation *const relation, Type *const target) } if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { + if (target->IsETSStringType() && IsETSCharType()) { + // Cast Char to String + auto unboxed = relation->GetChecker()->AsETSChecker()->MaybeUnboxType(this); + conversion::String(relation, unboxed); + return; + } conversion::WideningReference(relation, this, target->AsETSObjectType()); if (relation->IsTrue()) { return; diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 9a174689dd..3c6b6081b0 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -397,11 +397,6 @@ public: return allocator_; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - [[nodiscard]] static std::uint32_t GetPrecedence(checker::ETSChecker *checker, ETSObjectType const *type) noexcept; bool IsPropertiesInstantiated() const diff --git a/ets2panda/checker/types/ets/etsStringType.h b/ets2panda/checker/types/ets/etsStringType.h index 2e47f48eea..bad56b1e2d 100644 --- a/ets2panda/checker/types/ets/etsStringType.h +++ b/ets2panda/checker/types/ets/etsStringType.h @@ -76,11 +76,6 @@ public: return value_; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), IsConstantType() ? (GetValue().Length() != 0) : false}; - } - bool IsConvertibleTo(Type const *to) const; private: diff --git a/ets2panda/checker/types/ets/etsTupleType.h b/ets2panda/checker/types/ets/etsTupleType.h index 31aca83175..f76aec4af4 100644 --- a/ets2panda/checker/types/ets/etsTupleType.h +++ b/ets2panda/checker/types/ets/etsTupleType.h @@ -43,11 +43,6 @@ public: return typeList_; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - [[nodiscard]] ETSObjectType *GetWrapperType() const { return wrapperType_; diff --git a/ets2panda/checker/types/ets/etsTypeAliasType.h b/ets2panda/checker/types/ets/etsTypeAliasType.h index a0811891f9..f5b249c692 100644 --- a/ets2panda/checker/types/ets/etsTypeAliasType.h +++ b/ets2panda/checker/types/ets/etsTypeAliasType.h @@ -53,11 +53,6 @@ public: targetType_ = targetType; } - std::tuple ResolveConditionExpr() const override - { - return {false, false}; - } - void SetRecursive(bool value = true) { isRecursive_ = value; diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index fc29b8b98b..2652ec4908 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -161,6 +161,7 @@ void ETSUnionType::RelationTarget(TypeRelation *relation, Type *source, RelFN co if (relFn(relation, source, checker->MaybeUnboxType(ct))) { if (related) { AmbiguousUnionOperation(relation); + return; } relation->GetNode()->SetBoxingUnboxingFlags(checker->GetBoxingFlag(ct)); related = true; @@ -225,22 +226,7 @@ void ETSUnionType::CastTarget(TypeRelation *relation, Type *source) RelationTarget(relation, source, relFn); } -static auto constexpr ETS_NORMALIZABLE_NUMERIC = TypeFlag(TypeFlag::ETS_NUMERIC); - -static Type *LargestNumeric(Type *t1, Type *t2) -{ - static_assert(TypeFlag::DOUBLE > TypeFlag::FLOAT); - static_assert(TypeFlag::FLOAT > TypeFlag::LONG); - static_assert(TypeFlag::LONG > TypeFlag::INT); - static_assert(TypeFlag::INT > TypeFlag::SHORT); - static_assert(TypeFlag::SHORT > TypeFlag::BYTE); - - auto v1 = t1->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; - auto v2 = t2->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; - ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v1)); - ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v2)); - return v1 > v2 ? t1 : t2; -} +static auto constexpr ETS_NORMALIZABLE_NUMERIC = TypeFlag(TypeFlag::ETS_INTEGRAL_NUMERIC); static std::optional TryMergeTypes(TypeRelation *relation, Type *const t1, Type *const t2) { @@ -310,9 +296,29 @@ void ETSUnionType::NormalizeTypes(TypeRelation *relation, ArenaVector &t if (types.size() == 1) { return; } - auto const isNumeric = [](auto *ct) { return ct->HasTypeFlag(ETS_NORMALIZABLE_NUMERIC); }; + auto const isNumeric = [relation](auto *ct) { + auto *checker = relation->GetChecker()->AsETSChecker(); + return checker->MaybeUnboxType(ct)->HasTypeFlag(ETS_NORMALIZABLE_NUMERIC); + }; + // CC-OFFNXT(G.FMT.14-CPP) project code style + auto const largerNumeric = [relation](Type *t1, Type *t2) -> Type * { + static_assert(TypeFlag::LONG > TypeFlag::INT); + static_assert(TypeFlag::INT > TypeFlag::SHORT); + static_assert(TypeFlag::SHORT > TypeFlag::BYTE); + + auto *checker = relation->GetChecker()->AsETSChecker(); + auto *unboxedT1 = checker->MaybeUnboxType(t1); + auto *unboxedT2 = checker->MaybeUnboxType(t2); + + auto v1 = unboxedT1->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; + auto v2 = unboxedT2->TypeFlags() & ETS_NORMALIZABLE_NUMERIC; + ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v1)); + ES2PANDA_ASSERT(helpers::math::IsPowerOfTwo(v2)); + return v1 > v2 ? t1 : t2; + }; + if (std::all_of(types.begin(), types.end(), isNumeric)) { - types[0] = std::accumulate(std::next(types.begin()), types.end(), types[0], LargestNumeric); + types[0] = std::accumulate(std::next(types.begin()), types.end(), types[0], largerNumeric); types.resize(1); return; } @@ -379,7 +385,8 @@ bool ETSUnionType::IsAssignableType(checker::Type *sourceType) const noexcept // NOTE! When calling this method we assume that 'AssignmentTarget(...)' check was passes successfully, // thus the required assignable type always exists. -checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, checker::Type *sourceType) const noexcept +checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, checker::Type *sourceType, + bool narrowingAllowed) const noexcept { if (IsAssignableType(sourceType)) { return sourceType; @@ -410,7 +417,7 @@ checker::Type *ETSUnionType::GetAssignableType(checker::ETSChecker *checker, che return type; } } - if (sourceType->IsConstantType() && !numericTypes.empty()) { + if (narrowingAllowed && !numericTypes.empty()) { return numericTypes.begin()->second; } } @@ -705,19 +712,6 @@ Type *ETSUnionType::FindExactOrBoxedType(ETSChecker *checker, Type *const type) return nullptr; } -std::tuple ETSUnionType::ResolveConditionExpr() const -{ - if (PossiblyETSString()) { - return {false, false}; - } - if (std::all_of(ConstituentTypes().begin(), ConstituentTypes().end(), - [](checker::Type const *ct) { return ct->DefinitelyETSNullish(); })) { - return {true, false}; - } - // We have to test if union can contain builtin numerics or string types to infer "true" - return {false, false}; -} - bool ETSUnionType::HasType(Type *type) const { for (const auto &cType : constituentTypes_) { diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index d38376a8f8..5cbf51a099 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -60,8 +60,6 @@ public: static ArenaVector GetNonConstantTypes(ETSChecker *checker, const ArenaVector &types); - std::tuple ResolveConditionExpr() const override; - // Do not use it anywhere except codegen Type *GetAssemblerLUB() const { @@ -74,7 +72,8 @@ public: return std::all_of(constituentTypes_.cbegin(), constituentTypes_.cend(), p); } - [[nodiscard]] checker::Type *GetAssignableType(ETSChecker *checker, checker::Type *sourceType) const noexcept; + [[nodiscard]] checker::Type *GetAssignableType(ETSChecker *checker, checker::Type *sourceType, + bool narrowingAllowed) const noexcept; [[nodiscard]] std::pair GetComplimentaryType(ETSChecker *checker, checker::Type *sourceType); diff --git a/ets2panda/checker/types/ets/etsVoidType.cpp b/ets2panda/checker/types/ets/etsVoidType.cpp index bb3e90fb25..0fe7ede620 100644 --- a/ets2panda/checker/types/ets/etsVoidType.cpp +++ b/ets2panda/checker/types/ets/etsVoidType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2024 Huawei Device Co., Ltd. + * Copyright (c) 2021 - 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -23,6 +23,11 @@ void ETSVoidType::Identical(TypeRelation *relation, Type *other) } } +void ETSVoidType::IsSupertypeOf(TypeRelation *const relation, Type *source) +{ + relation->Result(source->IsETSUndefinedType()); +} + bool ETSVoidType::AssignmentSource(TypeRelation *relation, Type *target) { // NOTE(vpukhov): #19701 void refactoring diff --git a/ets2panda/checker/types/ets/etsVoidType.h b/ets2panda/checker/types/ets/etsVoidType.h index bf6f9fcf7f..845d638d89 100644 --- a/ets2panda/checker/types/ets/etsVoidType.h +++ b/ets2panda/checker/types/ets/etsVoidType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -26,6 +26,7 @@ public: void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; bool AssignmentSource(TypeRelation *relation, Type *target) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override diff --git a/ets2panda/checker/types/ets/floatType.h b/ets2panda/checker/types/ets/floatType.h index 61f04f8e0b..936effb4b0 100644 --- a/ets2panda/checker/types/ets/floatType.h +++ b/ets2panda/checker/types/ets/floatType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,12 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_FLOAT; } - std::tuple ResolveConditionExpr() const override - { - // isNan = !(value_ == value_) - return {IsConstantType(), (value_ != 0) && (value_ == value_)}; - } - private: UType value_ {0.0}; }; diff --git a/ets2panda/checker/types/ets/intType.h b/ets2panda/checker/types/ets/intType.h index b1583a8695..835cc47d61 100644 --- a/ets2panda/checker/types/ets/intType.h +++ b/ets2panda/checker/types/ets/intType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_INT; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/longType.h b/ets2panda/checker/types/ets/longType.h index 898b692072..0823bc7608 100644 --- a/ets2panda/checker/types/ets/longType.h +++ b/ets2panda/checker/types/ets/longType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_LONG; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/shortType.h b/ets2panda/checker/types/ets/shortType.h index 0cbd73ab16..4b226806a3 100644 --- a/ets2panda/checker/types/ets/shortType.h +++ b/ets2panda/checker/types/ets/shortType.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -52,11 +52,6 @@ public: ss << compiler::Signatures::TYPE_DESCRIPTOR_SHORT; } - std::tuple ResolveConditionExpr() const override - { - return {IsConstantType(), value_ != 0}; - } - private: UType value_ {0}; }; diff --git a/ets2panda/checker/types/ets/types.h b/ets2panda/checker/types/ets/types.h index 89d59b801e..7a731779e5 100644 --- a/ets2panda/checker/types/ets/types.h +++ b/ets2panda/checker/types/ets/types.h @@ -41,5 +41,6 @@ #include "checker/types/signature.h" #include "etsReadonlyType.h" #include "etsNeverType.h" +#include "etsEnumType.h" #endif /* TYPES_H */ diff --git a/ets2panda/checker/types/globalTypesHolder.cpp b/ets2panda/checker/types/globalTypesHolder.cpp index 2644c1b719..dcada0dd73 100644 --- a/ets2panda/checker/types/globalTypesHolder.cpp +++ b/ets2panda/checker/types/globalTypesHolder.cpp @@ -164,6 +164,7 @@ void GlobalTypesHolder::AddEtsSpecificBuiltinTypes() builtinNameMappings_.emplace("Int", GlobalTypeId::ETS_INT_BUILTIN); builtinNameMappings_.emplace("Integral", GlobalTypeId::ETS_INTEGRAL_BUILTIN); builtinNameMappings_.emplace("Long", GlobalTypeId::ETS_LONG_BUILTIN); + builtinNameMappings_.emplace("Numeric", GlobalTypeId::ETS_NUMERIC_BUILTIN); builtinNameMappings_.emplace("Object", GlobalTypeId::ETS_OBJECT_BUILTIN); builtinNameMappings_.emplace("Runtime", GlobalTypeId::ETS_RUNTIME_BUILTIN); builtinNameMappings_.emplace("RuntimeLinker", GlobalTypeId::ETS_RUNTIME_LINKER_BUILTIN); @@ -482,6 +483,11 @@ Type *GlobalTypesHolder::GlobalLongBuiltinType() return globalTypes_.at(static_cast(GlobalTypeId::ETS_LONG_BUILTIN)); } +Type *GlobalTypesHolder::GlobalNumericBuiltinType() +{ + return globalTypes_.at(static_cast(GlobalTypeId::ETS_NUMERIC_BUILTIN)); +} + Type *GlobalTypesHolder::GlobalMapBuiltinType() { return globalTypes_.at(static_cast(GlobalTypeId::ETS_MAP_BUILTIN)); diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index cd5e023539..5f68b3fbb3 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -74,6 +74,7 @@ enum class GlobalTypeId : std::size_t { ETS_INT_BUILTIN, ETS_INTEGRAL_BUILTIN, ETS_LONG_BUILTIN, + ETS_NUMERIC_BUILTIN, ETS_MAP_BUILTIN, ETS_ERROR_BUILTIN, ETS_RUNTIME_BUILTIN, @@ -282,6 +283,7 @@ public: Type *GlobalIntegerBuiltinType(); Type *GlobalIntegralBuiltinType(); Type *GlobalLongBuiltinType(); + Type *GlobalNumericBuiltinType(); Type *GlobalErrorBuiltinType(); Type *GlobalRuntimeBuiltinType(); Type *GlobalShortBuiltinType(); diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index 34b2d8a74e..0983219efb 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -217,7 +217,9 @@ static bool MethodSignaturesAreCompatible(TypeRelation *relation, bool checkIden } auto const areCompatible = [relation, checkIdentical](Type *superT, Type *subT) { - return checkIdentical ? relation->IsIdenticalTo(superT, subT) : relation->IsSupertypeOf(superT, subT); + return checkIdentical + ? superT->IsETSTypeParameter() || subT->IsETSTypeParameter() || relation->IsIdenticalTo(superT, subT) + : relation->IsSupertypeOf(superT, subT); }; if (!relation->NoReturnTypeCheck() && !areCompatible(super->ReturnType(), sub->ReturnType())) { return false; diff --git a/ets2panda/checker/types/signature.h b/ets2panda/checker/types/signature.h index 2a4f8ec06d..d94e607e8b 100644 --- a/ets2panda/checker/types/signature.h +++ b/ets2panda/checker/types/signature.h @@ -90,6 +90,7 @@ enum class SignatureFlags : uint32_t { RETHROWS = 1U << 17U, EXTENSION_FUNCTION = 1U << 18U, DUPLICATE_ASM = 1U << 19U, + BRIDGE = 1U << 20U, INTERNAL_PROTECTED = INTERNAL | PROTECTED, GETTER_OR_SETTER = GETTER | SETTER, @@ -223,6 +224,11 @@ public: return signatureInfo_->restVar; } + [[nodiscard]] varbinder::LocalVariable *RestVar() noexcept + { + return signatureInfo_->restVar; + } + [[nodiscard]] uint8_t ProtectionFlag() const noexcept { if ((flags_ & SignatureFlags::PRIVATE) != 0) { diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index 1a0895b37a..2a0d79af85 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -267,15 +267,24 @@ public: ToAssemblerType(ss); } - virtual uint32_t Rank() const + std::string ToAssemblerType() const { - return 0; + std::stringstream ss; + ToAssemblerType(ss); + return ss.str(); } - virtual std::tuple ResolveConditionExpr() const + std::string ToAssemblerTypeWithRank() const { - ES2PANDA_UNREACHABLE(); - }; + std::stringstream ss; + ToAssemblerTypeWithRank(ss); + return ss.str(); + } + + virtual uint32_t Rank() const + { + return 0; + } virtual void Identical(TypeRelation *relation, Type *other); virtual void AssignmentTarget(TypeRelation *relation, Type *source) = 0; diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index 5f59255974..5b66e1c63d 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -204,20 +204,58 @@ bool TypeRelation::IsCastableTo(Type *const source, Type *const target) return result_ == RelationResult::TRUE; } +Type *TypeRelation::SelectBoxedUnionTargetType(Type *target, Type *source) +{ + ETSChecker *checker = this->GetChecker()->AsETSChecker(); + + if (!target->IsETSUnionType() || !source->IsETSObjectType()) { + return nullptr; + } + Type *boxedUnionTarget = target->AsETSUnionType()->FindUnboxableType(); + if (boxedUnionTarget == nullptr) { + return nullptr; + } + Type *targetUnboxedType = checker->MaybeUnboxType(boxedUnionTarget); + if (targetUnboxedType == nullptr || !targetUnboxedType->IsETSPrimitiveType()) { + return nullptr; + } + // if + return boxedUnionTarget; +} + bool TypeRelation::IsLegalBoxedPrimitiveConversion(Type *target, Type *source) { - if (!target->IsETSReferenceType() || !source->IsETSReferenceType()) { + auto type = this->GetNode()->TsType(); + ETSChecker *checker = this->GetChecker()->AsETSChecker(); + + if (target == nullptr || source == nullptr) { return false; } + + if (target->IsETSUnionType() && source->IsETSObjectType()) { + Type *sourceUnboxedType = checker->MaybeUnboxType(source); + if (sourceUnboxedType == nullptr || !sourceUnboxedType->IsETSPrimitiveType()) { + return false; + } + Type *boxedUnionTarget = target->AsETSUnionType()->FindUnboxableType(); + if (boxedUnionTarget == nullptr) { + return false; + } + Type *targetUnboxedType = checker->MaybeUnboxType(boxedUnionTarget); + if (targetUnboxedType == nullptr || !targetUnboxedType->IsETSPrimitiveType()) { + return false; + } + return this->Result(this->IsAssignableTo(sourceUnboxedType, target)); + } + if (!target->IsETSObjectType() || !source->IsETSObjectType()) { return false; } + if (!target->AsETSObjectType()->IsBoxedPrimitive() || !source->AsETSObjectType()->IsBoxedPrimitive()) { return false; } - ETSChecker *checker = this->GetChecker()->AsETSChecker(); - Type *targetUnboxedType = checker->MaybeUnboxType(target); Type *sourceUnboxedType = checker->MaybeUnboxType(source); @@ -228,7 +266,9 @@ bool TypeRelation::IsLegalBoxedPrimitiveConversion(Type *target, Type *source) return false; } - return this->Result(this->IsAssignableTo(sourceUnboxedType, targetUnboxedType)); + bool res = this->Result(this->IsAssignableTo(sourceUnboxedType, targetUnboxedType)); + this->GetNode()->SetTsType(type); + return res; } bool TypeRelation::IsSupertypeOf(Type *super, Type *sub) diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index 4fadbde95e..f71f472980 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -63,9 +63,10 @@ enum class TypeRelationFlag : uint32_t { OVERRIDING_CONTEXT = 1U << 25U, IGNORE_REST_PARAM = 1U << 26U, STRING_TO_CHAR = 1U << 27U, + OVERLOADING_CONTEXT = 1U << 28U, ASSIGNMENT_CONTEXT = WIDENING | BOXING | UNBOXING, - BRIDGE_CHECK = OVERRIDING_CONTEXT | IGNORE_TYPE_PARAMETERS | NO_RETURN_TYPE_CHECK, + BRIDGE_CHECK = OVERRIDING_CONTEXT | IGNORE_TYPE_PARAMETERS, CASTING_CONTEXT = NARROWING | WIDENING | BOXING | UNBOXING | UNCHECKED_CAST, }; @@ -297,6 +298,7 @@ public: { return IsSupertypeOf(const_cast(super), const_cast(sub)); } + Type *SelectBoxedUnionTargetType(Type *target, Type *source); bool IsLegalBoxedPrimitiveConversion(Type *target, Type *source); bool IsSupertypeOf(Type *super, Type *sub); bool IsIdenticalTo(IndexInfo *source, IndexInfo *target); diff --git a/ets2panda/compiler/base/condition.cpp b/ets2panda/compiler/base/condition.cpp index c8a7d0de4d..db9afc1790 100644 --- a/ets2panda/compiler/base/condition.cpp +++ b/ets2panda/compiler/base/condition.cpp @@ -15,6 +15,7 @@ #include "condition.h" +#include "checker/ETSAnalyzerHelpers.h" #include "compiler/core/pandagen.h" #include "compiler/core/ETSGen.h" #include "ir/expressions/assignmentExpression.h" diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 0affcc5bc9..b4fdea643f 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -334,6 +334,11 @@ void ETSCompiler::Compile(const ir::ETSTypeReferencePart *node) const ES2PANDA_ASSERT(etsg->Checker()->Relation()->IsIdenticalTo(etsg->GetAccumulatorType(), node->TsType())); } +void ETSCompiler::Compile(const ir::OpaqueTypeNode *node) const +{ + GetETSGen()->SetAccumulatorType(node->TsType()); +} + void ETSCompiler::Compile([[maybe_unused]] const ir::ETSWildcardType *node) const { ES2PANDA_UNREACHABLE(); @@ -1524,6 +1529,7 @@ void ETSCompiler::Compile(const ir::VariableDeclarator *st) const etsg->LoadDefaultValue(st, st->Id()->AsIdentifier()->Variable()->TsType()); } + // ????????????????????????????????????? is this meaningfull???? etsg->ApplyConversion(st, st->TsType()); lref.SetValue(); } diff --git a/ets2panda/compiler/core/ETSCompilerUnrechable.cpp b/ets2panda/compiler/core/ETSCompilerUnrechable.cpp index 3f3908e820..26d98fa12f 100644 --- a/ets2panda/compiler/core/ETSCompilerUnrechable.cpp +++ b/ets2panda/compiler/core/ETSCompilerUnrechable.cpp @@ -188,11 +188,6 @@ void ETSCompiler::Compile([[maybe_unused]] const ir::OmittedExpression *expr) co ES2PANDA_UNREACHABLE(); } -void ETSCompiler::Compile([[maybe_unused]] const ir::OpaqueTypeNode *node) const -{ - ES2PANDA_UNREACHABLE(); -} - void ETSCompiler::Compile([[maybe_unused]] const ir::BrokenTypeNode *node) const { ES2PANDA_UNREACHABLE(); diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index ea7f55889c..fb19731ee5 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -807,7 +807,7 @@ void ETSGen::TestIsInstanceConstituent(const ir::AstNode *const node, std::tuple ES2PANDA_ASSERT(!target->IsETSDynamicType()); auto [ifTrue, ifFalse] = label; - if (target->IsConstantType()) { + if (target->IsConstantType() && (target->IsETSBigIntType() || target->IsETSStringType())) { TestIsInstanceConstant(node, ifTrue, srcReg, target); return; } @@ -1006,6 +1006,13 @@ void ETSGen::GuardUncheckedType(const ir::AstNode *node, const checker::Type *un SetAccumulatorType(unchecked); // this check guards possible type violations, **do not relax it** CheckedReferenceNarrowing(node, Checker()->MaybeBoxType(target)); + // Because on previos step accumulator type may be set in CheckerReferenceNarrowing to boxed countepart of + // target We need to apply unbox conversion if needed to avoid RTE + if (target->IsETSPrimitiveType() && GetAccumulatorType()->IsETSUnboxableObject()) { + // NOTE: need to refactor + node->AddBoxingUnboxingFlags(Checker()->GetUnboxingFlag(target)); + ApplyConversion(node, target); + } } SetAccumulatorType(target); } @@ -1024,14 +1031,16 @@ void ETSGen::EmitFailedTypeCastException(const ir::AstNode *node, const VReg src void ETSGen::LoadConstantObject(const ir::Expression *node, const checker::Type *type) { - if (type->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL)) { + if (type->IsETSBigIntType()) { LoadAccumulatorBigInt(node, type->AsETSObjectType()->AsETSBigIntType()->GetValue()); const VReg value = AllocReg(); StoreAccumulator(node, value); CreateBigIntObject(node, value); - } else { + } else if (type->IsETSStringType()) { LoadAccumulatorString(node, type->AsETSObjectType()->AsETSStringType()->GetValue()); SetAccumulatorType(node->TsType()); + } else { + ES2PANDA_UNREACHABLE(); } } @@ -1315,6 +1324,8 @@ void ETSGen::EmitBoxingConversion(const ir::AstNode *node) auto boxedType = const_cast(GetAccumulatorType()); const_cast(node->AsExpression())->SetTsType(boxedType); } + + node->RemoveBoxingUnboxingFlags(boxingFlag); } void ETSGen::SwapBinaryOpArgs(const ir::AstNode *const node, const VReg lhs) @@ -1700,9 +1711,13 @@ void ETSGen::CastToInt(const ir::AstNode *node) void ETSGen::CastToReftype(const ir::AstNode *const node, const checker::Type *const targetType, const bool unchecked) { - ES2PANDA_ASSERT(GetAccumulatorType()->IsETSReferenceType()); - const auto *const sourceType = GetAccumulatorType(); + // sourceType can be either RefType or CharType + ES2PANDA_ASSERT(sourceType->IsETSReferenceType() || sourceType->IsCharType()); + if (sourceType->IsCharType()) { + // NOTE: temporary flag have to be set for CastToString + node->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR); + } if (sourceType->IsETSDynamicType()) { CastDynamicToObject(node, targetType); @@ -1806,6 +1821,7 @@ void ETSGen::CastToString(const ir::AstNode *const node) SetAccumulatorType(Checker()->GetGlobalTypesHolder()->GlobalETSStringBuiltinType()); } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic, big switch case void ETSGen::CastToDynamic(const ir::AstNode *node, const checker::ETSDynamicType *type) { std::string_view methodName {}; @@ -1841,6 +1857,12 @@ void ETSGen::CastToDynamic(const ir::AstNode *node, const checker::ETSDynamicTyp case checker::TypeFlag::ETS_TUPLE: methodName = compiler::Signatures::Dynamic::NewObjectBuiltin(type->Language()); break; + case checker::TypeFlag::ETS_UNDEFINED: + methodName = compiler::Signatures::Dynamic::GetUndefinedBuiltin(type->Language()); + break; + case checker::TypeFlag::ETS_NULL: + methodName = compiler::Signatures::Dynamic::GetNullBuiltin(type->Language()); + break; case checker::TypeFlag::ETS_DYNAMIC_TYPE: SetAccumulatorType(type); return; @@ -2646,15 +2668,6 @@ void ETSGen::RefEqualityLoose(const ir::AstNode *node, VReg lhs, VReg rhs, Label if (ltype->DefinitelyETSNullish() || rtype->DefinitelyETSNullish()) { HandleDefinitelyNullishEquality(node, lhs, rhs, ifFalse); - } else if (!ltype->PossiblyETSValueTypedExceptNullish() || !rtype->PossiblyETSValueTypedExceptNullish()) { - auto ifTrue = AllocLabel(); - if ((ltype->PossiblyETSUndefined() && rtype->PossiblyETSNull()) || - (rtype->PossiblyETSUndefined() && ltype->PossiblyETSNull())) { - HandlePossiblyNullishEquality(node, lhs, rhs, ifFalse, ifTrue); - } - LoadAccumulator(node, lhs); - Ra().Emit(node, rhs, ifFalse); - SetLabel(node, ifTrue); } else if (auto spec = SelectLooseObjComparator( // try to select specific type // CC-OFFNXT(G.FMT.06-CPP) project code style const_cast(Checker()), const_cast(ltype), diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index f759d97a55..e15be4dfc7 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -26,8 +26,6 @@ #include "ir/base/scriptFunction.h" #include "ir/base/classProperty.h" #include "ir/statements/annotationDeclaration.h" -#include "ir/ts/tsEnumDeclaration.h" -#include "ir/ts/tsEnumMember.h" #include "ir/ts/tsInterfaceDeclaration.h" #include "ir/ts/tsInterfaceBody.h" #include "ir/ts/tsTypeParameterDeclaration.h" @@ -341,37 +339,53 @@ void ETSEmitter::GenExternalRecord(varbinder::RecordTable *recordTable, const pa } // Helper function to reduce EmitDefaultFieldValue size and pass code check -static pandasm::ScalarValue CreateScalarValue(const checker::Type *type, checker::TypeFlag typeKind) +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic, big switch case +static pandasm::ScalarValue CreateScalarValue(ir::Literal const *literal, checker::TypeFlag typeKind) { switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: { + ES2PANDA_ASSERT(literal->IsBooleanLiteral()); return pandasm::ScalarValue::Create( - static_cast(type->AsETSBooleanType()->GetValue())); + static_cast(literal->AsBooleanLiteral()->Value())); } case checker::TypeFlag::BYTE: { - return pandasm::ScalarValue::Create(type->AsByteType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsByte()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetByte()); } case checker::TypeFlag::SHORT: { - return pandasm::ScalarValue::Create(type->AsShortType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsShort()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetShort()); } case checker::TypeFlag::INT: { - return pandasm::ScalarValue::Create(type->AsIntType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsInt()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetInt()); } case checker::TypeFlag::LONG: { - return pandasm::ScalarValue::Create(type->AsLongType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsLong()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetLong()); } case checker::TypeFlag::FLOAT: { - return pandasm::ScalarValue::Create(type->AsFloatType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsFloat()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetFloat()); } case checker::TypeFlag::DOUBLE: { - return pandasm::ScalarValue::Create(type->AsDoubleType()->GetValue()); + ES2PANDA_ASSERT(literal->IsNumberLiteral() && literal->AsNumberLiteral()->Number().IsDouble()); + return pandasm::ScalarValue::Create( + literal->AsNumberLiteral()->Number().GetDouble()); } case checker::TypeFlag::CHAR: { - return pandasm::ScalarValue::Create(type->AsCharType()->GetValue()); + ES2PANDA_ASSERT(literal->IsCharLiteral()); + return pandasm::ScalarValue::Create(literal->AsCharLiteral()->Char()); } case checker::TypeFlag::ETS_OBJECT: { + ES2PANDA_ASSERT(literal->IsStringLiteral()); return pandasm::ScalarValue::Create( - type->AsETSObjectType()->AsETSStringType()->GetValue().Mutf8()); + literal->AsStringLiteral()->Str().Mutf8()); } default: { ES2PANDA_UNREACHABLE(); @@ -381,19 +395,14 @@ static pandasm::ScalarValue CreateScalarValue(const checker::Type *type, checker void ETSEmitter::EmitDefaultFieldValue(pandasm::Field &classField, const ir::Expression *init) { - if (init == nullptr) { + if (init == nullptr || !init->IsLiteral()) { return; } const auto *type = init->TsType(); - - if (!type->HasTypeFlag(checker::TypeFlag::CONSTANT)) { - return; - } - auto typeKind = checker::ETSChecker::TypeKind(type); classField.metadata->SetFieldType(classField.type); - classField.metadata->SetValue(CreateScalarValue(type, typeKind)); + classField.metadata->SetValue(CreateScalarValue(init->AsLiteral(), typeKind)); } void ETSEmitter::GenInterfaceMethodDefinition(const ir::MethodDefinition *methodDef, bool external) @@ -610,32 +619,6 @@ void ETSEmitter::GenClassRecord(const ir::ClassDefinition *classDef, bool extern Program()->recordTable.emplace(classRecord.name, std::move(classRecord)); } -// Helper function to check if the unary expression is a numeric literal with negation. -// This expression should be handled during lowering with the associated issue number. -static bool IsNegativeLiteralNode(const ir::UnaryExpression *expr) -{ - return expr->OperatorType() == lexer::TokenType::PUNCTUATOR_MINUS && expr->Argument()->IsNumberLiteral(); -} - -void ETSEmitter::CreateEnumProp(const ir::ClassProperty *prop, pandasm::Field &field) -{ - if (prop->Value() == nullptr) { - return; - } - field.metadata->SetFieldType(field.type); - auto declNode = prop->Value()->AsMemberExpression()->PropVar()->Declaration()->Node(); - auto *init = declNode->AsClassProperty()->OriginEnumMember()->Init(); - if (init->IsNumberLiteral()) { - auto value = init->AsNumberLiteral()->Number().GetInt(); - field.metadata->SetValue(pandasm::ScalarValue::Create(value)); - } else if (init->IsStringLiteral()) { - auto value = init->AsStringLiteral()->Str().Mutf8(); - field.metadata->SetValue(pandasm::ScalarValue::Create(value)); - } else { - ES2PANDA_UNREACHABLE(); - } -} - void ETSEmitter::ProcessArrayExpression( std::string &baseName, std::vector>> &result, std::vector &literals, const ir::Expression *elem) @@ -652,68 +635,53 @@ void ETSEmitter::ProcessArrayExpression( } } -static void ProcessEnumExpression(std::vector &literals, const ir::Expression *elem) -{ - auto *memberExpr = elem->IsCallExpression() ? elem->AsCallExpression()->Arguments()[0]->AsMemberExpression() - : elem->AsMemberExpression(); - auto *init = memberExpr->PropVar()->Declaration()->Node()->AsClassProperty()->OriginEnumMember()->Init(); - if (init->IsNumberLiteral()) { - auto enumValue = static_cast(init->AsNumberLiteral()->Number().GetInt()); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::TAGVALUE, - static_cast(panda_file::LiteralTag::INTEGER)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::INTEGER, enumValue}); - } else { - auto enumValue = init->AsStringLiteral()->Str().Mutf8(); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::TAGVALUE, - static_cast(panda_file::LiteralTag::STRING)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, enumValue}); - } -} - void ETSEmitter::ProcessArrayElement(const ir::Expression *elem, std::vector &literals, std::string &baseName, LiteralArrayVector &result) { - switch (elem->Type()) { - case ir::AstNodeType::NUMBER_LITERAL: { - auto doubleValue = elem->AsNumberLiteral()->Number().GetDouble(); - literals.emplace_back(pandasm::LiteralArray::Literal { - panda_file::LiteralTag::TAGVALUE, static_cast(panda_file::LiteralTag::DOUBLE)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::DOUBLE, doubleValue}); + ES2PANDA_ASSERT(elem->IsLiteral() || elem->IsArrayExpression()); + auto emplaceLiteral = [&literals](panda_file::LiteralTag tag, auto value) { + literals.emplace_back( + pandasm::LiteralArray::Literal {panda_file::LiteralTag::TAGVALUE, static_cast(tag)}); + literals.emplace_back(pandasm::LiteralArray::Literal {tag, value}); + }; + // NOTE(dkofanov): Why 'LiteralTag::ARRAY_*'-types isn't used? + switch (checker::ETSChecker::TypeKind(elem->TsType())) { + case checker::TypeFlag::ETS_BOOLEAN: { + emplaceLiteral(panda_file::LiteralTag::BOOL, elem->AsBooleanLiteral()->Value()); break; } - case ir::AstNodeType::BOOLEAN_LITERAL: { - bool boolValue = elem->AsBooleanLiteral()->Value(); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::TAGVALUE, - static_cast(panda_file::LiteralTag::BOOL)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::BOOL, boolValue}); + case checker::TypeFlag::CHAR: + case checker::TypeFlag::BYTE: + case checker::TypeFlag::SHORT: + case checker::TypeFlag::INT: { + emplaceLiteral(panda_file::LiteralTag::INTEGER, + static_cast(elem->AsNumberLiteral()->Number().GetInt())); break; } - case ir::AstNodeType::STRING_LITERAL: { - std::string stringValue {elem->AsStringLiteral()->Str().Utf8()}; - literals.emplace_back(pandasm::LiteralArray::Literal { - panda_file::LiteralTag::TAGVALUE, static_cast(panda_file::LiteralTag::STRING)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, stringValue}); + case checker::TypeFlag::LONG: { + emplaceLiteral(panda_file::LiteralTag::BIGINT, + static_cast(elem->AsNumberLiteral()->Number().GetInt())); break; } - case ir::AstNodeType::ARRAY_EXPRESSION: { - ProcessArrayExpression(baseName, result, literals, elem); + case checker::TypeFlag::FLOAT: { + emplaceLiteral(panda_file::LiteralTag::FLOAT, elem->AsNumberLiteral()->Number().GetFloat()); break; } - case ir::AstNodeType::MEMBER_EXPRESSION: - case ir::AstNodeType::CALL_EXPRESSION: { - ProcessEnumExpression(literals, elem); + case checker::TypeFlag::DOUBLE: { + emplaceLiteral(panda_file::LiteralTag::DOUBLE, elem->AsNumberLiteral()->Number().GetDouble()); break; } - case ir::AstNodeType::UNARY_EXPRESSION: { - double doubleValue = (-1) * elem->AsUnaryExpression()->Argument()->AsNumberLiteral()->Number().GetDouble(); - literals.emplace_back(pandasm::LiteralArray::Literal { - panda_file::LiteralTag::TAGVALUE, static_cast(panda_file::LiteralTag::DOUBLE)}); - literals.emplace_back(pandasm::LiteralArray::Literal {panda_file::LiteralTag::DOUBLE, doubleValue}); + case checker::TypeFlag::ETS_OBJECT: { + emplaceLiteral(panda_file::LiteralTag::STRING, elem->AsStringLiteral()->ToString()); break; } - default: - ES2PANDA_UNREACHABLE(); + case checker::TypeFlag::ETS_ARRAY: { + ProcessArrayExpression(baseName, result, literals, elem); break; + } + default: { + ES2PANDA_UNREACHABLE(); + } } } @@ -742,13 +710,9 @@ void ETSEmitter::CreateLiteralArrayProp(const ir::ClassProperty *prop, std::stri ++rank; elemType = checker->GetElementTypeOfArray(elemType); } - if (elemType->IsETSEnumType()) { - field.type = PandasmTypeWithRank(elemType, rank); - } else { - std::stringstream ss; - elemType->ToAssemblerType(ss); - field.type = pandasm::Type(ss.str(), rank); - } + std::stringstream ss; + elemType->ToAssemblerType(ss); + field.type = pandasm::Type(ss.str(), rank); auto value = prop->Value(); if (value != nullptr) { @@ -773,8 +737,6 @@ void ETSEmitter::GenCustomAnnotationProp(const ir::ClassProperty *prop, std::str if (external) { field.metadata->SetAttribute(Signatures::EXTERNAL); - } else if (type->IsETSEnumType()) { - CreateEnumProp(prop, field); } else if (type->IsETSPrimitiveType() || type->IsETSStringType()) { EmitDefaultFieldValue(field, prop->Value()); } else if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { @@ -823,22 +785,6 @@ pandasm::AnnotationElement ETSEmitter::ProcessArrayType(const ir::ClassProperty std::string_view {litArrays.back().first}))}; } -pandasm::AnnotationElement ETSEmitter::ProcessETSEnumType(std::string &baseName, const ir::Expression *init, - const checker::Type *type) -{ - auto declNode = init->AsMemberExpression()->PropVar()->Declaration()->Node(); - auto *initValue = declNode->AsClassProperty()->OriginEnumMember()->Init(); - if (type->IsETSIntEnumType()) { - auto enumValue = static_cast(initValue->AsNumberLiteral()->Number().GetInt()); - auto intEnumValue = pandasm::ScalarValue::Create(enumValue); - return pandasm::AnnotationElement {baseName, std::make_unique(intEnumValue)}; - } - ES2PANDA_ASSERT(type->IsETSStringEnumType()); - auto enumValue = initValue->AsStringLiteral()->Str().Mutf8(); - auto stringValue = pandasm::ScalarValue::Create(enumValue); - return pandasm::AnnotationElement {baseName, std::make_unique(stringValue)}; -} - pandasm::AnnotationElement ETSEmitter::GenCustomAnnotationElement(const ir::ClassProperty *prop, std::string &baseName) { const auto *init = prop->Value(); @@ -848,33 +794,13 @@ pandasm::AnnotationElement ETSEmitter::GenCustomAnnotationElement(const ir::Clas if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { return ProcessArrayType(prop, baseName, init); } - - if (type->IsETSEnumType()) { - return ProcessETSEnumType(baseName, init, type); - } - switch (checker::ETSChecker::TypeKind( - Context()->checker->AsETSChecker()->MaybeUnboxType(const_cast(type)))) { - case checker::TypeFlag::BYTE: - case checker::TypeFlag::SHORT: - case checker::TypeFlag::INT: - case checker::TypeFlag::LONG: - case checker::TypeFlag::FLOAT: - case checker::TypeFlag::DOUBLE: - case checker::TypeFlag::ETS_BOOLEAN: - case checker::TypeFlag::ETS_OBJECT: { - if (init->IsUnaryExpression() && IsNegativeLiteralNode(init->AsUnaryExpression())) { - double negNumberValue = - (-1) * init->AsUnaryExpression()->Argument()->AsNumberLiteral()->Number().GetDouble(); - return pandasm::AnnotationElement { - propName, std::make_unique( - pandasm::ScalarValue::Create(negNumberValue))}; - } - return pandasm::AnnotationElement { - propName, std::make_unique(CreateScalarValue(init->TsType(), typeKind))}; - } - default: - ES2PANDA_UNREACHABLE(); + if (init->IsLiteral()) { + auto typeKind = checker::ETSChecker::TypeKind(type); + auto propName = prop->Id()->Name().Mutf8(); + return pandasm::AnnotationElement { + propName, std::make_unique(CreateScalarValue(init->AsLiteral(), typeKind))}; } + ES2PANDA_UNREACHABLE(); } pandasm::AnnotationData ETSEmitter::GenCustomAnnotation(ir::AnnotationUsage *anno, std::string &baseName) @@ -1018,32 +944,37 @@ ir::MethodDefinition *ETSEmitter::FindAsyncImpl(ir::ScriptFunction *asyncFunc) const ir::ClassDefinition *classDef = ownerNode->AsClassDefinition(); ES2PANDA_ASSERT(classDef != nullptr); - auto it = - std::find_if(classDef->Body().rbegin(), classDef->Body().rend(), [&implName, &asyncFunc](ir::AstNode *node) { - if (!node->IsMethodDefinition()) { - return false; - } - bool isSameName = node->AsMethodDefinition()->Id()->Name().Utf8() == implName; - bool isBothStaticOrInstance = - (node->Modifiers() & ir::ModifierFlags::STATIC) == (asyncFunc->Modifiers() & ir::ModifierFlags::STATIC); - return isSameName && isBothStaticOrInstance; - }); - if (it == classDef->Body().rend()) { + ir::MethodDefinition *method = nullptr; + for (auto node : classDef->Body()) { + if (!node->IsMethodDefinition()) { + continue; + } + bool isSameName = node->AsMethodDefinition()->Id()->Name().Utf8() == implName; + bool isBothStaticOrInstance = + (node->Modifiers() & ir::ModifierFlags::STATIC) == (asyncFunc->Modifiers() & ir::ModifierFlags::STATIC); + if (isSameName && isBothStaticOrInstance) { + method = node->AsMethodDefinition(); + break; + } + } + if (method == nullptr) { return nullptr; } - ir::MethodDefinition *method = (*it)->AsMethodDefinition(); auto *checker = static_cast(Context()->checker); checker::TypeRelation *typeRel = checker->Relation(); checker::SavedTypeRelationFlagsContext savedFlagsCtx(typeRel, checker::TypeRelationFlag::NO_RETURN_TYPE_CHECK); method->Function()->Signature()->IsSubtypeOf(typeRel, asyncFunc->Signature()); - auto overloadIt = method->Overloads().begin(); - while (overloadIt != method->Overloads().end() && !typeRel->IsTrue()) { - method = *overloadIt; - method->Function()->Signature()->IsSubtypeOf(typeRel, asyncFunc->Signature()); - ++overloadIt; + if (typeRel->IsTrue()) { + return method; + } + for (auto overload : method->Overloads()) { + overload->Function()->Signature()->IsSubtypeOf(typeRel, asyncFunc->Signature()); + if (typeRel->IsTrue()) { + return overload; + } } - return typeRel->IsTrue() ? method : nullptr; + return nullptr; } pandasm::AnnotationData ETSEmitter::GenAnnotationAsync(ir::ScriptFunction *scriptFunc) diff --git a/ets2panda/compiler/core/ETSemitter.h b/ets2panda/compiler/core/ETSemitter.h index 937d81276a..c41988cadd 100644 --- a/ets2panda/compiler/core/ETSemitter.h +++ b/ets2panda/compiler/core/ETSemitter.h @@ -90,11 +90,8 @@ private: void GenClassRecord(const ir::ClassDefinition *classDef, bool external); pandasm::AnnotationElement ProcessArrayType(const ir::ClassProperty *prop, std::string &baseName, const ir::Expression *init); - pandasm::AnnotationElement ProcessETSEnumType(std::string &baseName, const ir::Expression *init, - const checker::Type *type); pandasm::AnnotationElement GenCustomAnnotationElement(const ir::ClassProperty *prop, std::string &baseName); pandasm::AnnotationData GenCustomAnnotation(ir::AnnotationUsage *anno, std::string &baseName); - void CreateEnumProp(const ir::ClassProperty *prop, pandasm::Field &field); void ProcessArrayElement(const ir::Expression *elem, std::vector &literals, std::string &baseName, LiteralArrayVector &result); LiteralArrayVector CreateLiteralArray(std::string &baseName, const ir::Expression *array); diff --git a/ets2panda/compiler/core/compilerImpl.cpp b/ets2panda/compiler/core/compilerImpl.cpp index b4a76e4e4e..e936e5857a 100644 --- a/ets2panda/compiler/core/compilerImpl.cpp +++ b/ets2panda/compiler/core/compilerImpl.cpp @@ -127,9 +127,14 @@ static bool RunVerifierAndPhases(public_lib::Context &context, parser::Program & const auto verifierEachPhase = options.IsAstVerifierEachPhase(); ast_verifier::ASTVerifier verifier(context, program); + bool afterCheckerPhase = false; while (auto phase = context.phaseManager->NextPhase()) { const auto name = std::string {phase->Name()}; + if (phase->Name() == compiler::CheckerPhase::NAME) { + afterCheckerPhase = true; + } + if (options.GetSkipPhases().count(name) > 0) { continue; } @@ -145,7 +150,7 @@ static bool RunVerifierAndPhases(public_lib::Context &context, parser::Program & } // Stop lowerings processing after Checker phase if any error happened. - if (phase->Name() == compiler::CheckerPhase::NAME && context.diagnosticEngine->IsAnyError()) { + if (afterCheckerPhase && context.diagnosticEngine->IsAnyError()) { return false; } } diff --git a/ets2panda/compiler/lowering/checkerPhase.h b/ets2panda/compiler/lowering/checkerPhase.h index 03b9e6979b..13d9961210 100644 --- a/ets2panda/compiler/lowering/checkerPhase.h +++ b/ets2panda/compiler/lowering/checkerPhase.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -21,7 +21,7 @@ namespace ark::es2panda::compiler { class CheckerPhase : public Phase { public: - static constexpr std::string_view NAME = "CheckerPhase"; + static constexpr std::string_view const NAME = "CheckerPhase"; std::string_view Name() const override { return NAME; diff --git a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp index d801b5526c..52dd7ccbc8 100644 --- a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp +++ b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp @@ -169,6 +169,7 @@ void ComposeAsyncImplMethod(checker::ETSChecker *checker, ir::MethodDefinition * auto *baseOverloadImplMethod = node->BaseOverloadMethod()->AsyncPairMethod(); implMethod->Function()->Id()->SetVariable(baseOverloadImplMethod->Function()->Id()->Variable()); baseOverloadImplMethod->AddOverload(implMethod); + implMethod->SetParent(baseOverloadImplMethod); } else { classDef->Body().push_back(implMethod); } diff --git a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp index 2f63e74222..e5e5c6d78d 100644 --- a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp +++ b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp @@ -134,6 +134,7 @@ static void HandleFunctionParam(public_lib::Context *ctx, ir::ETSParameterExpres auto *initId = allocator->New(id->Name(), allocator); initId->SetVariable(id->Variable()); initId->SetTsType(oldType); + initId->SetRange(id->Range()); // The new variable will have the same name as the parameter. This is not representable in source code. auto *boxedType = checker->GlobalBuiltinBoxType(oldType); @@ -146,6 +147,7 @@ static void HandleFunctionParam(public_lib::Context *ctx, ir::ETSParameterExpres auto *newDeclarator = util::NodeAllocator::ForceSetParent( allocator, ir::VariableDeclaratorFlag::CONST, allocator->New(newVarName.View(), allocator), newInit); + newDeclarator->SetRange(param->Range()); ArenaVector declVec {allocator->Adapter()}; declVec.emplace_back(newDeclarator); @@ -162,6 +164,7 @@ static void HandleFunctionParam(public_lib::Context *ctx, ir::ETSParameterExpres auto *newDeclaration = util::NodeAllocator::ForceSetParent( allocator, ir::VariableDeclaration::VariableDeclarationKind::CONST, allocator, std::move(declVec)); newDeclaration->SetParent(body); + newDeclaration->SetRange(param->Range()); bodyStmts.insert(bodyStmts.begin(), newDeclaration); auto lexScope = varbinder::LexicalScope::Enter(varBinder, scope); @@ -192,6 +195,8 @@ static ir::AstNode *HandleVariableDeclarator(public_lib::Context *ctx, ir::Varia if (arg->TsType() != type) { arg = util::NodeAllocator::ForceSetParent( allocator, arg, allocator->New(type, allocator), false); + arg->AsTSAsExpression()->TypeAnnotation()->SetRange(declarator->Init()->Range()); + arg->SetRange(declarator->Init()->Range()); } initArgs.push_back(arg); } @@ -201,6 +206,11 @@ static ir::AstNode *HandleVariableDeclarator(public_lib::Context *ctx, ir::Varia allocator, declarator->Flag(), allocator->New(id->Name(), allocator), newInit); newDeclarator->SetParent(declarator->Parent()); + newInit->GetTypeRef()->SetRange(declarator->Range()); + newInit->SetRange(declarator->Range()); + newDeclarator->Id()->SetRange(declarator->Range()); + newDeclarator->SetRange(declarator->Range()); + auto *newDecl = allocator->New(oldVar->Name(), newDeclarator); auto *newVar = allocator->New(newDecl, oldVar->Flags()); newDeclarator->Id()->AsIdentifier()->SetVariable(newVar); @@ -352,6 +362,7 @@ bool BoxingForLocals::PerformForModule(public_lib::Context *ctx, parser::Program std::function searchForFunctions = [&](ir::AstNode *ast) { if (ast->IsScriptFunction()) { HandleScriptFunction(ctx, ast->AsScriptFunction()); // no recursion + RefineSourceRanges(ast); } else { ast->Iterate(searchForFunctions); } diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index 503cf4dd99..d5ff5281c3 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -14,25 +14,207 @@ */ #include "constantExpressionLowering.h" +#include #include "checker/ETSchecker.h" #include "compiler/lowering/util.h" -#include "lexer/token/token.h" +#include "ir/expressions/literals/undefinedLiteral.h" +#include "compiler/lowering/scopesInit/scopesInitPhase.h" +#include "util/helpers.h" namespace ark::es2panda::compiler { using AstNodePtr = ir::AstNode *; -void ConstantExpressionLowering::LogError(const diagnostic::DiagnosticKind &diagnostic, - const util::DiagnosticMessageParams &diagnosticParams, - const lexer::SourcePosition &pos) const +static ir::BooleanLiteral *CreateBooleanLiteral(bool val, ir::AstNode *parent, const lexer::SourceRange &loc, + ArenaAllocator *allocator) { - context_->diagnosticEngine->LogDiagnostic(diagnostic, diagnosticParams, pos); + auto resNode = util::NodeAllocator::Alloc(allocator, val); + resNode->SetParent(parent); + resNode->SetRange(loc); + return resNode; +} + +template +static ir::NumberLiteral *CreateNumberLiteral(T val, ir::AstNode *parent, const lexer::SourceRange &loc, + ArenaAllocator *allocator) +{ + auto resNum = lexer::Number(val); + + auto *resNode = util::NodeAllocator::Alloc(allocator, resNum); + + // Some hack to set string representation of lexer::Number + resNode->Number().SetStr(util::UString(resNode->ToString(), allocator).View()); + + resNode->SetParent(parent); + resNode->SetRange(loc); + return resNode; +} + +static ir::Identifier *CreateErrorIdentifier(const ir::AstNode *node, ArenaAllocator *allocator) +{ + // Creating Identifier without passing any arguments leads to creating Error Identifier with *ERROR_LITERAL* + auto res = util::NodeAllocator::Alloc(allocator, allocator); + + res->SetParent(const_cast(node)->Parent()); + res->SetRange(node->Range()); + return res; +} + +static ir::CharLiteral *CreateCharLiteral(char16_t val, ir::AstNode *parent, const lexer::SourceRange &loc, + ArenaAllocator *allocator) +{ + auto *result = util::NodeAllocator::Alloc(allocator, val); + result->SetParent(parent); + result->SetRange(loc); + return result; +} + +static ir::PrimitiveType TypeRankToPrimitiveType(TypeRank tr) +{ + switch (tr) { + case TypeRank::CHAR: + return ir::PrimitiveType::CHAR; + case TypeRank::INT8: + return ir::PrimitiveType::BYTE; + case TypeRank::INT16: + return ir::PrimitiveType::SHORT; + case TypeRank::INT32: + return ir::PrimitiveType::INT; + case TypeRank::INT64: + return ir::PrimitiveType::LONG; + case TypeRank::FLOAT: + return ir::PrimitiveType::FLOAT; + case TypeRank::DOUBLE: + return ir::PrimitiveType::DOUBLE; + } + ES2PANDA_UNREACHABLE(); +} + +static TypeRank GetTypeRank(const ir::Literal *literal) +{ + if (literal->IsCharLiteral()) { + return TypeRank::CHAR; + } + if (literal->IsNumberLiteral()) { + auto number = literal->AsNumberLiteral()->Number(); + if (number.IsByte()) { + return TypeRank::INT8; + } + if (number.IsShort()) { + return TypeRank::INT16; + } + if (number.IsInt()) { + return TypeRank::INT32; + } + if (number.IsLong()) { + return TypeRank::INT64; + } + if (number.IsFloat()) { + return TypeRank::FLOAT; + } + if (number.IsDouble()) { + return TypeRank::DOUBLE; + } + } + ES2PANDA_UNREACHABLE(); } -static bool IsSupportedLiteralForNumeric(ir::Literal *const node) +template +static TargetType GetVal(const ir::Literal *node) { - return node->IsNumberLiteral() || node->IsCharLiteral() || node->IsBooleanLiteral(); + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(node->IsBooleanLiteral()); + return node->AsBooleanLiteral()->Value(); + } + + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(node->IsCharLiteral()); + return node->AsCharLiteral()->Char(); + } + + ES2PANDA_ASSERT(node->IsNumberLiteral()); + + auto numNode = node->AsNumberLiteral(); + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsByte()); + return numNode->Number().GetByte(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsShort()); + return numNode->Number().GetShort(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsInt()); + return numNode->Number().GetInt(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsLong()); + return numNode->Number().GetLong(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsFloat()); + return numNode->Number().GetFloat(); + } + if constexpr (std::is_same_v) { + ES2PANDA_ASSERT(numNode->Number().IsDouble()); + return numNode->Number().GetDouble(); + } + ES2PANDA_UNREACHABLE(); +} + +template +static To CastValTo(const ir::Literal *lit) +{ + if (lit->IsBooleanLiteral()) { + return static_cast(GetVal(lit)); + } + + if (lit->IsStringLiteral() && lit->AsStringLiteral()->Str().IsConvertibleToChar() && std::is_same_v) { + auto getChar = [](const ir::Literal *strLit) { + if (strLit->IsCharLiteral()) { + return strLit->AsCharLiteral()->Char(); + } + ES2PANDA_ASSERT(strLit->IsStringLiteral()); + util::StringView::Iterator it(strLit->AsStringLiteral()->Str()); + return static_cast(it.PeekCp()); + }; + return getChar(lit); + } + + ES2PANDA_ASSERT(lit->IsNumberLiteral() || lit->IsCharLiteral()); + + auto rank = GetTypeRank(lit); + switch (rank) { + case TypeRank::DOUBLE: + return static_cast(GetVal(lit)); + case TypeRank::FLOAT: + return static_cast(GetVal(lit)); + case TypeRank::INT64: + return static_cast(GetVal(lit)); + case TypeRank::INT32: + return static_cast(GetVal(lit)); + case TypeRank::INT16: + return static_cast(GetVal(lit)); + case TypeRank::INT8: + return static_cast(GetVal(lit)); + case TypeRank::CHAR: + return static_cast(GetVal(lit)); + } + + ES2PANDA_UNREACHABLE(); +} + +static bool IsConvertibleToNumericType(const ir::Literal *lit) +{ + // true if CharLiteral and NumberLiteral + return !(lit->IsStringLiteral() || lit->IsBooleanLiteral() || lit->IsNullLiteral() || lit->IsUndefinedLiteral()); +} + +static void LogError(public_lib::Context *context, const diagnostic::DiagnosticKind &diagnostic, + const util::DiagnosticMessageParams &diagnosticParams, const lexer::SourcePosition &pos) +{ + context->diagnosticEngine->LogDiagnostic(diagnostic, diagnosticParams, pos); } static bool IsSupportedLiteral(ir::Expression *const node) @@ -52,136 +234,245 @@ static bool IsStringTypeReference(ir::ETSTypeReference *type) return name == "string" || name == "String"; } -static bool CheckIsBooleanConstantForUnary(ir::Literal *const unaryLiteral, lexer::TokenType opType) +static ir::AstNode *CommonCastStringToChar(const ir::Literal *lit, ArenaAllocator *allocator) { - if (unaryLiteral->IsBooleanLiteral()) { - return true; + auto parent = const_cast(lit)->Parent(); + return CreateCharLiteral(CastValTo(lit), parent, lit->Range(), allocator); +} + +template +static ir::AstNode *CommonCastNumberLiteralTo(const ir::Literal *num, ArenaAllocator *allocator) +{ + auto parent = const_cast(num)->Parent(); + + if constexpr (std::is_same_v) { + return CreateCharLiteral(CastValTo(num), parent, num->Range(), allocator); } - return opType == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK; + + return CreateNumberLiteral(CastValTo(num), parent, num->Range(), allocator); } -static bool CheckIsBooleanConstantForBinary(ir::Literal *lhs, ir::Literal *rhs, lexer::TokenType opType) +template +static ir::AstNode *FloatingPointNumberLiteralCast(const ir::Literal *num, public_lib::Context *context) { - if (lhs->IsBooleanLiteral() && rhs->IsBooleanLiteral()) { - return true; + if (sizeof(From) > sizeof(To)) { + // Constant narrowing floating point conversion is not permitted + LogError(context, diagnostic::CONSTANT_FLOATING_POINT_COVERSION, {}, num->Start()); + return const_cast(num); } - return opType == lexer::TokenType::PUNCTUATOR_GREATER_THAN || - opType == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - opType == lexer::TokenType::PUNCTUATOR_LESS_THAN || opType == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL || - opType == lexer::TokenType::PUNCTUATOR_EQUAL || opType == lexer::TokenType::PUNCTUATOR_NOT_EQUAL || - opType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || opType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR; + + // float -> double + return CommonCastNumberLiteralTo(num, context->allocator); } -static bool CheckIsNumericConstant(ir::Literal *const left, ir::Literal *const right) +template +static ir::AstNode *NarrowingNumberLiteralCast(const ir::Literal *num, public_lib::Context *context) { - return (left->IsNumberLiteral() || left->IsCharLiteral()) && (right->IsNumberLiteral() || right->IsCharLiteral()); + auto maxTo = std::numeric_limits::max(); + auto minTo = std::numeric_limits::min(); + auto val = GetVal(num); + if (val < minTo || val > maxTo) { + LogError(context, diagnostic::CONSTANT_VALUE_OUT_OF_RANGE, {}, num->Start()); + return const_cast(num); + } + + return CommonCastNumberLiteralTo(num, context->allocator); } -template -static TargetType GetOperand(ir::Literal *const node) +template +static ir::AstNode *IntegralNumberLiteralCast(const ir::Literal *num, public_lib::Context *context) { - if (node->IsBooleanLiteral()) { - return node->AsBooleanLiteral()->Value(); + if (sizeof(From) > sizeof(To)) { + return NarrowingNumberLiteralCast(num, context); } - if (node->IsNumberLiteral()) { - auto numNode = node->AsNumberLiteral(); - if (numNode->Number().IsInt()) { - return numNode->Number().GetInt(); - } - if (numNode->Number().IsLong()) { - return numNode->Number().GetLong(); - } - if (numNode->Number().IsFloat()) { - return numNode->Number().GetFloat(); - } - if (numNode->Number().IsDouble()) { - return numNode->Number().GetDouble(); - } - ES2PANDA_UNREACHABLE(); + // Widening + return CommonCastNumberLiteralTo(num, context->allocator); +} + +template +static ir::AstNode *CastNumberOrCharLiteralFromTo(const ir::Literal *num, public_lib::Context *context) +{ + if constexpr (std::is_same_v) { + return const_cast(num); } - if (node->IsCharLiteral()) { - return node->AsCharLiteral()->Char(); + if constexpr (std::is_floating_point_v && std::is_floating_point_v) { + return FloatingPointNumberLiteralCast(num, context); + } + + if constexpr (std::is_integral_v && std::is_integral_v) { + return IntegralNumberLiteralCast(num, context); + } + + if constexpr (std::is_integral_v && std::is_floating_point_v) { + // integral -> floating point (widening) + return CommonCastNumberLiteralTo(num, context->allocator); + } + + if constexpr (std::is_floating_point_v && std::is_integral_v) { + // Constant narrowing floating point conversion is not permitted + LogError(context, diagnostic::CONSTANT_FLOATING_POINT_COVERSION, {}, num->Start()); + return const_cast(num); } ES2PANDA_UNREACHABLE(); } -static TypeRank GetTypeRank(ir::Literal *const literal) +template +static ir::AstNode *CastNumberOrCharLiteralFrom(const ir::Literal *lit, ir::PrimitiveType type, + public_lib::Context *context) { - if (literal->IsCharLiteral()) { - return TypeRank::CHAR; - } - if (literal->IsNumberLiteral()) { - auto number = literal->AsNumberLiteral()->Number(); - if (number.IsInt()) { - return TypeRank::INT32; - } - if (number.IsLong()) { - return TypeRank::INT64; - } - if (number.IsDouble()) { - return TypeRank::DOUBLE; - } - return TypeRank::FLOAT; + switch (type) { + case ir::PrimitiveType::CHAR: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::BYTE: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::SHORT: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::INT: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::LONG: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::FLOAT: + return CastNumberOrCharLiteralFromTo(lit, context); + case ir::PrimitiveType::DOUBLE: + return CastNumberOrCharLiteralFromTo(lit, context); + default: + ES2PANDA_UNREACHABLE(); } - ES2PANDA_UNREACHABLE(); } -static bool TestLiteralIsNotZero(ir::Literal *literal) +static ir::AstNode *CorrectNumberOrCharLiteral(const ir::Literal *lit, ir::PrimitiveType type, + public_lib::Context *context) { - ES2PANDA_ASSERT(literal->IsCharLiteral() || literal->IsNumberLiteral()); - if (literal->IsCharLiteral()) { - return literal->AsCharLiteral()->Char() != 0; + if (!lit->IsStringLiteral() && TypeRankToPrimitiveType(GetTypeRank(lit)) == type) { + return const_cast(lit); } - auto number = literal->AsNumberLiteral()->Number(); - if (number.IsInt()) { - return number.GetInt() != 0; + if (lit->IsStringLiteral() && lit->AsStringLiteral()->Str().IsConvertibleToChar()) { + return CommonCastStringToChar(lit, context->allocator); } - if (number.IsLong()) { - return number.GetLong() != 0; + + switch (GetTypeRank(lit)) { + case TypeRank::CHAR: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::INT8: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::INT16: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::INT32: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::INT64: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::FLOAT: + return CastNumberOrCharLiteralFrom(lit, type, context); + case TypeRank::DOUBLE: + return CastNumberOrCharLiteralFrom(lit, type, context); + default: + ES2PANDA_UNREACHABLE(); } - if (number.IsDouble()) { - return number.GetDouble() != 0; +} + +ir::TypeNode *GetTypeAnnotationFromVarDecl(const ir::Literal *lit) +{ + auto *parent = lit->Parent(); + if (!parent->IsVariableDeclarator()) { + return nullptr; } - if (number.IsFloat()) { - return number.GetFloat() != 0; + auto vd = parent->AsVariableDeclarator(); + if (!vd->Id()->IsIdentifier()) { + return nullptr; } - ES2PANDA_UNREACHABLE(); + return vd->Id()->AsIdentifier()->TypeAnnotation(); } -ir::AstNode *ConstantExpressionLowering::FoldTernaryConstant(ir::ConditionalExpression *cond) +static ir::PrimitiveType GetRightTypeOfNumberOrCharLiteral(const ir::Literal *lit) { - ir::AstNode *resNode {}; + auto *parent = lit->Parent(); + if (parent->IsVariableDeclarator()) { + auto vb = parent->AsVariableDeclarator(); + if (!vb->Id()->IsIdentifier()) { + return TypeRankToPrimitiveType(GetTypeRank(lit)); + } + + if (vb->Id()->AsIdentifier()->TypeAnnotation() == nullptr) { + return TypeRankToPrimitiveType(GetTypeRank(lit)); + } + + if (vb->Id()->AsIdentifier()->TypeAnnotation()->IsETSPrimitiveType()) { + return vb->Id()->AsIdentifier()->TypeAnnotation()->AsETSPrimitiveType()->GetPrimitiveType(); + } + } else if (parent->IsClassProperty()) { + auto cp = parent->AsClassProperty(); + if (cp->TypeAnnotation() == nullptr) { + return TypeRankToPrimitiveType(GetTypeRank(lit)); + } + + if (cp->TypeAnnotation()->IsETSPrimitiveType()) { + return cp->TypeAnnotation()->AsETSPrimitiveType()->GetPrimitiveType(); + } + } - auto const testCond = cond->Test()->AsLiteral(); - if (testCond->IsBooleanLiteral()) { - resNode = testCond->AsBooleanLiteral()->Value() ? cond->Consequent() : cond->Alternate(); + return TypeRankToPrimitiveType(GetTypeRank(lit)); +} + +static ir::AstNode *TryToCorrectNumberOrCharLiteral(ir::AstNode *node, public_lib::Context *context) +{ + if (node->IsStringLiteral()) { + auto lit = node->AsExpression()->AsLiteral(); + auto annotationType = GetTypeAnnotationFromVarDecl(lit); + if (annotationType != nullptr && annotationType->IsETSPrimitiveType() && + node->AsStringLiteral()->Str().IsConvertibleToChar()) { + return CorrectNumberOrCharLiteral(lit, ir::PrimitiveType::CHAR, context); + } } + + if (node->IsNumberLiteral() || node->IsCharLiteral()) { + auto lit = node->AsExpression()->AsLiteral(); + return CorrectNumberOrCharLiteral(lit, GetRightTypeOfNumberOrCharLiteral(lit), context); + } + + return node; +} + +// NOLINTBEGIN(readability-else-after-return) +static bool TestLiteral(const ir::Literal *lit) +{ // 15.10.1 Extended Conditional Expression - if (testCond->IsStringLiteral()) { - resNode = !testCond->AsStringLiteral()->Str().Empty() ? cond->Consequent() : cond->Alternate(); + if (lit->IsBooleanLiteral()) { + return lit->AsBooleanLiteral()->Value(); } - if (testCond->IsNullLiteral() || testCond->IsUndefinedLiteral()) { - resNode = cond->Alternate(); + if (lit->IsStringLiteral()) { + return !lit->AsStringLiteral()->Str().Empty(); } - if (testCond->IsCharLiteral() || testCond->IsNumberLiteral()) { - resNode = TestLiteralIsNotZero(testCond) ? cond->Consequent() : cond->Alternate(); + if (lit->IsNullLiteral() || lit->IsUndefinedLiteral()) { + return false; } - - if (resNode == nullptr) { - return cond; + if (lit->IsCharLiteral()) { + return lit->AsCharLiteral()->Char() != 0; } + if (lit->IsNumberLiteral()) { + return !lit->AsNumberLiteral()->Number().IsZero(); + } + ES2PANDA_UNREACHABLE(); +} +// NOLINTEND(readability-else-after-return) - resNode->SetParent(cond->Parent()); +ir::AstNode *ConstantExpressionLowering::FoldTernaryConstant(ir::ConditionalExpression *cond) +{ + auto const test = cond->Test()->AsLiteral(); + auto res = TestLiteral(test) ? cond->Consequent() : cond->Alternate(); + auto resNode = res->Clone(context_->allocator, cond->Parent()); + auto *scope = NearestScope(resNode->Parent()); + auto localCtx = varbinder::LexicalScope::Enter(varbinder_, scope); + InitScopesPhaseETS::RunExternalNode(resNode, varbinder_); resNode->SetRange(cond->Range()); return resNode; } template -bool ConstantExpressionLowering::PerformRelationOperator(InputType left, InputType right, lexer::TokenType opType) +static bool PerformRelationOperation(InputType left, InputType right, lexer::TokenType opType) { switch (opType) { case lexer::TokenType::PUNCTUATOR_GREATER_THAN: { @@ -196,9 +487,22 @@ bool ConstantExpressionLowering::PerformRelationOperator(InputType left, InputTy case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: { return left <= right; } + case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_EQUAL: { + if constexpr (std::is_floating_point_v) { + // Compare floating point numbers in two steps: + // 1. With fixed epsilon + // 2. with adaptive epsilon + // CC-OFFNXT(G.FMT.03-CPP) project code style + static constexpr auto EPSILON = 1.0e-5F; + if (std::fabs(left - right) <= EPSILON) { + return true; + } + return std::fabs(left - right) <= EPSILON * std::fmax(std::fabs(left), std::fabs(right)); + } return left == right; } + case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { return left != right; } @@ -208,367 +512,562 @@ bool ConstantExpressionLowering::PerformRelationOperator(InputType left, InputTy } } -bool ConstantExpressionLowering::HandleRelationOperator(ir::Literal *left, ir::Literal *right, lexer::TokenType opType) +static ir::AstNode *HandleNumericalRelationalExpression(const ir::BinaryExpression *expr, ArenaAllocator *allocator) { - if (left->IsBooleanLiteral()) { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); - } - if (left->IsStringLiteral()) { - return PerformRelationOperator(left->AsStringLiteral()->Str(), right->AsStringLiteral()->Str(), opType); - } + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + ES2PANDA_ASSERT(left->IsNumberLiteral() || left->IsCharLiteral()); + ES2PANDA_ASSERT(right->IsNumberLiteral() || right->IsCharLiteral()); - TypeRank leftRank = GetTypeRank(left); - TypeRank rightRank = GetTypeRank(right); - TypeRank targetRank = std::max(leftRank, rightRank); + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); + + bool res = false; switch (targetRank) { case TypeRank::DOUBLE: { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); + res = PerformRelationOperation(CastValTo(left), CastValTo(right), opType); + break; } case TypeRank::FLOAT: { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); + res = PerformRelationOperation(CastValTo(left), CastValTo(right), opType); + break; } case TypeRank::INT64: { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); + res = PerformRelationOperation(CastValTo(left), CastValTo(right), opType); + break; } case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: case TypeRank::CHAR: { - return PerformRelationOperator(GetOperand(left), GetOperand(right), opType); + res = PerformRelationOperation(CastValTo(left), CastValTo(right), opType); + break; } default: { ES2PANDA_UNREACHABLE(); } } + + return CreateBooleanLiteral(res, const_cast(expr)->Parent(), expr->Range(), allocator); } -bool ConstantExpressionLowering::HandleBitwiseLogicalOperator(ir::Literal *left, ir::Literal *right, - lexer::TokenType opType) +static bool HandleCharStringRelation(const ir::Literal *left, const ir::Literal *right, lexer::TokenType opType) { - bool leftValue = left->AsBooleanLiteral()->Value(); - bool rightValue = right->AsBooleanLiteral()->Value(); + auto getChar = [](const ir::Literal *lit) { + if (lit->IsCharLiteral()) { + return lit->AsCharLiteral()->Char(); + } + ES2PANDA_ASSERT(lit->IsStringLiteral()); + util::StringView::Iterator it(lit->AsStringLiteral()->Str()); + return static_cast(it.PeekCp()); + }; + + return PerformRelationOperation(getChar(left), getChar(right), opType); +} + +static ir::AstNode *HandleNullUndefinedRelation(const ir::BinaryExpression *expr, public_lib::Context *context) +{ + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + bool isLeftNullUndefined = left->IsNullLiteral() || left->IsUndefinedLiteral(); + bool isRightNullUndefined = right->IsNullLiteral() || right->IsUndefinedLiteral(); + + // Either left operand is null/undefined or right operand is null/undefined + ES2PANDA_ASSERT(isLeftNullUndefined || isRightNullUndefined); + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + switch (opType) { - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { - return (static_cast(leftValue) ^ static_cast(rightValue)) != 0U; + case lexer::TokenType::PUNCTUATOR_EQUAL: { + if ((isLeftNullUndefined && !isRightNullUndefined) || (!isLeftNullUndefined && isRightNullUndefined)) { + return CreateBooleanLiteral(false, parent, loc, allocator); + } + return CreateBooleanLiteral(true, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { - return (static_cast(leftValue) & static_cast(rightValue)) != 0U; + case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { + if ((isLeftNullUndefined && !isRightNullUndefined) || (!isLeftNullUndefined && isRightNullUndefined)) { + return CreateBooleanLiteral(true, parent, loc, allocator); + } + return CreateBooleanLiteral(false, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { - return (static_cast(leftValue) | static_cast(rightValue)) != 0U; + case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: { + // null === null and undefined === undefined are true + return CreateBooleanLiteral(left->IsNullLiteral() == right->IsNullLiteral(), parent, loc, allocator); } + case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: + // null !== undefined is true + return CreateBooleanLiteral(left->IsNullLiteral() != right->IsNullLiteral(), parent, loc, allocator); default: { - ES2PANDA_UNREACHABLE(); + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); } } } -ir::AstNode *ConstantExpressionLowering::HandleLogicalOperator(ir::BinaryExpression *expr, lexer::TokenType opType) +static ir::AstNode *HandleRelationalExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { - auto left = expr->Left(); - auto right = expr->Right(); + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); - bool leftBoolValue = false; - ir::AstNode *resultValueNode = nullptr; + if (IsConvertibleToNumericType(left) && IsConvertibleToNumericType(right)) { + return HandleNumericalRelationalExpression(expr, context->allocator); + } - if (left->IsBooleanLiteral()) { - leftBoolValue = left->AsBooleanLiteral()->Value(); - } else if (left->IsNumberLiteral() || left->IsCharLiteral()) { - leftBoolValue = GetOperand(left->AsLiteral()) != 0; - } else if (left->IsStringLiteral()) { - leftBoolValue = left->AsStringLiteral()->Str().Length() != 0; - } else if (left->IsNullLiteral() || left->IsUndefinedLiteral()) { - leftBoolValue = false; - } else { - ES2PANDA_UNREACHABLE(); + if (left->IsStringLiteral() && right->IsStringLiteral()) { + auto res = PerformRelationOperation(left->AsStringLiteral()->Str(), right->AsStringLiteral()->Str(), opType); + return CreateBooleanLiteral(res, const_cast(expr)->Parent(), expr->Range(), + context->allocator); } + if (left->IsBooleanLiteral() && right->IsBooleanLiteral()) { + auto res = PerformRelationOperation(GetVal(left), GetVal(right), opType); + return CreateBooleanLiteral(res, const_cast(expr)->Parent(), expr->Range(), + context->allocator); + } + + if ((left->IsNullLiteral() || left->IsUndefinedLiteral()) || + (right->IsNullLiteral() || right->IsUndefinedLiteral())) { + return HandleNullUndefinedRelation(expr, context); + } + + if ((left->IsCharLiteral() && right->IsStringLiteral() && right->AsStringLiteral()->Str().IsConvertibleToChar()) || + (right->IsCharLiteral() && left->IsStringLiteral() && left->AsStringLiteral()->Str().IsConvertibleToChar())) { + auto res = HandleCharStringRelation(left, right, opType); + return CreateBooleanLiteral(res, const_cast(expr)->Parent(), expr->Range(), + context->allocator); + } + + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); +} + +static bool IsMultiplicativeExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_MULTIPLY || opType == lexer::TokenType::PUNCTUATOR_DIVIDE || + opType == lexer::TokenType::PUNCTUATOR_MOD; +} + +static bool IsRelationalExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_GREATER_THAN || + opType == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || + opType == lexer::TokenType::PUNCTUATOR_LESS_THAN || opType == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL || + opType == lexer::TokenType::PUNCTUATOR_EQUAL || opType == lexer::TokenType::PUNCTUATOR_NOT_EQUAL || + opType == lexer::TokenType::PUNCTUATOR_STRICT_EQUAL || + opType == lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL; +} + +static bool IsAdditiveExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + + return opType == lexer::TokenType::PUNCTUATOR_PLUS || opType == lexer::TokenType::PUNCTUATOR_MINUS; +} + +template +static TargetType PerformMultiplicativeOperation(TargetType leftNum, TargetType rightNum, + const ir::BinaryExpression *expr, public_lib::Context *context) +{ + auto isForbiddenZeroDivision = [&rightNum]() { return std::is_integral_v && rightNum == 0; }; + auto opType = expr->OperatorType(); switch (opType) { - case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: { - if (!leftBoolValue) { - resultValueNode = left; - break; + case lexer::TokenType::PUNCTUATOR_MULTIPLY: { + return leftNum * rightNum; + } + case lexer::TokenType::PUNCTUATOR_DIVIDE: { + if (isForbiddenZeroDivision()) { + LogError(context, diagnostic::DIVISION_BY_ZERO, {}, expr->Start()); + // Max integral value + return std::numeric_limits::max(); } - resultValueNode = right; - break; + return leftNum / rightNum; } - case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { - if (leftBoolValue) { - resultValueNode = left; + case lexer::TokenType::PUNCTUATOR_MOD: { + if (isForbiddenZeroDivision()) { + LogError(context, diagnostic::DIVISION_BY_ZERO, {}, expr->Start()); + // Max integral value + return std::numeric_limits::max(); + } + if constexpr (std::is_integral_v) { + return leftNum % rightNum; } else { - resultValueNode = right; + return std::fmod(leftNum, rightNum); } - break; } - default: { + default: ES2PANDA_UNREACHABLE(); + } +} + +static ir::AstNode *HandleMultiplicativeExpression(const ir::BinaryExpression *expr, public_lib::Context *context) +{ + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + if (!IsConvertibleToNumericType(left) && !IsConvertibleToNumericType(right)) { + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); + } + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); + switch (targetRank) { + case TypeRank::DOUBLE: { + double res = + PerformMultiplicativeOperation(CastValTo(left), CastValTo(right), expr, context); + return CreateNumberLiteral(res, parent, loc, allocator); + } + case TypeRank::FLOAT: { + float res = PerformMultiplicativeOperation(CastValTo(left), CastValTo(right), expr, context); + return CreateNumberLiteral(res, parent, loc, allocator); + } + case TypeRank::INT64: { + int64_t res = + PerformMultiplicativeOperation(CastValTo(left), CastValTo(right), expr, context); + return CreateNumberLiteral(res, parent, loc, allocator); } + case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: + case TypeRank::CHAR: { + int32_t res = + PerformMultiplicativeOperation(CastValTo(left), CastValTo(right), expr, context); + return CreateNumberLiteral(res, parent, loc, allocator); + } + default: + ES2PANDA_UNREACHABLE(); } +} - resultValueNode->SetParent(expr->Parent()); - resultValueNode->SetRange({left->Range().start, right->Range().end}); - return resultValueNode; +template +static TargetType PerformAdditiveOperation(TargetType left, TargetType right, lexer::TokenType opType) +{ + if constexpr (std::is_floating_point_v) { + switch (opType) { + case lexer::TokenType::PUNCTUATOR_PLUS: + return left + right; + case lexer::TokenType::PUNCTUATOR_MINUS: + return left - right; + default: + ES2PANDA_UNREACHABLE(); + } + } else { + // Integral types + // try bit cast to unsigned counterpart to avoid signed integer overflow + auto uLeft = bit_cast, TargetType>(left); + auto uRight = bit_cast, TargetType>(right); + + switch (opType) { + case lexer::TokenType::PUNCTUATOR_PLUS: { + return bit_cast>(uLeft + uRight); + } + case lexer::TokenType::PUNCTUATOR_MINUS: { + return bit_cast>(uLeft - uRight); + } + default: + ES2PANDA_UNREACHABLE(); + } + } } -ir::AstNode *ConstantExpressionLowering::FoldBinaryBooleanConstant(ir::BinaryExpression *expr) +static ir::AstNode *PerformStringAdditiveOperation(const ir::BinaryExpression *expr, public_lib::Context *context) +{ + auto const lhs = expr->Left()->AsLiteral(); + auto const rhs = expr->Right()->AsLiteral(); + auto const resStr = util::UString(lhs->ToString() + rhs->ToString(), context->allocator).View(); + auto resNode = util::NodeAllocator::Alloc(context->allocator, resStr); + resNode->SetParent(const_cast(expr)->Parent()); + resNode->SetRange(expr->Range()); + return resNode; +} + +static ir::AstNode *HandleAdditiveExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { auto left = expr->Left()->AsLiteral(); auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + if ((opType == lexer::TokenType::PUNCTUATOR_PLUS) && (left->IsStringLiteral() || right->IsStringLiteral())) { + return PerformStringAdditiveOperation(expr, context); + } + + if (!IsConvertibleToNumericType(left) && !IsConvertibleToNumericType(right)) { + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); + } - bool result {}; - switch (expr->OperatorType()) { - case lexer::TokenType::PUNCTUATOR_GREATER_THAN: - case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: - case lexer::TokenType::PUNCTUATOR_LESS_THAN: - case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: - case lexer::TokenType::PUNCTUATOR_EQUAL: - case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - if ((left->IsBooleanLiteral() && right->IsBooleanLiteral()) || CheckIsNumericConstant(left, right) || - (left->IsStringLiteral() && right->IsStringLiteral())) { - result = HandleRelationOperator(left, right, expr->OperatorType()); - break; - } - return expr; + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); + switch (targetRank) { + case TypeRank::DOUBLE: { + auto res = PerformAdditiveOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { - if (left->IsBooleanLiteral() && right->IsBooleanLiteral()) { - result = HandleBitwiseLogicalOperator(left, right, expr->OperatorType()); - break; - } - return expr; + case TypeRank::FLOAT: { + auto res = PerformAdditiveOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: - case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { - // Special because of extended conditional expression - return HandleLogicalOperator(expr, expr->OperatorType()); + case TypeRank::INT64: { + int64_t res = PerformAdditiveOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - default: { - return expr; + case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: + case TypeRank::CHAR: { + int32_t res = PerformAdditiveOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } + default: + ES2PANDA_UNREACHABLE(); } +} - auto resNode = util::NodeAllocator::Alloc(context_->allocator, result); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; +static bool IsShiftExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || opType == lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT || + opType == lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT; } -template -IntegerType ConstantExpressionLowering::PerformBitwiseArithmetic(IntegerType left, IntegerType right, - lexer::TokenType operationType) +template +static SignedType PerformShiftOperation(SignedType left, SignedType right, lexer::TokenType opType) { - using UnsignedType = std::make_unsigned_t; + using UnsignedType = std::make_unsigned_t; - UnsignedType result = 0; - UnsignedType unsignedLeftValue = left; - UnsignedType unsignedRightValue = right; + SignedType result = 0; + auto uLeft = bit_cast(left); + auto uRight = bit_cast(right); auto mask = std::numeric_limits::digits - 1U; - auto shift = unsignedRightValue & mask; + UnsignedType shift = uRight & mask; - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { - result = unsignedLeftValue & unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { - result = unsignedLeftValue | unsignedRightValue; - break; - } - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { - result = unsignedLeftValue ^ unsignedRightValue; - break; - } + switch (opType) { case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: { static_assert(sizeof(UnsignedType) == 4 || sizeof(UnsignedType) == 8); - result = unsignedLeftValue << shift; - break; + return bit_cast(uLeft << shift); } case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: { - static_assert(sizeof(IntegerType) == 4 || sizeof(IntegerType) == 8); - result = static_cast(unsignedLeftValue) >> shift; // NOLINT(hicpp-signed-bitwise) - break; + static_assert(sizeof(SignedType) == 4 || sizeof(SignedType) == 8); + return bit_cast(left >> shift); // NOLINT(hicpp-signed-bitwise) } case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: { static_assert(sizeof(UnsignedType) == 4 || sizeof(UnsignedType) == 8); - result = unsignedLeftValue >> shift; - break; + return bit_cast(uLeft >> shift); } - default: { + default: ES2PANDA_UNREACHABLE(); - } } - return result; } -template -lexer::Number ConstantExpressionLowering::HandleBitwiseOperator(TargetType leftNum, TargetType rightNum, - lexer::TokenType operationType, TypeRank targetRank) +static ir::AstNode *HandleShiftExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + if (!IsConvertibleToNumericType(left) && !IsConvertibleToNumericType(right)) { + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); + } + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); switch (targetRank) { - case TypeRank::DOUBLE: { - return lexer::Number(PerformBitwiseArithmetic(leftNum, rightNum, operationType)); - } - case TypeRank::FLOAT: { - return lexer::Number(PerformBitwiseArithmetic(leftNum, rightNum, operationType)); - } + case TypeRank::DOUBLE: case TypeRank::INT64: { - return lexer::Number(PerformBitwiseArithmetic(leftNum, rightNum, operationType)); + int64_t res = PerformShiftOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } + case TypeRank::FLOAT: case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: case TypeRank::CHAR: { - return lexer::Number(PerformBitwiseArithmetic(leftNum, rightNum, operationType)); + int32_t res = PerformShiftOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - default: { + default: ES2PANDA_UNREACHABLE(); - } } } -template -TargetType ConstantExpressionLowering::HandleArithmeticOperation(TargetType leftNum, TargetType rightNum, - ir::BinaryExpression *expr) +static bool IsBitwiseLogicalExpression(const ir::BinaryExpression *expr) { - auto isForbiddenZeroDivision = [&rightNum]() { return std::is_integral::value && rightNum == 0; }; - auto operationType = expr->OperatorType(); - switch (operationType) { - case lexer::TokenType::PUNCTUATOR_PLUS: { - return leftNum + rightNum; + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_BITWISE_XOR || opType == lexer::TokenType::PUNCTUATOR_BITWISE_AND || + opType == lexer::TokenType::PUNCTUATOR_BITWISE_OR; +} + +template +static SignedType PerformBitwiseLogicalOperation(SignedType left, SignedType right, lexer::TokenType opType) +{ + using UnsignedType = std::make_unsigned_t; + + auto uLeft = bit_cast(left); + auto uRight = bit_cast(right); + + switch (opType) { + case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { + return uLeft & uRight; } - case lexer::TokenType::PUNCTUATOR_MINUS: { - return leftNum - rightNum; + case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { + return uLeft | uRight; } - case lexer::TokenType::PUNCTUATOR_DIVIDE: { - if (isForbiddenZeroDivision()) { - LogError(diagnostic::DIVISION_BY_ZERO, {}, expr->Start()); - return rightNum; - } - return leftNum / rightNum; + case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { + return uLeft ^ uRight; } - case lexer::TokenType::PUNCTUATOR_MULTIPLY: { - return leftNum * rightNum; + default: + ES2PANDA_UNREACHABLE(); + } +} + +static ir::AstNode *HandleNumericBitwiseLogicalExpression(const ir::BinaryExpression *expr, + public_lib::Context *context) +{ + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + TypeRank targetRank = std::max(GetTypeRank(left), GetTypeRank(right)); + switch (targetRank) { + case TypeRank::DOUBLE: + case TypeRank::INT64: { + int64_t res = PerformBitwiseLogicalOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } - case lexer::TokenType::PUNCTUATOR_MOD: { - if (isForbiddenZeroDivision()) { - LogError(diagnostic::DIVISION_BY_ZERO, {}, expr->Start()); - return rightNum; - } - if constexpr (std::is_integral_v) { - return leftNum % rightNum; - } else { - return std::fmod(leftNum, rightNum); - } + case TypeRank::FLOAT: + case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: + case TypeRank::CHAR: { + int32_t res = PerformBitwiseLogicalOperation(CastValTo(left), CastValTo(right), opType); + return CreateNumberLiteral(res, parent, loc, allocator); } default: ES2PANDA_UNREACHABLE(); } } -template -ir::AstNode *ConstantExpressionLowering::FoldBinaryNumericConstantHelper(ir::BinaryExpression *expr, - TypeRank targetRank) +static ir::AstNode *HandleBitwiseLogicalExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { - auto const lhs = expr->Left()->AsLiteral(); - auto const rhs = expr->Right()->AsLiteral(); - lexer::Number resNum {}; - auto lhsNumber = GetOperand(lhs); - auto rhsNumber = GetOperand(rhs); - switch (expr->OperatorType()) { - case lexer::TokenType::PUNCTUATOR_DIVIDE: - case lexer::TokenType::PUNCTUATOR_MOD: - case lexer::TokenType::PUNCTUATOR_PLUS: - case lexer::TokenType::PUNCTUATOR_MINUS: - case lexer::TokenType::PUNCTUATOR_MULTIPLY: { - auto num = HandleArithmeticOperation(lhsNumber, rhsNumber, expr); - resNum = lexer::Number(num); + auto left = expr->Left()->AsLiteral(); + auto right = expr->Right()->AsLiteral(); + auto opType = expr->OperatorType(); + + if (IsConvertibleToNumericType(left) && IsConvertibleToNumericType(right)) { + return HandleNumericBitwiseLogicalExpression(expr, context); + } + + if (!left->IsBooleanLiteral() && !right->IsBooleanLiteral()) { + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); + return CreateErrorIdentifier(expr, context->allocator); + } + + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + bool res = false; + + auto leftVal = left->AsBooleanLiteral()->Value(); + auto rightVal = right->AsBooleanLiteral()->Value(); + switch (opType) { + case lexer::TokenType::PUNCTUATOR_BITWISE_AND: { + res = ((static_cast(leftVal) & static_cast(rightVal)) != 0); break; } - case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: - case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { - resNum = HandleBitwiseOperator(lhsNumber, rhsNumber, expr->OperatorType(), targetRank); + case lexer::TokenType::PUNCTUATOR_BITWISE_OR: { + res = ((static_cast(leftVal) | static_cast(rightVal)) != 0); break; } - default: { - // Operation might not support. - return expr; + case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: { + res = leftVal ^ rightVal; + break; } + default: + ES2PANDA_UNREACHABLE(); } + return CreateBooleanLiteral(res, parent, loc, allocator); +} - ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(context_->allocator, resNum); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; +static bool IsConditionalExpression(const ir::BinaryExpression *expr) +{ + auto opType = expr->OperatorType(); + return opType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || opType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR; } -ir::AstNode *ConstantExpressionLowering::FoldBinaryNumericConstant(ir::BinaryExpression *expr) +static ir::AstNode *HandleConditionalExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { - auto left = expr->Left()->AsLiteral(); - auto right = expr->Right()->AsLiteral(); - if (!IsSupportedLiteralForNumeric(left) && !IsSupportedLiteralForNumeric(right)) { - return expr; - } + auto left = const_cast(expr)->Left()->AsLiteral(); + auto right = const_cast(expr)->Right()->AsLiteral(); - TypeRank leftRank = GetTypeRank(left); - TypeRank rightRank = GetTypeRank(right); - TypeRank targetRank = std::max(leftRank, rightRank); - switch (targetRank) { - case TypeRank::DOUBLE: { - return FoldBinaryNumericConstantHelper(expr, targetRank); - } - case TypeRank::FLOAT: { - return FoldBinaryNumericConstantHelper(expr, targetRank); - } - case TypeRank::INT64: { - return FoldBinaryNumericConstantHelper(expr, targetRank); + auto allocator = context->allocator; + auto parent = const_cast(expr)->Parent(); + auto loc = expr->Range(); + + bool lhs = TestLiteral(left); + bool rhs = TestLiteral(right); + + auto opType = expr->OperatorType(); + switch (opType) { + case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: { + return CreateBooleanLiteral(lhs && rhs, parent, loc, allocator); } - case TypeRank::INT32: - case TypeRank::CHAR: { - return FoldBinaryNumericConstantHelper(expr, targetRank); + case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { + return CreateBooleanLiteral(lhs || rhs, parent, loc, allocator); } default: { ES2PANDA_UNREACHABLE(); } } + ES2PANDA_UNREACHABLE(); } -ir::AstNode *ConstantExpressionLowering::FoldBinaryStringConstant(ir::BinaryExpression *const expr) +static ir::AstNode *FoldBinaryExpression(const ir::BinaryExpression *expr, public_lib::Context *context) { - if (expr->OperatorType() != lexer::TokenType::PUNCTUATOR_PLUS) { - LogError(diagnostic::UNSUPPORTED_OPERATOR_FOR_STRING, {}, expr->Left()->Start()); - return expr; + if (IsMultiplicativeExpression(expr)) { + return HandleMultiplicativeExpression(expr, context); } - - auto const lhs = expr->Left()->AsLiteral(); - auto const rhs = expr->Right()->AsLiteral(); - auto const resStr = util::UString(lhs->ToString() + rhs->ToString(), context_->allocator).View(); - auto resNode = util::NodeAllocator::Alloc(context_->allocator, resStr); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; -} - -ir::AstNode *ConstantExpressionLowering::FoldBinaryConstant(ir::BinaryExpression *const expr) -{ - auto const lhs = expr->Left()->AsLiteral(); - auto const rhs = expr->Right()->AsLiteral(); - - auto isBooleanConstant = CheckIsBooleanConstantForBinary(lhs, rhs, expr->OperatorType()); - if (isBooleanConstant) { - return FoldBinaryBooleanConstant(expr); + if (IsAdditiveExpression(expr)) { + return HandleAdditiveExpression(expr, context); + } + if (IsShiftExpression(expr)) { + return HandleShiftExpression(expr, context); + } + if (IsRelationalExpression(expr)) { + return HandleRelationalExpression(expr, context); + } + if (IsBitwiseLogicalExpression(expr)) { + return HandleBitwiseLogicalExpression(expr, context); } - if (lhs->IsStringLiteral() || rhs->IsStringLiteral()) { - return FoldBinaryStringConstant(expr); + if (IsConditionalExpression(expr)) { + return HandleConditionalExpression(expr, context); } - return FoldBinaryNumericConstant(expr); + ES2PANDA_UNREACHABLE(); } template -lexer::Number ConstantExpressionLowering::HandleBitwiseNegate(InputType value, TypeRank rank) +static lexer::Number HandleBitwiseNegate(InputType value, TypeRank rank) { switch (rank) { case TypeRank::DOUBLE: @@ -577,6 +1076,8 @@ lexer::Number ConstantExpressionLowering::HandleBitwiseNegate(InputType value, T } case TypeRank::FLOAT: case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: case TypeRank::CHAR: { return lexer::Number(static_cast(~static_cast(value))); } @@ -587,10 +1088,10 @@ lexer::Number ConstantExpressionLowering::HandleBitwiseNegate(InputType value, T } template -ir::AstNode *ConstantExpressionLowering::FoldUnaryNumericConstantHelper(ir::UnaryExpression *unary, ir::Literal *node, - TypeRank rank) +static ir::AstNode *FoldUnaryNumericConstantHelper(const ir::UnaryExpression *unary, const ir::Literal *node, + TypeRank rank, ArenaAllocator *allocator) { - auto value = GetOperand(node); + auto value = CastValTo(node); lexer::Number resNum {}; switch (unary->OperatorType()) { @@ -611,30 +1112,32 @@ ir::AstNode *ConstantExpressionLowering::FoldUnaryNumericConstantHelper(ir::Unar } } - ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(context_->allocator, resNum); - resNode->SetParent(unary->Parent()); + ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(allocator, resNum); + resNode->SetParent(const_cast(unary)->Parent()); resNode->SetRange(unary->Range()); return resNode; } -ir::AstNode *ConstantExpressionLowering::FoldUnaryNumericConstant(ir::UnaryExpression *unary) +static ir::AstNode *FoldUnaryNumericConstant(const ir::UnaryExpression *unary, ArenaAllocator *allocator) { auto literal = unary->Argument()->AsLiteral(); TypeRank rank = GetTypeRank(literal); switch (rank) { case TypeRank::DOUBLE: { - return FoldUnaryNumericConstantHelper(unary, literal, rank); + return FoldUnaryNumericConstantHelper(unary, literal, rank, allocator); } case TypeRank::FLOAT: { - return FoldUnaryNumericConstantHelper(unary, literal, rank); + return FoldUnaryNumericConstantHelper(unary, literal, rank, allocator); } case TypeRank::INT64: { - return FoldUnaryNumericConstantHelper(unary, literal, rank); + return FoldUnaryNumericConstantHelper(unary, literal, rank, allocator); } case TypeRank::INT32: + case TypeRank::INT16: + case TypeRank::INT8: case TypeRank::CHAR: { - return FoldUnaryNumericConstantHelper(unary, literal, rank); + return FoldUnaryNumericConstantHelper(unary, literal, rank, allocator); } default: { ES2PANDA_UNREACHABLE(); @@ -642,42 +1145,31 @@ ir::AstNode *ConstantExpressionLowering::FoldUnaryNumericConstant(ir::UnaryExpre } } -ir::AstNode *ConstantExpressionLowering::FoldUnaryBooleanConstant(ir::UnaryExpression *unary) +static ir::AstNode *FoldLogicalUnaryExpression(const ir::UnaryExpression *unary, ArenaAllocator *allocator) { - bool result {}; - auto *unaryLiteral = unary->Argument()->AsLiteral(); - - if (unary->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) { - // 15.10.1 Extended Conditional Expression - if (unaryLiteral->IsUndefinedLiteral() || unaryLiteral->IsNullLiteral()) { - result = true; - } else { - bool value = GetOperand(unaryLiteral); - result = !value; - } - } else { - ES2PANDA_UNREACHABLE(); - } - - auto resNode = util::NodeAllocator::Alloc(context_->allocator, result); - resNode->SetParent(unary->Parent()); + auto resNode = + util::NodeAllocator::Alloc(allocator, !TestLiteral(unary->Argument()->AsLiteral())); + resNode->SetParent(const_cast(unary)->Parent()); resNode->SetRange(unary->Range()); return resNode; } -ir::AstNode *ConstantExpressionLowering::FoldUnaryConstant(ir::UnaryExpression *const unary) +static ir::AstNode *FoldUnaryExpression(const ir::UnaryExpression *unary, public_lib::Context *context) { - auto unaryLiteral = unary->Argument()->AsLiteral(); + if (unary->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK) { + return FoldLogicalUnaryExpression(unary, context->allocator); + } - auto isBooleanConstant = CheckIsBooleanConstantForUnary(unaryLiteral, unary->OperatorType()); - if (isBooleanConstant) { - return FoldUnaryBooleanConstant(unary); + auto lit = unary->Argument()->AsLiteral(); + if (lit->IsNumberLiteral() || lit->IsCharLiteral() || lit->IsBooleanLiteral()) { + return FoldUnaryNumericConstant(unary, context->allocator); } - return FoldUnaryNumericConstant(unary); + LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_UNARY_EXPRESSION, {}, unary->Start()); + return CreateErrorIdentifier(unary, context->allocator); } -ir::AstNode *ConstantExpressionLowering::TryFoldTSAsExpressionForString(ir::TSAsExpression *expr) +static ir::AstNode *TryFoldTSAsExpressionForString(ir::TSAsExpression *expr) { if (expr->Expr()->IsStringLiteral() && expr->TypeAnnotation()->IsETSTypeReference() && IsStringTypeReference(expr->TypeAnnotation()->AsETSTypeReference())) { @@ -689,193 +1181,249 @@ ir::AstNode *ConstantExpressionLowering::TryFoldTSAsExpressionForString(ir::TSAs return expr; } -ir::AstNode *ConstantExpressionLowering::FoldTSAsExpressionToChar(ir::TSAsExpression *expr) -{ - auto *sourceLiteral = expr->Expr()->AsLiteral(); - auto resChar = GetOperand(sourceLiteral); - ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(context_->allocator, resChar); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; -} - -ir::AstNode *ConstantExpressionLowering::FoldTSAsExpressionToBoolean(ir::TSAsExpression *expr) -{ - auto *sourceLiteral = expr->Expr()->AsLiteral(); - auto resBool = GetOperand(sourceLiteral); - ir::TypedAstNode *resNode = util::NodeAllocator::Alloc(context_->allocator, resBool); - resNode->SetParent(expr->Parent()); - resNode->SetRange(expr->Range()); - return resNode; -} - -ir::AstNode *ConstantExpressionLowering::FoldTSAsExpression(ir::TSAsExpression *const expr) +static ir::AstNode *FoldTSAsExpression(ir::TSAsExpression *const expr, ArenaAllocator *allocator) { - if (expr->TypeAnnotation()->IsETSPrimitiveType()) { - auto *sourceLiteral = expr->Expr()->AsLiteral(); - lexer::Number resNum; + // For correct type inference, don't remove explicit type cast for array elements: + // [1 as int] should be inferred as int[], otherwise ([1]) it will be inferred as number[] + if (expr->TypeAnnotation()->IsETSPrimitiveType() && !expr->Parent()->IsArrayExpression()) { + auto *srcLit = expr->Expr()->AsLiteral(); switch (expr->TypeAnnotation()->AsETSPrimitiveType()->GetPrimitiveType()) { - case ir::PrimitiveType::CHAR: { - return FoldTSAsExpressionToChar(expr); - } - case ir::PrimitiveType::BOOLEAN: { - return FoldTSAsExpressionToBoolean(expr); - } - case ir::PrimitiveType::BYTE: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::SHORT: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::INT: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::LONG: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::FLOAT: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - case ir::PrimitiveType::DOUBLE: { - resNum = lexer::Number(GetOperand(sourceLiteral)); - break; - } - default: { - return expr; - } + case ir::PrimitiveType::CHAR: + return CreateCharLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::BOOLEAN: + return CreateBooleanLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::BYTE: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::SHORT: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::INT: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::LONG: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::FLOAT: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + case ir::PrimitiveType::DOUBLE: + return CreateNumberLiteral(CastValTo(srcLit), expr->Parent(), expr->Range(), allocator); + default: + ES2PANDA_UNREACHABLE(); } - ir::TypedAstNode *result = util::NodeAllocator::Alloc(context_->allocator, resNum); - result->SetParent(expr->Parent()); - result->SetRange(expr->Range()); - return result; } return TryFoldTSAsExpressionForString(expr); } -ir::AstNode *ConstantExpressionLowering::FoldMultilineString(ir::TemplateLiteral *expr) +static ir::AstNode *FoldTemplateLiteral(ir::TemplateLiteral *expr, ArenaAllocator *allocator) { - auto *result = util::NodeAllocator::Alloc(context_->allocator, expr->GetMultilineString()); - result->SetParent(expr->Parent()); - result->SetRange(expr->Range()); - return result; -} + auto litToString = [allocator](const ir::Literal *lit) { + if (lit->IsNumberLiteral()) { + return util::UString(lit->AsNumberLiteral()->ToString(), allocator).View(); + } + if (lit->IsCharLiteral()) { + return util::UString(lit->AsCharLiteral()->ToString(), allocator).View(); + } + if (lit->IsBooleanLiteral()) { + return util::UString(lit->AsBooleanLiteral()->ToString(), allocator).View(); + } + if (lit->IsStringLiteral()) { + return lit->AsStringLiteral()->Str(); + } + if (lit->IsUndefinedLiteral()) { + return util::UString(lit->AsUndefinedLiteral()->ToString(), allocator).View(); + } + if (lit->IsNullLiteral()) { + return util::UString(lit->AsNullLiteral()->ToString(), allocator).View(); + } + ES2PANDA_UNREACHABLE(); + }; -ir::AstNode *ConstantExpressionLowering::UnFoldEnumMemberExpression(ir::AstNode *constantNode) -{ - ir::NodeTransformer handleUnfoldEnumMember = [this, constantNode](ir::AstNode *const node) { - if (node->IsMemberExpression() && !node->Parent()->IsMemberExpression()) { - auto memExp = node->AsMemberExpression(); - return FindAndReplaceEnumMember(memExp, constantNode); + util::UString result(allocator); + auto quasis = expr->Quasis(); + auto expressions = expr->Expressions(); + + if (!quasis[0]->Raw().Empty()) { + result.Append(quasis[0]->Cooked()); + } + + auto const num = expressions.size(); + std::size_t i = 0U; + while (i < num) { + result.Append(litToString(expressions[i]->AsLiteral())); + if (!quasis[++i]->Raw().Empty()) { + result.Append(quasis[i]->Cooked()); } + } - return node; - }; - constantNode->TransformChildrenRecursivelyPostorder(handleUnfoldEnumMember, Name()); - return constantNode; + auto *strLit = util::NodeAllocator::Alloc(allocator, result.View()); + strLit->SetParent(expr->Parent()); + strLit->SetRange(expr->Range()); + return strLit; } -ir::AstNode *ConstantExpressionLowering::FindNameInEnumMember(ArenaVector *members, - util::StringView targetName) +static varbinder::Variable *ResolveIdentifier(const ir::Identifier *ident) { - auto it = std::find_if(members->begin(), members->end(), [&targetName](ir::AstNode *member) { - return member->AsTSEnumMember()->Key()->AsIdentifier()->Name() == targetName; - }); - return (it != members->end()) ? *it : nullptr; + if (ident->Variable() != nullptr) { + return ident->Variable(); + } + + varbinder::ResolveBindingOptions option = + varbinder::ResolveBindingOptions::ALL_DECLARATION | varbinder::ResolveBindingOptions::ALL_VARIABLES; + + varbinder::Scope *scope = NearestScope(ident); + auto *resolved = scope->Find(ident->Name(), option).variable; + return resolved; } -ir::AstNode *ConstantExpressionLowering::FindAndReplaceEnumMember(ir::MemberExpression *expr, ir::AstNode *node) +static varbinder::Variable *ResolveMemberExpressionProperty(ir::MemberExpression *me) { - if (!expr->Object()->IsIdentifier()) { - return expr; + varbinder::Variable *var = nullptr; + auto meObject = me->Object(); + if (meObject->IsMemberExpression()) { + var = ResolveMemberExpressionProperty(meObject->AsMemberExpression()); + } else if (meObject->IsIdentifier()) { + var = ResolveIdentifier(meObject->AsIdentifier()); + } + + if (var == nullptr) { + return nullptr; } - auto objectName = expr->Object()->AsIdentifier()->Name(); - auto propertyName = expr->Property()->AsIdentifier()->Name(); - for (auto curScope = node->Scope(); curScope != nullptr; curScope = curScope->Parent()) { - auto *foundDecl = curScope->FindDecl(objectName); - if (foundDecl == nullptr || !foundDecl->Node()->IsTSEnumDeclaration()) { - continue; + auto decl = var->Declaration(); + if (decl->IsClassDecl()) { + // NOTE(gogabr) : for some reason, ETSGLOBAL points to class declaration instead of definition. + auto *declNode = decl->AsClassDecl()->Node(); + auto *classDef = declNode->IsClassDefinition() ? declNode->AsClassDefinition() + : declNode->IsClassDeclaration() ? declNode->AsClassDeclaration()->Definition() + : nullptr; + ES2PANDA_ASSERT(classDef != nullptr); + + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) + auto scope = classDef->Scope(); + auto option = var->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE_OR_ENUM) + ? varbinder::ResolveBindingOptions::STATIC_DECLARATION | + varbinder::ResolveBindingOptions::STATIC_VARIABLES + : varbinder::ResolveBindingOptions::DECLARATION | varbinder::ResolveBindingOptions::VARIABLES; + return scope->FindLocal(me->Property()->AsIdentifier()->Name(), option); + } + + return nullptr; +} + +static bool IsConstantExpression(ir::AstNode *expr) +{ + if (!expr->IsExpression()) { + if (expr->IsETSTypeReference()) { + return false; } + } - auto members = foundDecl->Node()->AsTSEnumDeclaration()->Members(); - auto member = FindNameInEnumMember(&members, propertyName); - if (member != nullptr) { - auto *transformedInit = member->AsTSEnumMember()->Init(); - if (transformedInit == nullptr) { - return expr; - } + if (expr->IsETSPrimitiveType()) { + return true; + } + + if (expr->IsIdentifier()) { + auto var = ResolveIdentifier(expr->AsIdentifier()); + return var != nullptr && var->Declaration()->IsConstDecl(); + } - auto clonedInit = transformedInit->Clone(context_->allocator, transformedInit->Parent()); - clonedInit->SetRange(expr->Range()); - return UnFoldEnumMemberExpression(clonedInit); + if (expr->IsMemberExpression()) { + auto me = expr->AsMemberExpression(); + if (me->Kind() != ir::MemberExpressionKind::PROPERTY_ACCESS) { + return false; } + + auto var = ResolveMemberExpressionProperty(me); + return var != nullptr && var->Declaration()->IsReadonlyDecl(); } - return expr; -} -varbinder::Variable *ConstantExpressionLowering::FindIdentifier(ir::Identifier *ident) -{ - auto localCtx = varbinder::LexicalScope::Enter(varbinder_, NearestScope(ident)); - auto option = varbinder::ResolveBindingOptions::ALL_VARIABLES; - auto *resolved = localCtx.GetScope()->FindInFunctionScope(ident->Name(), option).variable; - if (resolved == nullptr) { - resolved = localCtx.GetScope()->FindInGlobal(ident->Name(), option).variable; + if (IsSupportedLiteral(expr->AsExpression())) { + return true; } - return resolved; + + auto isNotConstantExpression = [](ir::AstNode *node) { return !IsConstantExpression(node); }; + + return (expr->IsBinaryExpression() || expr->IsUnaryExpression() || expr->IsTSAsExpression() || + expr->IsConditionalExpression() || expr->IsTemplateLiteral()) && + !expr->IsAnyChild(isNotConstantExpression); } -ir::AstNode *ConstantExpressionLowering::UnfoldConstIdentifier(ir::AstNode *node, ir::AstNode *originNode) +ir::AstNode *ConstantExpressionLowering::UnfoldResolvedReference(ir::AstNode *resolved, ir::AstNode *node) { ir::AstNode *resNode = nullptr; - if (node->IsClassProperty()) { - auto prop = node->AsClassElement(); - resNode = prop->Value()->Clone(context_->allocator, originNode->Parent()); - resNode->SetRange(originNode->Range()); + if (resolved->IsClassProperty()) { + auto propVal = resolved->AsClassElement()->Value(); + if (propVal != nullptr && IsConstantExpression(propVal)) { + resNode = propVal->Clone(context_->allocator, node->Parent()); + resNode->SetRange(node->Range()); + } + } else if (resolved->Parent()->IsVariableDeclarator()) { + auto init = resolved->Parent()->AsVariableDeclarator()->Init(); + if (init != nullptr && IsConstantExpression(init)) { + resNode = init->Clone(context_->allocator, node->Parent()); + resNode->SetRange(node->Range()); + } + } + + if (resNode != nullptr) { + return MaybeUnfold(resNode); } - if (node->Parent()->IsVariableDeclarator()) { - resNode = node->Parent()->AsVariableDeclarator()->Init()->Clone(context_->allocator, originNode->Parent()); - resNode->SetRange(originNode->Range()); + + // failed to unfold + return node; +} + +ir::AstNode *ConstantExpressionLowering::MaybeUnfoldIdentifier(ir::Identifier *node) +{ + if (!node->IsReference(varbinder_->Extension())) { + return node; } - if (resNode == nullptr) { + + auto *resolved = ResolveIdentifier(node); + if (resolved == nullptr || !resolved->Declaration()->IsConstDecl()) { return node; } - if (!resNode->IsIdentifier()) { - return UnfoldConstIdentifiers(resNode); + return UnfoldResolvedReference(resolved->Declaration()->Node(), node); +} + +ir::AstNode *ConstantExpressionLowering::MaybeUnfoldMemberExpression(ir::MemberExpression *node) +{ + if (node->Kind() != ir::MemberExpressionKind::PROPERTY_ACCESS) { + return node; } - auto *ident = resNode->AsIdentifier(); - auto *resolved = FindIdentifier(ident); - if (resolved == nullptr) { - return resNode; + + if (auto *const property = node->Property(); property->IsLiteral()) { + property->SetParent(node->Parent()); + property->SetRange(node->Range()); + return property; } - if (!resolved->Declaration()->IsConstDecl()) { - return resNode; + + auto resolved = ResolveMemberExpressionProperty(node); + if (resolved == nullptr || !resolved->Declaration()->IsReadonlyDecl()) { + return node; } - return UnfoldConstIdentifier(resolved->Declaration()->Node(), resNode); + return UnfoldResolvedReference(resolved->Declaration()->Node(), node); } -ir::AstNode *ConstantExpressionLowering::UnfoldConstIdentifiers(ir::AstNode *constantNode) +ir::AstNode *ConstantExpressionLowering::MaybeUnfold(ir::AstNode *node) { - ir::NodeTransformer handleUnfoldIdentifiers = [this](ir::AstNode *const node) { - if (node->IsIdentifier()) { - auto *ident = node->AsIdentifier(); - auto *resolved = FindIdentifier(ident); - if (resolved == nullptr) { - return node; - } - if (!resolved->Declaration()->IsConstDecl()) { - return node; - } - return UnfoldConstIdentifier(resolved->Declaration()->Node(), node); + ir::NodeTransformer handleMaybeUnfold = [this](ir::AstNode *const n) { + if (auto const *const parent = n->Parent(); + parent->IsMemberExpression() && parent->AsMemberExpression()->Property() == n && + parent->AsMemberExpression()->Kind() != ir::MemberExpressionKind::ELEMENT_ACCESS) { + return n; } - return node; + + if (n->IsIdentifier()) { + return MaybeUnfoldIdentifier(n->AsIdentifier()); + } + + if (n->IsMemberExpression()) { + return MaybeUnfoldMemberExpression(n->AsMemberExpression()); + } + + return n; }; - constantNode->TransformChildrenRecursivelyPostorder(handleUnfoldIdentifiers, Name()); - return constantNode; + + node->TransformChildrenRecursivelyPostorder(handleMaybeUnfold, Name()); + return handleMaybeUnfold(node); } static bool IsPotentialConstant(const ir::AstNodeType type) @@ -885,48 +1433,48 @@ static bool IsPotentialConstant(const ir::AstNodeType type) type == ir::AstNodeType::CONDITIONAL_EXPRESSION || type == ir::AstNodeType::IDENTIFIER; } -ir::AstNode *ConstantExpressionLowering::FoldConstant(ir::AstNode *constantNode) +ir::AstNode *ConstantExpressionLowering::Fold(ir::AstNode *constantNode) { ir::NodeTransformer handleFoldConstant = [this](ir::AstNode *const node) { if (node->IsTemplateLiteral()) { auto tmpLiteral = node->AsTemplateLiteral(); - if (tmpLiteral->Expressions().empty()) { - return FoldMultilineString(tmpLiteral); + auto exprs = tmpLiteral->Expressions(); + auto notSupportedLit = std::find_if(exprs.begin(), exprs.end(), + [](ir::Expression *maybeLit) { return !IsSupportedLiteral(maybeLit); }); + // Cannot fold TemplateLiteral containing unsupported literal + if (notSupportedLit != exprs.end()) { + return node; } - LogError(diagnostic::STRING_INTERPOLATION_NOT_CONSTANT, {}, node->Start()); + return FoldTemplateLiteral(tmpLiteral, context_->allocator); } if (node->IsTSAsExpression()) { auto tsAsExpr = node->AsTSAsExpression(); if (IsSupportedLiteral(tsAsExpr->Expr())) { - return FoldTSAsExpression(tsAsExpr); + return FoldTSAsExpression(tsAsExpr, context_->allocator); } - LogError(diagnostic::ONLY_CONSTANT_EXPRESSION, {}, node->Start()); } if (node->IsUnaryExpression()) { auto unaryOp = node->AsUnaryExpression(); if (IsSupportedLiteral(unaryOp->Argument())) { - return FoldUnaryConstant(unaryOp); + return FoldUnaryExpression(unaryOp, context_); } - LogError(diagnostic::ONLY_CONSTANT_EXPRESSION, {}, node->Start()); } if (node->IsBinaryExpression()) { auto binop = node->AsBinaryExpression(); if (IsSupportedLiteral(binop->Left()) && IsSupportedLiteral(binop->Right())) { - return FoldBinaryConstant(binop); + return FoldBinaryExpression(binop, context_); } - LogError(diagnostic::ONLY_CONSTANT_EXPRESSION, {}, node->Start()); } if (node->IsConditionalExpression()) { auto condExp = node->AsConditionalExpression(); if (IsSupportedLiteral(condExp->Test())) { return FoldTernaryConstant(condExp); } - LogError(diagnostic::ONLY_CONSTANT_EXPRESSION, {}, node->Start()); } return node; }; constantNode->TransformChildrenRecursivelyPostorder(handleFoldConstant, Name()); - return constantNode; + return TryToCorrectNumberOrCharLiteral(handleFoldConstant(constantNode), context_); } // Note: memberExpression can be constant when it is enum property access, this check will be enabled after Issue23082. @@ -998,20 +1546,14 @@ bool ConstantExpressionLowering::PerformForModule(public_lib::Context *ctx, pars context_ = ctx; program_ = program; varbinder_ = ctx->parserProgram->VarBinder()->AsETSBinder(); + program->Ast()->TransformChildrenRecursively( [this](ir::AstNode *const node) -> AstNodePtr { - if (node->IsAnnotationDeclaration() || node->IsAnnotationUsage()) { - return FoldConstant(UnfoldConstIdentifiers(node)); - } - if (node->IsTSEnumDeclaration()) { - return FoldConstant(UnFoldEnumMemberExpression(UnfoldConstIdentifiers(node))); - } - // Note: Package need to check whether its immediate initializer is const expression. if (this->program_->IsPackage() && node->IsClassDefinition() && node->AsClassDefinition()->IsGlobal()) { TryFoldInitializerOfPackage(node->AsClassDefinition()); } - return node; + return Fold(MaybeUnfold(node)); }, Name()); diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.h b/ets2panda/compiler/lowering/ets/constantExpressionLowering.h index 8d9c3e77a1..0bf1aead0f 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.h +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.h @@ -22,7 +22,9 @@ namespace ark::es2panda::compiler { enum class TypeRank { // Keep this order + INT8, CHAR, + INT16, INT32, INT64, FLOAT, @@ -39,77 +41,14 @@ public: bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; private: - void LogError(const diagnostic::DiagnosticKind &diagnostic, const util::DiagnosticMessageParams &diagnosticParams, - const lexer::SourcePosition &pos) const; + ir::AstNode *MaybeUnfold(ir::AstNode *node); + ir::AstNode *MaybeUnfoldIdentifier(ir::Identifier *node); + ir::AstNode *MaybeUnfoldMemberExpression(ir::MemberExpression *node); + ir::AstNode *UnfoldResolvedReference(ir::AstNode *resolved, ir::AstNode *node); + ir::AstNode *Fold(ir::AstNode *constantNode); ir::AstNode *FoldTernaryConstant(ir::ConditionalExpression *cond); - template - bool PerformRelationOperator(InputType left, InputType right, lexer::TokenType opType); - - bool HandleRelationOperator(ir::Literal *left, ir::Literal *right, lexer::TokenType opType); - - bool HandleBitwiseLogicalOperator(ir::Literal *left, ir::Literal *right, lexer::TokenType opType); - - ir::AstNode *HandleLogicalOperator(ir::BinaryExpression *expr, lexer::TokenType opType); - - ir::AstNode *FoldBinaryBooleanConstant(ir::BinaryExpression *expr); - - template - IntegerType PerformBitwiseArithmetic(IntegerType left, IntegerType right, lexer::TokenType operationType); - - template - lexer::Number HandleBitwiseOperator(TargetType leftNum, TargetType rightNum, lexer::TokenType operationType, - TypeRank targetRank); - - template - TargetType HandleArithmeticOperation(TargetType leftNum, TargetType rightNum, ir::BinaryExpression *expr); - - template - ir::AstNode *FoldBinaryNumericConstantHelper(ir::BinaryExpression *expr, TypeRank targetRank); - - ir::AstNode *FoldBinaryNumericConstant(ir::BinaryExpression *expr); - - ir::AstNode *FoldBinaryStringConstant(ir::BinaryExpression *expr); - - ir::AstNode *FoldBinaryConstant(ir::BinaryExpression *expr); - - template - lexer::Number HandleBitwiseNegate(InputType value, TypeRank rank); - - template - ir::AstNode *FoldUnaryNumericConstantHelper(ir::UnaryExpression *unary, ir::Literal *node, TypeRank rank); - - ir::AstNode *FoldUnaryNumericConstant(ir::UnaryExpression *unary); - - ir::AstNode *FoldUnaryBooleanConstant(ir::UnaryExpression *unary); - - ir::AstNode *FoldUnaryConstant(ir::UnaryExpression *unary); - - ir::AstNode *TryFoldTSAsExpressionForString(ir::TSAsExpression *expr); - - ir::AstNode *FoldTSAsExpressionToChar(ir::TSAsExpression *expr); - - ir::AstNode *FoldTSAsExpressionToBoolean(ir::TSAsExpression *expr); - - ir::AstNode *FoldTSAsExpression(ir::TSAsExpression *expr); - - ir::AstNode *FoldMultilineString(ir::TemplateLiteral *expr); - - ir::AstNode *FoldConstant(ir::AstNode *constantNode); - - varbinder::Variable *FindIdentifier(ir::Identifier *ident); - - ir::AstNode *UnfoldConstIdentifier(ir::AstNode *node, ir::AstNode *originNode); - - ir::AstNode *UnFoldEnumMemberExpression(ir::AstNode *constantNode); - - ir::AstNode *FindNameInEnumMember(ArenaVector *members, util::StringView targetName); - - ir::AstNode *FindAndReplaceEnumMember(ir::MemberExpression *expr, ir::AstNode *node); - - ir::AstNode *UnfoldConstIdentifiers(ir::AstNode *constantNode); - void IsInitByConstant(ir::AstNode *node); void TryFoldInitializerOfPackage(ir::ClassDefinition *globalClass); diff --git a/ets2panda/compiler/lowering/ets/enumLowering.cpp b/ets2panda/compiler/lowering/ets/enumLowering.cpp index 7a524ec4aa..213f565763 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumLowering.cpp @@ -391,11 +391,13 @@ ir::ScriptFunction *EnumLoweringPhase::CreateFunctionForCtorOfEnumClass(ir::Clas thisExpr, fieldIdentifier, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); auto *rightHandSide = checker_->AllocNode(PARAM_ORDINAL, Allocator()); rightHandSide->SetVariable(inputOrdinalParam->Ident()->Variable()); - auto *initializer = checker_->AllocNode(leftHandSide, rightHandSide, - lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - auto initStatement = checker_->AllocNode(initializer); - initStatement->SetParent(body); - body->Statements().push_back(initStatement); + if (!enumClass->IsDeclare()) { + auto *initializer = checker_->AllocNode(leftHandSide, rightHandSide, + lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + auto initStatement = checker_->AllocNode(initializer); + initStatement->SetParent(body); + body->Statements().push_back(initStatement); + } return func; } @@ -407,7 +409,7 @@ void EnumLoweringPhase::CreateCtorForEnumClass(ir::ClassDefinition *const enumCl auto *const identClone = func->Id()->Clone(Allocator(), nullptr); auto *const methodDef = checker_->AllocNode( - ir::MethodDefinitionKind::CONSTRUCTOR, identClone, funcExpr, ir::ModifierFlags::PUBLIC, Allocator(), false); + ir::MethodDefinitionKind::CONSTRUCTOR, identClone, funcExpr, ir::ModifierFlags::PRIVATE, Allocator(), false); methodDef->SetParent(enumClass); enumClass->Body().push_back(methodDef); } @@ -595,8 +597,7 @@ ir::Identifier *EnumLoweringPhase::CreateEnumValuesArray(const ir::TSEnumDeclara lexer::Number(member->AsTSEnumMember() ->Init() ->AsNumberLiteral() - ->Number() - .GetValue())); + ->Number())); return enumValueLiteral; }); // clang-format on diff --git a/ets2panda/compiler/lowering/ets/enumLowering.h b/ets2panda/compiler/lowering/ets/enumLowering.h index 75a38b23fd..e62fb133c2 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.h +++ b/ets2panda/compiler/lowering/ets/enumLowering.h @@ -24,17 +24,17 @@ namespace ark::es2panda::compiler { class EnumLoweringPhase : public PhaseForDeclarations { public: - static constexpr std::string_view const STRING_REFERENCE_TYPE {"String"}; - static constexpr std::string_view const IDENTIFIER_I {"i"}; - static constexpr std::string_view const PARAM_NAME {"name"}; - static constexpr std::string_view const PARAM_VALUE {"value"}; - static constexpr std::string_view const PARAM_ORDINAL {"ordinal"}; - static constexpr std::string_view const STRING_VALUES_ARRAY_NAME {"#StringValuesArray"}; - static constexpr std::string_view const ITEMS_ARRAY_NAME {"#ItemsArray"}; - static constexpr std::string_view const NAMES_ARRAY_NAME {"#NamesArray"}; - static constexpr std::string_view const VALUES_ARRAY_NAME {"#ValuesArray"}; - static constexpr std::string_view const ORDINAL_NAME {"#ordinal"}; - static constexpr std::string_view const BASE_CLASS_NAME {"BaseEnum"}; + static constexpr std::string_view STRING_REFERENCE_TYPE {"String"}; + static constexpr std::string_view IDENTIFIER_I {"i"}; + static constexpr std::string_view PARAM_NAME {"name"}; + static constexpr std::string_view PARAM_VALUE {"value"}; + static constexpr std::string_view PARAM_ORDINAL {"ordinal"}; + static constexpr std::string_view ITEMS_ARRAY_NAME {"#ItemsArray"}; + static constexpr std::string_view STRING_VALUES_ARRAY_NAME {checker::ETSEnumType::STRING_VALUES_ARRAY_NAME}; + static constexpr std::string_view NAMES_ARRAY_NAME {checker::ETSEnumType::NAMES_ARRAY_NAME}; + static constexpr std::string_view VALUES_ARRAY_NAME {checker::ETSEnumType::VALUES_ARRAY_NAME}; + static constexpr std::string_view ORDINAL_NAME {"#ordinal"}; + static constexpr std::string_view BASE_CLASS_NAME {"BaseEnum"}; enum EnumType { INT = 0, LONG = 1, STRING = 2 }; diff --git a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp index 3fb0f59817..5badcb8516 100644 --- a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp @@ -91,7 +91,9 @@ static EnumCastType NeedHandleEnumCasting(ir::TSAsExpression *node) { auto type = node->TsType(); EnumCastType castType = EnumCastType::NONE; - if (type->IsETSStringType()) { + if (type == nullptr) { + return castType; + } else if (type->IsETSStringType()) { castType = EnumCastType::CAST_TO_STRING; } else if (type->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC) || (type->IsETSObjectType() && @@ -325,15 +327,28 @@ ir::AstNode *EnumPostCheckLoweringPhase::GenerateEnumCasting(ir::TSAsExpression return node; } +static auto *InlineValueOf(ir::MemberExpression *enumMemberRef, ArenaAllocator *allocator) +{ + auto key = enumMemberRef->Property()->AsIdentifier()->Name().Utf8(); + auto enumType = enumMemberRef->TsType()->AsETSEnumType(); + auto ord = enumType->GetOrdinalFromMemberName(key); + auto origLiteral = enumType->GetValueLiteralFromOrdinal(ord); + auto literal = origLiteral->Clone(allocator, enumMemberRef->Parent())->AsExpression(); + literal->SetTsType(origLiteral->TsType()); + return literal; +} + ir::AstNode *EnumPostCheckLoweringPhase::GenerateValueOfCall(ir::AstNode *const node) { - node->Parent()->AddAstNodeFlags(ir::AstNodeFlags::RECHECK); + node->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); if (!node->IsExpression()) { - node->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); return node; } + if (node->AsExpression()->TsType()->AsETSEnumType()->NodeIsEnumLiteral(node->AsExpression())) { + return InlineValueOf(node->AsMemberExpression(), checker_->Allocator()); + } + node->Parent()->AddAstNodeFlags(ir::AstNodeFlags::RECHECK); auto *callExpr = CreateCallInstanceEnumExpression(checker_, node, checker::ETSEnumType::VALUE_OF_METHOD_NAME); - node->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); return callExpr; } @@ -403,7 +418,7 @@ bool EnumPostCheckLoweringPhase::PerformForModule(public_lib::Context *ctx, pars } return GenerateEnumCasting(node->AsTSAsExpression(), castFlag); } - if (node->IsSwitchStatement() && node->AsSwitchStatement()->Discriminant()->TsType()->IsETSEnumType()) { + if (node->IsSwitchStatement() && node->AsSwitchStatement()->Discriminant()->TsType() && node->AsSwitchStatement()->Discriminant()->TsType()->IsETSEnumType()) { return GenerateGetOrdinalCallForSwitch(node->AsSwitchStatement()); } return node; diff --git a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h index 867cc73f8a..d765846356 100644 --- a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h +++ b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.h @@ -29,7 +29,7 @@ enum class EnumCastType { CAST_TO_STRING_ENUM, }; -class EnumPostCheckLoweringPhase : public PhaseForBodies { +class EnumPostCheckLoweringPhase : public PhaseForDeclarations { public: EnumPostCheckLoweringPhase() noexcept = default; std::string_view Name() const override diff --git a/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp b/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp new file mode 100644 index 0000000000..3891497c8e --- /dev/null +++ b/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "enumPropertiesInAnnotationsLowering.h" +#include "ir/base/classProperty.h" +#include "checker/types/ets/etsArrayType.h" +#include "checker/types/ets/etsEnumType.h" +#include "ir/base/classProperty.h" + +namespace ark::es2panda::compiler { + +static void TransformEnumArrayRecursively(checker::ETSArrayType *propType) +{ + if (propType->ElementType()->IsETSEnumType()) { + auto newElemType = propType->ElementType()->AsETSEnumType()->Underlying(); + propType->SetElementType(newElemType); + return; + } + if (propType->ElementType()->IsETSArrayType()) { + TransformEnumArrayRecursively(propType->ElementType()->AsETSArrayType()); + } +} + +static void SetValueType(ir::Expression *value, checker::Type *newType) +{ + if (value->Variable() != nullptr) { + value->Variable()->SetTsType(newType); + } + value->SetTsType(newType); + if (newType->IsETSArrayType() && newType->AsETSArrayType()->ElementType()->IsETSArrayType()) { + for (auto elem : value->AsArrayExpression()->Elements()) { + SetValueType(elem, newType->AsETSArrayType()->ElementType()); + } + } +} + +static void TransformEnumToUnderlying(ir::ClassProperty *prop, checker::Checker *checker) +{ + checker::Type *propType = prop->TsType(); + checker::Type *newPropType {}; + if (propType->IsETSEnumType()) { + prop->SetTypeAnnotation(nullptr); + newPropType = propType->AsETSEnumType()->Underlying(); + } else if (propType->IsETSArrayType()) { + prop->SetTypeAnnotation(nullptr); + newPropType = propType->Clone(checker); + TransformEnumArrayRecursively(newPropType->AsETSArrayType()); + } else { + return; + } + prop->SetTsType(newPropType); + prop->Key()->SetTsType(newPropType); + prop->Key()->Variable()->SetTsType(newPropType); + if (prop->Value() != nullptr) { + SetValueType(prop->Value(), newPropType); + } +} + +bool EnumPropertiesInAnnotationsLoweringPhase::PerformForModule([[maybe_unused]] public_lib::Context *ctx, + parser::Program *program) +{ + auto *checker = ctx->checker; + program->Ast()->IterateRecursively([checker](auto *node) { + if (node->IsAnnotationDeclaration() || node->IsAnnotationUsage()) { + node->Iterate([checker](auto *child) { + child->IsClassProperty() ? TransformEnumToUnderlying(child->AsClassProperty(), checker) : void(); + }); + } + }); + return true; +} + +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.h b/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.h new file mode 100644 index 0000000000..c5869ede39 --- /dev/null +++ b/ets2panda/compiler/lowering/ets/enumPropertiesInAnnotationsLowering.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_ENUM_PROPERTIES_IN_ANNOTATIONS_LOWERING_H +#define ES2PANDA_COMPILER_ENUM_PROPERTIES_IN_ANNOTATIONS_LOWERING_H + +#include "compiler/lowering/phase.h" + +namespace ark::es2panda::compiler { + +class EnumPropertiesInAnnotationsLoweringPhase : public PhaseForDeclarations { +public: + EnumPropertiesInAnnotationsLoweringPhase() noexcept = default; + std::string_view Name() const override + { + return "EnumPropertiesInAnnotationsLoweringPhase"; + } + bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; +}; + +} // namespace ark::es2panda::compiler + +#endif // ES2PANDA_COMPILER_ENUM_PROPERTIES_IN_ANNOTATIONS_LOWERING_H diff --git a/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp b/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp index 59f3c0a0cc..3afbd0dc32 100644 --- a/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp +++ b/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp @@ -64,7 +64,7 @@ std::string GenericBridgesPhase::CreateMethodDefinitionString(ir::ClassDefinitio } typeNodes.emplace_back(checker->AllocNode( - const_cast(derivedFunction->Signature()->ReturnType()), checker->Allocator())); + const_cast(baseSignature->ReturnType()), checker->Allocator())); str1 += "): @@T" + std::to_string(typeNodes.size()) + ' '; typeNodes.emplace_back(checker->AllocNode( @@ -78,7 +78,7 @@ std::string GenericBridgesPhase::CreateMethodDefinitionString(ir::ClassDefinitio void GenericBridgesPhase::AddGenericBridge(ir::ClassDefinition const *const classDefinition, ir::MethodDefinition *const methodDefinition, checker::Signature const *baseSignature, - ir::ScriptFunction const *const derivedFunction) const + ir::ScriptFunction *const derivedFunction) const { auto *parser = context_->parser->AsETSParser(); std::vector typeNodes {}; @@ -116,13 +116,17 @@ void GenericBridgesPhase::AddGenericBridge(ir::ClassDefinition const *const clas auto *methodType = methodDefinition->Id()->Variable()->TsType()->AsETSFunctionType(); checker->BuildFunctionSignature(bridgeMethod->Function()); + bridgeMethod->Function()->Signature()->AddSignatureFlag(checker::SignatureFlags::BRIDGE); + auto *const bridgeMethodType = checker->BuildMethodType(bridgeMethod->Function()); - checker->CheckIdenticalOverloads(methodType, bridgeMethodType, bridgeMethod); + checker->CheckIdenticalOverloads(methodType, bridgeMethodType, bridgeMethod, false, + checker::TypeRelationFlag::NONE); bridgeMethod->SetTsType(bridgeMethodType); methodType->AddCallSignature(bridgeMethod->Function()->Signature()); methodDefinition->Id()->Variable()->SetTsType(methodType); - bridgeMethod->Check(checker); + bridgeMethod->Function()->Body()->Check( + checker); // avoid checking overriding, this may fail if only return type is different. } void GenericBridgesPhase::ProcessScriptFunction(ir::ClassDefinition const *const classDefinition, @@ -156,11 +160,13 @@ void GenericBridgesPhase::ProcessScriptFunction(ir::ClassDefinition const *const } baseSignature2 = baseSignature2->Substitute(relation, substitutions.derivedConstraints); - ir::ScriptFunction const *derivedFunction = nullptr; + ir::ScriptFunction *derivedFunction = nullptr; checker::ETSFunctionType const *methodType = derivedMethod->Id()->Variable()->TsType()->AsETSFunctionType(); for (auto *signature : methodType->CallSignatures()) { signature = signature->Substitute(relation, substitutions.derivedConstraints); - if (overrides(baseSignature1, signature) || checker->HasSameAssemblySignature(baseSignature1, signature)) { + // A special case is when the overriding function's return type is going to be unboxed. + if ((overrides(baseSignature1, signature) || checker->HasSameAssemblySignature(baseSignature1, signature)) && + baseSignature1->ReturnType()->IsETSUnboxableObject() == signature->ReturnType()->IsETSUnboxableObject()) { // NOTE: we already have custom-implemented method with the required bridge signature. // Probably sometimes we will issue warning notification here... return; diff --git a/ets2panda/compiler/lowering/ets/genericBridgesLowering.h b/ets2panda/compiler/lowering/ets/genericBridgesLowering.h index 508c4160ff..4fafc089c6 100644 --- a/ets2panda/compiler/lowering/ets/genericBridgesLowering.h +++ b/ets2panda/compiler/lowering/ets/genericBridgesLowering.h @@ -54,7 +54,7 @@ private: ir::MethodDefinition *derivedMethod, Substitutions const &substitutions) const; void AddGenericBridge(ir::ClassDefinition const *classDefinition, ir::MethodDefinition *methodDefinition, - checker::Signature const *baseSignature, ir::ScriptFunction const *derivedFunction) const; + checker::Signature const *baseSignature, ir::ScriptFunction *derivedFunction) const; std::string CreateMethodDefinitionString(ir::ClassDefinition const *classDefinition, checker::Signature const *baseSignature, diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 28e9a1c0ab..ed062d4a3e 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -1123,8 +1123,14 @@ static ir::AstNode *InsertInvokeCall(public_lib::Context *ctx, ir::CallExpressio newCallee->SetTsType(prop->TsType()); newCallee->SetObjectType(ifaceType); + /* Pull out substituted call signature */ + auto *funcIface = + ifaceType->HasObjectFlag(checker::ETSObjectFlags::INTERFACE) ? ifaceType : ifaceType->Interfaces()[0]; + checker::Signature *callSig = funcIface->GetFunctionalInterfaceInvokeType()->CallSignatures()[0]; + ES2PANDA_ASSERT(callSig != nullptr); + call->SetCallee(newCallee); - call->SetSignature(prop->TsType()->AsETSFunctionType()->CallSignatures()[0]); + call->SetSignature(callSig); /* NOTE(gogabr): argument types may have been spoiled by widening/narrowing conversions. Repair them here. diff --git a/ets2panda/compiler/lowering/ets/opAssignment.cpp b/ets2panda/compiler/lowering/ets/opAssignment.cpp index af57069fdd..682e53d8e8 100644 --- a/ets2panda/compiler/lowering/ets/opAssignment.cpp +++ b/ets2panda/compiler/lowering/ets/opAssignment.cpp @@ -128,15 +128,15 @@ static std::string GenFormatForExpression(ir::Expression *expr, size_t ix1, size if ((kind & ir::MemberExpressionKind::PROPERTY_ACCESS) != 0) { res += ".@@I" + std::to_string(ix2); } else if (kind == ir::MemberExpressionKind::ELEMENT_ACCESS) { - res += "[@@I" + std::to_string(ix2) + "]"; + res += "[@@E" + std::to_string(ix2) + "]"; } } return res; } -static ir::Identifier *GetClone(ArenaAllocator *allocator, ir::Identifier *node) +static ir::Expression *GetClone(ArenaAllocator *allocator, ir::Expression *node) { - return node == nullptr ? nullptr : node->Clone(allocator, nullptr); + return node == nullptr ? nullptr : node->Clone(allocator, nullptr)->AsExpression(); } static std::string GetFormatPlaceholder(const ir::Expression *expr, const size_t counter) @@ -292,7 +292,7 @@ ir::AstNode *HandleOpAssignment(public_lib::Context *ctx, ir::AssignmentExpressi struct ArgumentInfo { std::string newAssignmentStatements {}; ir::Identifier *id1 = nullptr; - ir::Identifier *id2 = nullptr; + ir::Expression *id2 = nullptr; ir::Identifier *id3 = nullptr; ir::Expression *object = nullptr; ir::Expression *property = nullptr; @@ -309,12 +309,12 @@ static void ParseArgument(public_lib::Context *ctx, ir::Expression *argument, Ar } if (argument->IsIdentifier()) { - info.id1 = GetClone(allocator, argument->AsIdentifier()); + info.id1 = GetClone(allocator, argument->AsIdentifier())->AsIdentifier(); } else if (argument->IsMemberExpression()) { auto *memberExpression = argument->AsMemberExpression(); if (info.object = memberExpression->Object(); info.object != nullptr && info.object->IsIdentifier()) { - info.id1 = GetClone(allocator, info.object->AsIdentifier()); + info.id1 = GetClone(allocator, info.object->AsIdentifier())->AsIdentifier(); } else if (info.object != nullptr) { info.id1 = Gensym(allocator); info.newAssignmentStatements = "const @@I1 = (@@E2) as @@T3; "; @@ -323,9 +323,13 @@ static void ParseArgument(public_lib::Context *ctx, ir::Expression *argument, Ar if (info.property = memberExpression->Property(); info.property != nullptr && info.property->IsIdentifier()) { info.id2 = GetClone(allocator, info.property->AsIdentifier()); + } else if (info.property != nullptr && info.property->IsLiteral()) { + // Be careful not to disturb tuple element access + info.id2 = GetClone(allocator, info.property); } else if (info.property != nullptr) { info.id2 = Gensym(allocator); - info.newAssignmentStatements += "const @@I4 = (@@E5) as @@T6; "; + info.newAssignmentStatements += "const @@I4 = (@@E5) as @@T6;"; + info.newAssignmentStatements += ";"; info.propType = info.property->TsType(); } } diff --git a/ets2panda/compiler/lowering/ets/opAssignment.h b/ets2panda/compiler/lowering/ets/opAssignment.h index 6a45b47b29..adbc88070f 100644 --- a/ets2panda/compiler/lowering/ets/opAssignment.h +++ b/ets2panda/compiler/lowering/ets/opAssignment.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -22,9 +22,10 @@ namespace ark::es2panda::compiler { class OpAssignmentLowering : public PhaseForBodies { public: + static constexpr std::string_view const NAME = "OpAssignmentLowering"; std::string_view Name() const override { - return "OpAssignmentLowering"; + return NAME; } bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; diff --git a/ets2panda/compiler/lowering/ets/recordLowering.cpp b/ets2panda/compiler/lowering/ets/recordLowering.cpp index d8e2cfc9d7..504b42d93b 100644 --- a/ets2panda/compiler/lowering/ets/recordLowering.cpp +++ b/ets2panda/compiler/lowering/ets/recordLowering.cpp @@ -152,6 +152,21 @@ ir::Statement *RecordLowering::CreateStatement(const std::string &src, ir::Expre return nullptr; } +void RecordLowering::CheckKeyType(checker::ETSChecker *checker, checker::Type const *const keyType, + ir::ObjectExpression const *const expr, public_lib::Context *ctx) const noexcept +{ + if (keyType->IsETSObjectType()) { + if (keyType->IsETSStringType() || + checker->Relation()->IsIdenticalTo(keyType, checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType()) || + checker->Relation()->IsIdenticalTo(keyType, checker->GetGlobalTypesHolder()->GlobalIntegralBuiltinType()) || + keyType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_NUMERIC) || + keyType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::ENUM_OBJECT)) { + return; + } + } + ctx->checker->AsETSChecker()->LogError(diagnostic::OBJ_LIT_UNKNOWN_PROP, {}, expr->Start()); +} + ir::Expression *RecordLowering::UpdateObjectExpression(ir::ObjectExpression *expr, public_lib::Context *ctx) { auto checker = ctx->checker->AsETSChecker(); @@ -171,10 +186,23 @@ ir::Expression *RecordLowering::UpdateObjectExpression(ir::ObjectExpression *exp // Access type arguments [[maybe_unused]] size_t constexpr NUM_ARGUMENTS = 2; - auto typeArguments = expr->PreferredType()->AsETSObjectType()->TypeArguments(); + auto const &typeArguments = expr->PreferredType()->AsETSObjectType()->TypeArguments(); ES2PANDA_ASSERT(typeArguments.size() == NUM_ARGUMENTS); + auto const *keyType = typeArguments[0]; + if (keyType->IsETSTypeParameter()) { + keyType = keyType->AsETSTypeParameter()->GetConstraintType(); + } + // check keys correctness + if (keyType->IsETSUnionType()) { + for (auto const *const ct : keyType->AsETSUnionType()->ConstituentTypes()) { + CheckKeyType(checker, ct, expr, ctx); + } + } else { + CheckKeyType(checker, keyType, expr, ctx); + } + KeySetType keySet; CheckDuplicateKey(keySet, expr, ctx); CheckLiteralsCompleteness(keySet, expr, ctx); diff --git a/ets2panda/compiler/lowering/ets/recordLowering.h b/ets2panda/compiler/lowering/ets/recordLowering.h index a422dc6083..ffdf7f795e 100644 --- a/ets2panda/compiler/lowering/ets/recordLowering.h +++ b/ets2panda/compiler/lowering/ets/recordLowering.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023 - 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -39,6 +39,8 @@ private: void CheckLiteralsCompleteness(KeySetType &keySet, ir::ObjectExpression *expr, public_lib::Context *ctx); ir::Statement *CreateStatement(const std::string &src, ir::Expression *ident, ir::Expression *key, ir::Expression *value, public_lib::Context *ctx); + void CheckKeyType(checker::ETSChecker *checker, checker::Type const *keyType, ir::ObjectExpression const *expr, + public_lib::Context *ctx) const noexcept; }; } // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/spreadLowering.cpp b/ets2panda/compiler/lowering/ets/spreadLowering.cpp index 5ea7b5fb2a..4ab017a7ab 100644 --- a/ets2panda/compiler/lowering/ets/spreadLowering.cpp +++ b/ets2panda/compiler/lowering/ets/spreadLowering.cpp @@ -96,7 +96,8 @@ static ir::Identifier *CreateNewArrayDeclareStatement(public_lib::Context *ctx, // But now cast Expression doesn't support built-in array (cast fatherType[] to sonType[]), so "newArrayName // as arrayType" should be added after cast Expression is implemented completely. // Related issue: #issue20162 - if (checker::ETSChecker::IsReferenceType(arrayElementType)) { + if (checker->IsReferenceType(arrayElementType) && + !(arrayElementType->IsETSObjectType() && arrayElementType->AsETSObjectType()->IsBoxedPrimitive())) { arrayElementType = checker->CreateETSUnionType({arrayElementType, checker->GlobalETSUndefinedType()}); } @@ -107,9 +108,9 @@ static ir::Identifier *CreateNewArrayDeclareStatement(public_lib::Context *ctx, newArrayDeclareStr << "let @@I1: FixedArray<@@T2> = new (@@T3)[@@I4];" << std::endl; } - ir::Statement *newArrayDeclareSt = parser->CreateFormattedStatement( - newArrayDeclareStr.str(), newArrayId->Clone(allocator, nullptr), arrayElementType, arrayElementType, - newArrayLengthId->Clone(allocator, nullptr)); + ir::Statement *newArrayDeclareSt = + parser->CreateFormattedStatement(newArrayDeclareStr, newArrayId->Clone(allocator, nullptr), arrayElementType, + arrayElementType, newArrayLengthId->Clone(allocator, nullptr)); statements.emplace_back(newArrayDeclareSt); return newArrayId; diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp index 9b675c5de2..9d21718251 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp @@ -107,11 +107,10 @@ static void InsertInGlobal(ir::ClassDefinition *globalClass, ir::AstNode *node) node->SetParent(globalClass); } -void GlobalClassHandler::SetupInitializerBlock(parser::Program *program, - ArenaVector> &&initializerBlock, +void GlobalClassHandler::SetupInitializerBlock(ArenaVector> &&initializerBlock, ir::ClassDefinition *globalClass) { - if (program->IsDeclarationModule() || initializerBlock.empty()) { + if (globalProgram_->IsDeclarationModule() || initializerBlock.empty()) { return; } @@ -125,17 +124,17 @@ void GlobalClassHandler::SetupInitializerBlock(parser::Program *program, } // Note: cannot use the all same name for every stdlib package. - std::string moduleName = std::string(program->ModuleName()); + std::string moduleName = std::string(globalProgram_->ModuleName()); std::replace(moduleName.begin(), moduleName.end(), '.', '_'); util::UString initializerBlockName = util::UString {std::string(compiler::Signatures::INITIALIZER_BLOCK_INIT) + moduleName, allocator_}; ir::MethodDefinition *initializerBlockInit = - CreateGlobalMethod(initializerBlockName.View().Utf8(), std::move(blockStmts), program); + CreateGlobalMethod(initializerBlockName.View().Utf8(), std::move(blockStmts)); InsertInGlobal(globalClass, initializerBlockInit); AddInitCallToStaticBlock(globalClass, initializerBlockInit); } -void GlobalClassHandler::SetupGlobalMethods(parser::Program *program, ArenaVector &&initStatements, +void GlobalClassHandler::SetupGlobalMethods(ArenaVector &&initStatements, ir::ClassDefinition *globalClass, bool isDeclare) { if (isDeclare) { @@ -143,7 +142,7 @@ void GlobalClassHandler::SetupGlobalMethods(parser::Program *program, ArenaVecto } ir::MethodDefinition *initMethod = - CreateGlobalMethod(compiler::Signatures::INIT_METHOD, std::move(initStatements), program); + CreateGlobalMethod(compiler::Signatures::INIT_METHOD, std::move(initStatements)); InsertInGlobal(globalClass, initMethod); if (!initMethod->Function()->Body()->AsBlockStatement()->Statements().empty()) { AddInitCallToStaticBlock(globalClass, initMethod); @@ -178,18 +177,32 @@ void GlobalClassHandler::MergeNamespace(ArenaVector &namespaces } } -ArenaVector GlobalClassHandler::TransformNamespaces(ArenaVector &namespaces, - parser::Program *program) +ArenaVector GlobalClassHandler::TransformNamespaces(ArenaVector &namespaces) { ArenaVector classDecls {allocator_->Adapter()}; - MergeNamespace(namespaces, program); + MergeNamespace(namespaces, globalProgram_); for (auto ns : namespaces) { - classDecls.emplace_back(TransformNamespace(ns, program)); + classDecls.emplace_back(TransformNamespace(ns)); } return classDecls; } -ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, parser::Program *program) +void GlobalClassHandler::TransformBrokenNamespace() +{ + globalProgram_->Ast()->TransformChildrenRecursively( + // CC-OFFNXT(G.FMT.14-CPP) project code style + [this](ir::AstNode *node) -> ir::AstNode * { + if (node->IsETSModule() && node->AsETSModule()->IsNamespace()) { + auto res = TransformNamespace(node->AsETSModule()); + res->SetParent(node->Parent()); + return res; + } + return node; + }, + "TransformBrokenNamespace"); +} + +ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns) { ir::ClassDeclaration *const globalDecl = CreateTransformedClass(ns); ir::ClassDefinition *const globalClass = globalDecl->Definition(); @@ -202,16 +215,16 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, statement->Iterate([this](ir::AstNode *node) { AddStaticBlockToClass(node); }); } auto stmts = CollectProgramGlobalStatements(body, globalClass, ns); - immediateInitializers.emplace_back(GlobalStmts {program, std::move(stmts.immediateInit)}); + immediateInitializers.emplace_back(GlobalStmts {globalProgram_, std::move(stmts.immediateInit)}); for (auto &initBlock : stmts.initializerBlocks) { - initializerBlock.emplace_back(GlobalStmts {program, std::move(initBlock)}); + initializerBlock.emplace_back(GlobalStmts {globalProgram_, std::move(initBlock)}); } AddStaticBlockToClass(globalClass); const ModuleDependencies md {allocator_->Adapter()}; - auto immediateInitStatements = FormInitMethodStatements(program, &md, std::move(immediateInitializers)); - auto initializerBlockStatements = FormInitStaticBlockMethodStatements(program, &md, std::move(initializerBlock)); - SetupGlobalMethods(program, std::move(immediateInitStatements), globalClass, ns->IsDeclare()); - SetupInitializerBlock(program, std::move(initializerBlockStatements), globalClass); + auto immediateInitStatements = FormInitMethodStatements(&md, std::move(immediateInitializers)); + auto initializerBlockStatements = FormInitMethodStatements(&md, std::move(initializerBlock)); + SetupGlobalMethods(std::move(immediateInitStatements), globalClass, + ns->IsDeclare()); // remove namespaceDecl from orginal node auto end = std::remove_if(body.begin(), body.end(), [&namespaces](ir::AstNode *node) { @@ -222,7 +235,7 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, return false; }); body.erase(end, body.end()); - auto globalClasses = TransformNamespaces(namespaces, program); + auto globalClasses = TransformNamespaces(namespaces); for (auto *cls : globalClasses) { globalClass->Body().emplace_back(cls); cls->SetParent(globalClass); @@ -238,12 +251,12 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns, return globalDecl; } -void GlobalClassHandler::CollectProgramGlobalClasses(parser::Program *program, ArenaVector namespaces) +void GlobalClassHandler::CollectProgramGlobalClasses(ArenaVector namespaces) { - auto classDecls = TransformNamespaces(namespaces, program); + auto classDecls = TransformNamespaces(namespaces); for (auto cls : classDecls) { - program->Ast()->Statements().push_back(cls); - cls->SetParent(program->Ast()); + globalProgram_->Ast()->Statements().push_back(cls); + cls->SetParent(globalProgram_->Ast()); CollectNamespaceExportedClasses(cls->Definition()); } } @@ -268,14 +281,12 @@ void GlobalClassHandler::SetupGlobalClass(const ArenaVector & if (programs.empty()) { return; } - ArenaUnorderedSet packageInitializerBlockCount(allocator_->Adapter()); - parser::Program *const globalProgram = programs.front(); - ir::ClassDeclaration *const globalDecl = CreateGlobalClass(globalProgram); + ir::ClassDeclaration *const globalDecl = CreateGlobalClass(globalProgram_); ir::ClassDefinition *const globalClass = globalDecl->Definition(); // NOTE(vpukhov): a clash inside program list is possible - ES2PANDA_ASSERT(globalProgram->IsPackage() || programs.size() == 1); + ES2PANDA_ASSERT(globalProgram_->IsPackage() || programs.size() == 1); ArenaVector immediateInitializers(allocator_->Adapter()); ArenaVector initializerBlock(allocator_->Adapter()); @@ -301,30 +312,30 @@ void GlobalClassHandler::SetupGlobalClass(const ArenaVector & program->SetGlobalClass(globalClass); } - globalProgram->Ast()->Statements().emplace_back(globalDecl); - globalDecl->SetParent(globalProgram->Ast()); + globalProgram_->Ast()->Statements().emplace_back(globalDecl); + globalDecl->SetParent(globalProgram_->Ast()); globalClass->SetGlobalInitialized(); - CollectProgramGlobalClasses(globalProgram, namespaces); + + CollectProgramGlobalClasses(namespaces); + TransformBrokenNamespace(); auto initializerBlockStmts = - FormInitStaticBlockMethodStatements(globalProgram, moduleDependencies, std::move(initializerBlock)); + FormInitStaticBlockMethodStatements(moduleDependencies, std::move(initializerBlock)); - CollectExportedClasses(globalClass, globalProgram->Ast()->Statements()); + CollectExportedClasses(globalClass, globalProgram_->Ast()->Statements()); // NOTE(vpukhov): stdlib checks are to be removed - do not extend the existing logic - if (globalProgram->Kind() != parser::ScriptKind::STDLIB) { + if (globalProgram_->Kind() != parser::ScriptKind::STDLIB) { AddStaticBlockToClass(globalClass); - if (!util::Helpers::IsStdLib(globalProgram)) { - auto immInitStmts = - FormInitMethodStatements(globalProgram, moduleDependencies, std::move(immediateInitializers)); - SetupGlobalMethods(globalProgram, std::move(immInitStmts)); + if (!util::Helpers::IsStdLib(globalProgram_)) { + auto initStatements = FormInitMethodStatements(moduleDependencies, std::move(immediateInitializers)); + SetupGlobalMethods(std::move(initStatements)); } } - SetupInitializerBlock(globalProgram, std::move(initializerBlockStmts), globalClass); + SetupInitializerBlock(std::move(initializerBlockStmts), globalClass); } -ir::MethodDefinition *GlobalClassHandler::CreateGlobalMethod(std::string_view name, - ArenaVector &&statements, - const parser::Program *program) +ir::MethodDefinition *GlobalClassHandler::CreateGlobalMethod(const std::string_view name, + ArenaVector &&statements) { const auto functionFlags = ir::ScriptFunctionFlags::NONE; auto functionModifiers = ir::ModifierFlags::STATIC | ir::ModifierFlags::PUBLIC; @@ -344,7 +355,7 @@ ir::MethodDefinition *GlobalClassHandler::CreateGlobalMethod(std::string_view na auto *methodDef = NodeAllocator::Alloc(allocator_, ir::MethodDefinitionKind::METHOD, ident->Clone(allocator_, nullptr)->AsExpression(), funcExpr, functionModifiers, allocator_, false); - methodDef->SetRange({lexer::SourcePosition(program), lexer::SourcePosition(program)}); + methodDef->SetRange({lexer::SourcePosition(globalProgram_), lexer::SourcePosition(globalProgram_)}); return methodDef; } @@ -393,13 +404,13 @@ ir::Identifier *GlobalClassHandler::RefIdent(const util::StringView &name) } ArenaVector> GlobalClassHandler::FormInitStaticBlockMethodStatements( - parser::Program *program, const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements) + const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements) { // Note: will create method body for initializer block one by one, don't merge them. ArenaVector> staticBlocks(allocator_->Adapter()); for (const auto &[p, ps] : initStatements) { ArenaVector statements(allocator_->Adapter()); - if (!util::Helpers::IsStdLib(program) && moduleDependencies != nullptr) { + if (!util::Helpers::IsStdLib(globalProgram_) && moduleDependencies != nullptr) { FormDependentInitTriggers(statements, moduleDependencies); } statements.insert(statements.end(), ps.begin(), ps.end()); @@ -409,12 +420,11 @@ ArenaVector> GlobalClassHandler::FormInitStaticBloc return staticBlocks; } -ArenaVector GlobalClassHandler::FormInitMethodStatements(parser::Program *program, - const ModuleDependencies *moduleDependencies, +ArenaVector GlobalClassHandler::FormInitMethodStatements(const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements) { ArenaVector statements(allocator_->Adapter()); - if (!util::Helpers::IsStdLib(program) && moduleDependencies != nullptr) { + if (!util::Helpers::IsStdLib(globalProgram_) && moduleDependencies != nullptr) { FormDependentInitTriggers(statements, moduleDependencies); } for (const auto &[p, ps] : initStatements) { @@ -549,15 +559,26 @@ static bool HasMethod(ir::ClassDefinition const *cls, const std::string_view nam }); } -void GlobalClassHandler::SetupGlobalMethods(parser::Program *program, ArenaVector &&initStatements) +void GlobalClassHandler::SetupGlobalMethods(ArenaVector &&initStatements) { - ir::ClassDefinition *const globalClass = program->GlobalClass(); - SetupGlobalMethods(program, std::move(initStatements), globalClass, program->IsDeclarationModule()); + ir::ClassDefinition *const globalClass = globalProgram_->GlobalClass(); + + auto const insertInGlobal = [globalClass](ir::AstNode *node) { + // NOTE(vpukhov): inserted to begin for some reason + globalClass->Body().insert(globalClass->Body().begin(), node); + node->SetParent(globalClass); + }; + + if (!globalProgram_->IsDeclarationModule()) { + ir::MethodDefinition *initMethod = + CreateGlobalMethod(compiler::Signatures::INIT_METHOD, std::move(initStatements)); + insertInGlobal(initMethod); + } - if (program->IsSeparateModule() && !HasMethod(globalClass, compiler::Signatures::MAIN)) { - ir::MethodDefinition *mainMethod = CreateGlobalMethod( - compiler::Signatures::MAIN, ArenaVector(allocator_->Adapter()), program); - InsertInGlobal(globalClass, mainMethod); + if (globalProgram_->IsSeparateModule() && !HasMethod(globalClass, compiler::Signatures::MAIN)) { + ir::MethodDefinition *mainMethod = + CreateGlobalMethod(compiler::Signatures::MAIN, ArenaVector(allocator_->Adapter())); + insertInGlobal(mainMethod); } } diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h index ae589327d1..8dac90e886 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h @@ -31,8 +31,10 @@ public: parser::Program *program; ArenaVector statements; }; - explicit GlobalClassHandler(parser::ETSParser *parser, ArenaAllocator *allocator) - : parser_(parser), allocator_(allocator), packageInitializerBlockCount_(allocator->Adapter()) {}; + explicit GlobalClassHandler(parser::ETSParser *parser, ArenaAllocator *allocator, parser::Program *program) + : parser_(parser), allocator_(allocator), globalProgram_(program), packageInitializerBlockCount_(allocator->Adapter()) {}; + + static void MergeNamespace(ArenaVector &namespaces, parser::Program *program); /** * Each "Module" has it's own global class, which contains all top level statements across "module" @@ -40,9 +42,13 @@ public: * @param programs - vector of files in module */ void SetupGlobalClass(const ArenaVector &programs, const ModuleDependencies *moduleDependencies); - void static MergeNamespace(ArenaVector &namespaces, parser::Program *program); + void CheckPackageMultiInitializerBlock(util::StringView packageName, const ArenaVector> &initializerBlocks); + void SetGlobalProgram(parser::Program *program) + { + globalProgram_ = program; + } private: /** @@ -50,35 +56,33 @@ private: * @param program program of module * @param init_statements statements which should be executed */ - void SetupGlobalMethods(parser::Program *program, ArenaVector &&statements); + void SetupGlobalMethods(ArenaVector &&statements); void AddStaticBlockToClass(ir::AstNode *node); - void CollectProgramGlobalClasses(parser::Program *program, ArenaVector namespaces); - ir::ClassDeclaration *TransformNamespace(ir::ETSModule *ns, parser::Program *program); + void CollectProgramGlobalClasses(ArenaVector namespaces); + ir::ClassDeclaration *TransformNamespace(ir::ETSModule *ns); ir::ClassDeclaration *CreateTransformedClass(ir::ETSModule *ns); template void CollectExportedClasses(ir::ClassDefinition *classDef, const ArenaVector &statements); void CollectNamespaceExportedClasses(ir::ClassDefinition *classDef); - void SetupGlobalMethods(parser::Program *program, ArenaVector &&initStatements, + void SetupGlobalMethods(ArenaVector &&initStatements, ir::ClassDefinition *globalClass, bool isDeclare); - void SetupInitializerBlock(parser::Program *program, ArenaVector> &&initializerBlock, + void SetupInitializerBlock(ArenaVector> &&initializerBlock, ir::ClassDefinition *globalClass); - ArenaVector TransformNamespaces(ArenaVector &namespaces, - parser::Program *program); + ArenaVector TransformNamespaces(ArenaVector &namespaces); ir::ClassDeclaration *CreateGlobalClass(const parser::Program *globalProgram); ir::ClassStaticBlock *CreateStaticBlock(ir::ClassDefinition *classDef); - ir::MethodDefinition *CreateGlobalMethod(std::string_view name, ArenaVector &&statements, - const parser::Program *program); + ir::MethodDefinition *CreateGlobalMethod(std::string_view name, ArenaVector &&statements); void AddInitCallToStaticBlock(ir::ClassDefinition *globalClass, ir::MethodDefinition *initMethod); void AddInitializerBlockToStaticBlock(ir::ClassDefinition *globalClass, ArenaVector &&initializerBlocks); ArenaVector> FormInitStaticBlockMethodStatements( - parser::Program *program, const ModuleDependencies *moduleDependencies, + const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements); + void TransformBrokenNamespace(); - ArenaVector FormInitMethodStatements(parser::Program *program, - const ModuleDependencies *moduleDependencies, + ArenaVector FormInitMethodStatements(const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements); void FormDependentInitTriggers(ArenaVector &statements, @@ -92,6 +96,7 @@ private: parser::ETSParser *const parser_; ArenaAllocator *const allocator_; + parser::Program *globalProgram_; ArenaUnorderedSet packageInitializerBlockCount_; }; } // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp index 448e32937d..bc31ae6c65 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/topLevelStmts.cpp @@ -56,15 +56,17 @@ bool TopLevelStatements::Perform(public_lib::Context *ctx, parser::Program *prog // NOTE(vpukhov): enforce compilation failure } - GlobalClassHandler globalClass(ctx->parser->AsETSParser(), program->Allocator()); + GlobalClassHandler globalClass(ctx->parser->AsETSParser(), program->Allocator(), program); for (auto &[package, extPrograms] : program->ExternalSources()) { auto moduleDependencies = imports.HandleGlobalStmts(extPrograms); + globalClass.SetGlobalProgram(extPrograms.front()); globalClass.SetupGlobalClass(extPrograms, &moduleDependencies); } ArenaVector mainModule(program->Allocator()->Adapter()); mainModule.emplace_back(program); auto moduleDependencies = imports.HandleGlobalStmts(mainModule); + globalClass.SetGlobalProgram(program); globalClass.SetupGlobalClass(mainModule, &moduleDependencies); return true; } diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp new file mode 100644 index 0000000000..c2598d1a28 --- /dev/null +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -0,0 +1,1373 @@ +/* + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "generated/tokenType.h" +#include "ir/visitor/IterateAstVisitor.h" +#include "checker/ETSchecker.h" +#include "checker/ets/dynamic/dynamicCall.h" +#include "checker/types/ets/etsTupleType.h" +#include "checker/types/globalTypesHolder.h" +#include "compiler/lowering/util.h" +#include "ir/ets/etsTuple.h" + +#include "compiler/lowering/ets/unboxLowering.h" +#include +#include + +namespace ark::es2panda::compiler { + +namespace { +struct UnboxContext { + // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes,readability-identifier-naming) + explicit UnboxContext(parser::ETSParser *_parser, varbinder::ETSBinder *_varbinder, checker::ETSChecker *_checker) + : parser(_parser), varbinder(_varbinder), checker(_checker), handled(_checker->Allocator()->Adapter()) + { + } + + // NOLINTBEGIN(misc-non-private-member-variables-in-classes) + parser::ETSParser *parser; + varbinder::ETSBinder *varbinder; + checker::ETSChecker *checker; + ArenaSet handled; + // NOLINTEND(misc-non-private-member-variables-in-classes) +}; +} // namespace + +static bool IsRecursivelyUnboxedReference(checker::Type *t); + +static bool IsRecursivelyUnboxed(checker::Type *t) +{ + return t->IsETSPrimitiveType() || IsRecursivelyUnboxedReference(t); +} + +static bool IsRecursivelyUnboxedReference(checker::Type *t) +{ + return (t->IsETSTupleType() && + std::any_of(t->AsETSTupleType()->GetTupleTypesList().begin(), + t->AsETSTupleType()->GetTupleTypesList().end(), IsRecursivelyUnboxedReference)) || + (t->IsETSArrayType() && IsRecursivelyUnboxed(t->AsETSArrayType()->ElementType())) || + (t->IsETSUnionType() && + std::any_of(t->AsETSUnionType()->ConstituentTypes().begin(), t->AsETSUnionType()->ConstituentTypes().end(), + IsRecursivelyUnboxedReference)) || + (t->IsETSObjectType() && + std::any_of(t->AsETSObjectType()->TypeArguments().begin(), t->AsETSObjectType()->TypeArguments().end(), + IsRecursivelyUnboxedReference)); +} + +static bool TypeIsBoxedPrimitive(checker::Type *tp) +{ + return tp->IsETSObjectType() && tp->AsETSObjectType()->IsBoxedPrimitive(); +} + +static bool IsUnboxingApplicableReference(checker::Type *t); + +static bool IsUnboxingApplicable(checker::Type *t) +{ + return TypeIsBoxedPrimitive(t) || IsUnboxingApplicableReference(t); +} + +static bool IsUnboxingApplicableReference(checker::Type *t) +{ + return (t->IsETSTupleType() && + std::any_of(t->AsETSTupleType()->GetTupleTypesList().begin(), + t->AsETSTupleType()->GetTupleTypesList().end(), IsUnboxingApplicableReference)) || + (t->IsETSArrayType() && IsUnboxingApplicable(t->AsETSArrayType()->ElementType())) || + (t->IsETSUnionType() && + std::any_of(t->AsETSUnionType()->ConstituentTypes().begin(), t->AsETSUnionType()->ConstituentTypes().end(), + IsUnboxingApplicableReference)) || + (t->IsETSObjectType() && + std::any_of(t->AsETSObjectType()->TypeArguments().begin(), t->AsETSObjectType()->TypeArguments().end(), + IsUnboxingApplicableReference)); +} + +static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, checker::Type *t); + +static checker::Type *MaybeRecursivelyUnboxType(UnboxContext *uctx, checker::Type *t) +{ + if (TypeIsBoxedPrimitive(t)) { + return uctx->checker->MaybeUnboxType(t); + } + return MaybeRecursivelyUnboxReferenceType(uctx, t); +} + +// CC-OFFNXT(huge_method,G.FUN.01-CPP) solid logic +static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, checker::Type *t) +{ + auto *allocator = uctx->checker->Allocator(); + bool anyChange = false; + static std::uint64_t typeId = 0U; + + if (t == nullptr) { + return t; + } + + if (t->IsETSTypeParameter()) { + auto typeParameter = t->AsETSTypeParameter(); + auto constraintType = typeParameter->GetConstraintType(); + // We need to avoid endless recursion in case of recursive generic types, say 'class A>' + if (typeId == 0U) { + typeId = t->Id(); + typeParameter->SetConstraintType(MaybeRecursivelyUnboxReferenceType(uctx, constraintType)); + typeId = 0U; + } else if (t->Id() != typeId) { + typeParameter->SetConstraintType(MaybeRecursivelyUnboxReferenceType(uctx, constraintType)); + } + return t; + } + + if (t->IsETSTupleType()) { + auto *srcTup = t->AsETSTupleType(); + + ArenaVector newTps {allocator->Adapter()}; + for (auto *e : srcTup->GetTupleTypesList()) { + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); + newTps.push_back(newE); + anyChange |= (newE != e); + } + + return anyChange ? allocator->New(uctx->checker, newTps) : t; + } + + if (t->IsETSArrayType()) { + auto *srcArr = t->AsETSArrayType(); + auto *newE = MaybeRecursivelyUnboxType(uctx, srcArr->ElementType()); + return (newE == srcArr->ElementType()) ? t : uctx->checker->CreateETSArrayType(newE); + } + + if (t->IsETSUnionType()) { + auto *srcUnion = t->AsETSUnionType(); + ArenaVector newTps {allocator->Adapter()}; + for (auto *e : srcUnion->ConstituentTypes()) { + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); + newTps.push_back(newE); + anyChange |= (newE != e); + } + return anyChange ? uctx->checker->CreateETSUnionType(std::move(newTps)) : t; + } + + if (t->IsETSObjectType()) { + auto *objTp = t->AsETSObjectType(); + ArenaVector newTps {allocator->Adapter()}; + for (auto *e : objTp->TypeArguments()) { + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, e); + newTps.push_back(newE); + anyChange |= (newE != e); + } + return anyChange ? objTp->GetOriginalBaseType()->SubstituteArguments(uctx->checker->Relation(), newTps) : t; + } + + return t; +} + +// We should never see an array of boxed primitives, even as a component of some bigger type construction +static checker::Type *NormalizeType(UnboxContext *uctx, checker::Type *tp) +{ + return MaybeRecursivelyUnboxReferenceType(uctx, tp); +} + +static void NormalizeAllTypes(UnboxContext *uctx, ir::AstNode *ast) +{ + // Use preorder to avoid dealing with inner structure of type nodes: they are quickly replaced + // by opaque nodes that have no children. + ast->TransformChildrenRecursivelyPreorder( + // CC-OFFNXT(G.FMT.14-CPP) project code style + [uctx](ir::AstNode *child) -> ir::AstNode * { + if (child->IsExpression() && child->AsExpression()->IsTypeNode()) { + // Avoid dealing with annotation usages. + // ETSTypeReferenceParts only appear within ETSTypeReference, so the only way to get one is + // again through AnnotationUsage. + if (child->Parent()->IsAnnotationUsage() || child->IsETSTypeReferencePart()) { + return child; + } + auto typeNodeType = child->AsExpression()->AsTypeNode()->GetType(uctx->checker); + if (typeNodeType == nullptr || typeNodeType->IsETSDynamicType()) { + return child; + } + auto r = uctx->checker->Allocator()->New(NormalizeType(uctx, typeNodeType), + uctx->checker->Allocator()); + r->SetRange(child->Range()); + r->SetParent(child->Parent()); + return r; + } + if (child->IsTyped()) { + child->AsTyped()->SetTsType(NormalizeType(uctx, child->AsTyped()->TsType())); + if (child->Variable() != nullptr && child->Variable()->TsType() != nullptr) { + child->Variable()->SetTsType(NormalizeType(uctx, child->Variable()->TsType())); + } + } + return child; + }, + "unbox-normalize-types"); +} + +static void HandleScriptFunctionHeader(UnboxContext *uctx, ir::ScriptFunction *func) +{ + auto *sig = func->Signature(); + if (sig == nullptr) { + return; + } + + // Special case for primitive `valueOf` functions -- should still return boxed values (used in codegen) + if (func->Parent()->Parent()->IsMethodDefinition() && + func->Parent()->Parent()->AsMethodDefinition()->Id()->Name() == "valueOf" && + ContainingClass(func)->AsETSObjectType()->IsBoxedPrimitive() && sig->Params().size() == 1 && + !sig->Params()[0]->TsType()->IsETSEnumType()) { + auto *boxed = func->Parent()->Parent()->Parent()->AsTyped()->TsType(); + auto *unboxed = MaybeRecursivelyUnboxType(uctx, boxed); + + ES2PANDA_ASSERT(sig->ReturnType() == boxed); + + sig->Params()[0]->SetTsType(unboxed); + uctx->varbinder->BuildFunctionName(func); + return; + } + + // Special case for enum boxing function -- this should still return a boxed value + if (func->Parent()->Parent()->IsMethodDefinition() && + func->Parent()->Parent()->AsMethodDefinition()->Id()->Name() == "boxedfromInt") { + return; + } + + for (size_t i = 0; i < func->Signature()->Params().size(); i++) { + auto *sigParam = func->Signature()->Params()[i]; + auto *funcParam = func->Params()[i]->AsETSParameterExpression(); + if (IsUnboxingApplicable(sigParam->TsType())) { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, sigParam->TsType()); + sigParam->SetTsType(unboxedType); + funcParam->SetTsType(unboxedType); + funcParam->Ident()->SetTsType(unboxedType); + funcParam->Variable()->SetTsType(unboxedType); + } + } + if (sig->RestVar() != nullptr) { + auto *funcRestParam = func->Params()[func->Params().size() - 1]->AsETSParameterExpression(); + ES2PANDA_ASSERT(funcRestParam != nullptr && funcRestParam->IsRestParameter()); + + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, sig->RestVar()->TsType()); + sig->RestVar()->SetTsType(unboxedType); + funcRestParam->Ident()->SetTsType(unboxedType); + funcRestParam->Ident()->Variable()->SetTsType(unboxedType); + } + if (IsUnboxingApplicable(sig->ReturnType())) { + sig->SetReturnType(MaybeRecursivelyUnboxType(uctx, sig->ReturnType())); + } + + // Signature may have changed, so need to change internal name. + uctx->varbinder->BuildFunctionName(func); +} + +static void HandleClassProperty(UnboxContext *uctx, ir::ClassProperty *prop) +{ + auto *propType = prop->TsType(); + if (propType == nullptr) { + propType = prop->Key()->Variable()->TsType(); + } + ES2PANDA_ASSERT(propType != nullptr); + if (IsUnboxingApplicable(propType) && prop->Key()->IsIdentifier()) { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, propType); + prop->SetTsType(unboxedType); + prop->Key()->Variable()->SetTsType(unboxedType); + } +} + +static void HandleVariableDeclarator(UnboxContext *uctx, ir::VariableDeclarator *vdecl) +{ + if (IsUnboxingApplicable(vdecl->Id()->Variable()->TsType())) { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, vdecl->Id()->Variable()->TsType()); + vdecl->SetTsType(unboxedType); + vdecl->Id()->SetTsType(unboxedType); + vdecl->Id()->Variable()->SetTsType(unboxedType); + } +} + +static void HandleDeclarationNode(UnboxContext *uctx, ir::AstNode *ast) /// +{ + if (uctx->handled.count(ast) > 0) { + return; + } + if (ast->IsScriptFunction()) { + HandleScriptFunctionHeader(uctx, ast->AsScriptFunction()); + } else if (ast->IsMethodDefinition()) { + HandleScriptFunctionHeader(uctx, ast->AsMethodDefinition()->Function()); + } else if (ast->IsClassProperty()) { + HandleClassProperty(uctx, ast->AsClassProperty()); + } else if (ast->IsVariableDeclarator()) { + HandleVariableDeclarator(uctx, ast->AsVariableDeclarator()); + } + uctx->handled.insert(ast); +} + +static ir::Expression *InsertUnboxing(UnboxContext *uctx, ir::Expression *expr) +{ + auto *boxedType = expr->TsType(); + if (boxedType->IsETSTypeParameter()) { + boxedType = boxedType->AsETSTypeParameter()->GetConstraintType(); + } + auto *unboxedType = MaybeRecursivelyUnboxType(uctx, boxedType); + auto *parent = expr->Parent(); + + auto *allocator = uctx->checker->Allocator(); + + auto *arenaString = allocator->New(allocator->Adapter()); + if (unboxedType->IsETSIntEnumType() || unboxedType->IsETSStringEnumType()) { + arenaString->append("unbox"); + } else { + arenaString->append("unboxed"); + } + auto *methodId = allocator->New(util::StringView(arenaString), allocator); + auto *mexpr = util::NodeAllocator::ForceSetParent( + allocator, expr, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + auto *call = util::NodeAllocator::ForceSetParent( + allocator, mexpr, ArenaVector(allocator->Adapter()), nullptr, false); + call->SetParent(parent); + auto range = expr->Range(); + methodId->SetRange(range); + mexpr->SetRange(range); + call->SetRange(range); + + CheckLoweredNode(uctx->varbinder, uctx->checker, call); + + /* Ensure that calleeMethod's signature is updated to return an unboxed value */ + auto *calleeMethod = methodId->Variable()->Declaration()->Node(); + HandleDeclarationNode(uctx, calleeMethod); + call->SetTsType(unboxedType); + + return call; +} + +static ir::Expression *InsertBoxing(UnboxContext *uctx, ir::Expression *expr) +{ + auto *unboxedType = expr->TsType(); + auto *boxedType = uctx->checker->MaybeBoxType(unboxedType); + auto *parent = expr->Parent(); + + auto *allocator = uctx->checker->Allocator(); + + auto args = ArenaVector(allocator->Adapter()); + + if (unboxedType->IsETSIntEnumType() || unboxedType->IsETSStringEnumType()) { + auto *memberExpr = util::NodeAllocator::ForceSetParent( + allocator, allocator->New(boxedType, allocator), + allocator->New("boxedfromInt", allocator), ir::MemberExpressionKind::PROPERTY_ACCESS, false, + false); + auto *asExpr = util::NodeAllocator::ForceSetParent( + allocator, expr, allocator->New(uctx->checker->GlobalIntType(), allocator), false); + args.push_back(asExpr); + auto *call = util::NodeAllocator::ForceSetParent(allocator, memberExpr, std::move(args), + nullptr, false); + + call->SetParent(parent); + auto range = expr->Range(); + memberExpr->Object()->SetRange(range); + memberExpr->Property()->SetRange(range); + memberExpr->SetRange(range); + asExpr->TypeAnnotation()->SetRange(range); + asExpr->SetRange(range); + call->SetRange(range); + + CheckLoweredNode(uctx->varbinder, uctx->checker, call); + HandleDeclarationNode(uctx, call); + + return call; + } + + args.push_back(expr); + auto *constrCall = util::NodeAllocator::ForceSetParent( + allocator, allocator->New(boxedType, allocator), std::move(args)); + constrCall->SetParent(parent); + + auto range = expr->Range(); + constrCall->GetTypeRef()->SetRange(range); + constrCall->SetRange(range); + + CheckLoweredNode(uctx->varbinder, uctx->checker, constrCall); + + /* Ensure that the constructor signature is updated to accept an unboxed value */ + auto *constructor = constrCall->GetSignature()->Function(); + HandleDeclarationNode(uctx, constructor); + + return constrCall; +} + +/* NOTE(gogabr): conversions should be inserted at the checker stage. This function is temporary. */ +static ir::Expression *InsertPrimitiveConversionIfNeeded(UnboxContext *uctx, ir::Expression *expr, + checker::Type *expectedType) +{ + auto *checker = uctx->checker; + auto *relation = checker->Relation(); + auto *allocator = checker->Allocator(); + auto *actualType = expr->TsType(); + auto *parent = expr->Parent(); + + ES2PANDA_ASSERT(IsRecursivelyUnboxed(actualType)); + + if (relation->IsSupertypeOf(expectedType, uctx->checker->MaybeBoxType(actualType))) { + return expr; + } + + checker::Type *toConvert = nullptr; + auto checkSubtyping = [expectedType, checker, &toConvert](checker::Type *tp) { + if (toConvert != nullptr) { + return; + } + if (checker->Relation()->IsSupertypeOf(expectedType, checker->MaybeBoxType(tp))) { + toConvert = tp; + } + }; + checkSubtyping(checker->GlobalByteBuiltinType()); + checkSubtyping(checker->GlobalShortBuiltinType()); + checkSubtyping(checker->GlobalIntBuiltinType()); + checkSubtyping(checker->GlobalLongBuiltinType()); + checkSubtyping(checker->GlobalFloatBuiltinType()); + checkSubtyping(checker->GlobalDoubleBuiltinType()); + if (toConvert == nullptr && actualType->IsCharType() && + relation->IsSupertypeOf(expectedType, checker->GlobalBuiltinETSStringType())) { + toConvert = uctx->checker->GlobalBuiltinETSStringType(); + } + if (toConvert == nullptr && actualType->IsByteType() && + relation->IsSupertypeOf(expectedType, checker->GlobalCharBuiltinType())) { + toConvert = uctx->checker->GlobalCharBuiltinType(); + } + ES2PANDA_ASSERT(toConvert != nullptr); + auto *toConvertUnboxed = checker->MaybeUnboxType(toConvert); + + auto *res = util::NodeAllocator::ForceSetParent( + allocator, expr, allocator->New(toConvertUnboxed, allocator), false); + res->SetParent(parent); + res->SetTsType(toConvertUnboxed); + + auto range = expr->Range(); + res->TypeAnnotation()->SetRange(range); + res->SetRange(range); + + if (toConvert->IsETSStringType() && actualType->IsCharType()) { + res->AddAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); + } + + return res; +} + +// CC-OFFNXT(huge_cyclomatic_complexity,G.FUN.01-CPP) solid logic +static ir::Expression *PerformLiteralConversion(UnboxContext *uctx, lexer::Number const *n, checker::Type *expectedType) +{ + auto *allocator = uctx->checker->Allocator(); + bool isInt = false; + int64_t longValue = 0; + double doubleValue = 0.0; + if (n->IsByte()) { + longValue = n->GetByte(); + isInt = true; + } else if (n->IsShort()) { + longValue = n->GetShort(); + isInt = true; + } else if (n->IsInt()) { + longValue = n->GetInt(); + isInt = true; + } else if (n->IsLong()) { + longValue = n->GetLong(); + isInt = true; + } else if (n->IsFloat()) { + doubleValue = n->GetFloat(); + isInt = false; + } else if (n->IsDouble()) { + doubleValue = n->GetDouble(); + isInt = false; + } else { + ES2PANDA_UNREACHABLE(); + } + + lexer::Number num {}; + if (expectedType->IsByteType()) { + num = lexer::Number {isInt ? (int8_t)longValue : (int8_t)doubleValue}; + } else if (expectedType->IsShortType()) { + num = lexer::Number {isInt ? (int16_t)longValue : (int16_t)doubleValue}; + } else if (expectedType->IsIntType()) { + num = lexer::Number {isInt ? (int32_t)longValue : (int32_t)doubleValue}; + } else if (expectedType->IsLongType()) { + num = lexer::Number {isInt ? longValue : (int64_t)doubleValue}; + } else if (expectedType->IsFloatType()) { + num = lexer::Number {isInt ? (float)longValue : (float)doubleValue}; + } else if (expectedType->IsDoubleType()) { + num = lexer::Number {isInt ? (double)longValue : doubleValue}; + } else { + ES2PANDA_UNREACHABLE(); + } + + auto *res = allocator->New(num); + res->SetTsType(expectedType); + return res; +} + +static ir::Expression *InsertConversionBetweenPrimitivesIfNeeded(UnboxContext *uctx, ir::Expression *expr, + checker::Type *expectedType) +{ + auto *oldType = expr->TsType(); + if (uctx->checker->Relation()->IsIdenticalTo(oldType, expectedType)) { + return expr; + } + + auto *checker = uctx->checker; + auto *parent = expr->Parent(); + ir::Expression *res; + + auto range = expr->Range(); + + if (expr->IsNumberLiteral() && expectedType->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC)) { + /* Some contexts (namely, annotations) expect literals, so provide them if possible */ + res = PerformLiteralConversion(uctx, &expr->AsNumberLiteral()->Number(), expectedType); + res->SetRange(range); + } else { + auto *allocator = checker->Allocator(); + res = util::NodeAllocator::ForceSetParent( + allocator, expr, allocator->New(expectedType, allocator), false); + res->AsTSAsExpression()->TypeAnnotation()->SetRange(range); + res->SetRange(range); + } + + res->SetParent(parent); + res->SetTsType(expectedType); + return res; +} + +static ir::Expression *AdjustType(UnboxContext *uctx, ir::Expression *expr, checker::Type *expectedType) +{ + if (expr == nullptr) { + return nullptr; + } + expectedType = uctx->checker->GetApparentType(expectedType); + auto *actualType = expr->TsType(); + + if (expectedType->IsETSDynamicType()) { + return expr; + } + if (actualType->IsETSDynamicType()) { + auto *parent = expr->Parent(); + auto *allocator = uctx->checker->Allocator(); + auto *res = util::NodeAllocator::ForceSetParent( + allocator, expr, allocator->New(expectedType, allocator), false); + res->SetParent(parent); + res->SetTsType(expectedType); + res->SetRange(expr->Range()); + return res; + } + + expr->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); + if (actualType->IsETSPrimitiveType() && uctx->checker->IsReferenceType(expectedType)) { + expr = InsertPrimitiveConversionIfNeeded(uctx, expr, expectedType); + ES2PANDA_ASSERT( + uctx->checker->Relation()->IsSupertypeOf(expectedType, uctx->checker->MaybeBoxType(expr->TsType())) || + (expr->TsType()->IsCharType() && expectedType->IsETSStringType())); + return InsertBoxing(uctx, expr); + } + if ((TypeIsBoxedPrimitive(actualType) || + (actualType->IsETSTypeParameter() && + TypeIsBoxedPrimitive(actualType->AsETSTypeParameter()->GetConstraintType()))) && + expectedType->IsETSPrimitiveType()) { + return InsertConversionBetweenPrimitivesIfNeeded(uctx, InsertUnboxing(uctx, expr), expectedType); + } + if (TypeIsBoxedPrimitive(actualType) && uctx->checker->IsReferenceType(expectedType) && + !uctx->checker->Relation()->IsSupertypeOf(expectedType, actualType)) { + return AdjustType(uctx, InsertUnboxing(uctx, expr), expectedType); + } + if (actualType->IsETSPrimitiveType() && expectedType->IsETSPrimitiveType()) { + return InsertConversionBetweenPrimitivesIfNeeded(uctx, expr, expectedType); + } + return expr; +} + +static void HandleForOfStatement(UnboxContext *uctx, ir::ForOfStatement *forOf) +{ + auto *left = forOf->Left(); + + ir::Identifier *id = nullptr; + if (left->IsIdentifier()) { + id = left->AsIdentifier(); + } else if (left->IsVariableDeclaration()) { + ES2PANDA_ASSERT(left->AsVariableDeclaration()->Declarators().size() == 1); + id = left->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier(); + } + ES2PANDA_ASSERT(id != nullptr); + + // NOTE(gogabr): we need to recompute the right side type instead of just unboxing; + // this may be, for example, a generic call that returns a boxed array. + auto *tp = MaybeRecursivelyUnboxType(uctx, forOf->Right()->TsType()); + + checker::Type *elemTp = nullptr; + if (tp->IsETSArrayType()) { + elemTp = tp->AsETSArrayType()->ElementType(); + } else if (tp->IsETSStringType()) { + elemTp = uctx->checker->GlobalCharType(); + } else { + ES2PANDA_ASSERT(tp->IsETSUnionType()); + ES2PANDA_ASSERT(id->Variable()->TsType()->IsETSUnionType()); + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) + elemTp = id->Variable()->TsType(); // always a union type, no need to change + } + + /* This type assignment beats other assignment that could be produced during normal handling of id's declaration + */ + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) + id->SetTsType(elemTp); + id->Variable()->SetTsType(elemTp); + id->Variable()->Declaration()->Node()->AsTyped()->SetTsType(elemTp); +} + +// Borrowed from arithmetic.cpp, didn't want to make it public -- gogabr +static checker::Type *EffectiveTypeOfNumericOrEqualsOp(checker::ETSChecker *checker, checker::Type *left, + checker::Type *right) +{ + if (left->IsDoubleType() || right->IsDoubleType()) { + return checker->GlobalDoubleType(); + } + if (left->IsFloatType() || right->IsFloatType()) { + return checker->GlobalFloatType(); + } + if (left->IsLongType() || right->IsLongType()) { + return checker->GlobalLongType(); + } + if (left->IsCharType() && right->IsCharType()) { + return checker->GlobalCharType(); + } + if (left->IsETSBooleanType() && right->IsETSBooleanType()) { + return checker->GlobalETSBooleanType(); + } + return checker->GlobalIntType(); +} + +static void ReplaceInParent(ir::AstNode *from, ir::AstNode *to) +{ + // CC-OFFNXT(G.FMT.14-CPP) project code style + auto const replaceNode = [=](ir::AstNode *child) -> ir::AstNode * { + if (child == from) { + to->SetParent(from->Parent()); + return to; + } + return child; + }; + from->Parent()->TransformChildren(replaceNode, "UnboxLoweringReplaceInParent"); +} + +namespace { +struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { + explicit UnboxVisitor(UnboxContext *uctx) : uctx_(uctx) {} + + void VisitReturnStatement(ir::ReturnStatement *retStmt) override + { + ir::ScriptFunction *nearestScriptFunction = nullptr; + for (ir::AstNode *curr = retStmt; curr != nullptr; curr = curr->Parent()) { + if (curr->IsScriptFunction()) { + nearestScriptFunction = curr->AsScriptFunction(); + break; + } + } + ES2PANDA_ASSERT(nearestScriptFunction != nullptr); + + retStmt->SetArgument(AdjustType(uctx_, retStmt->Argument(), nearestScriptFunction->Signature()->ReturnType())); + } + + void VisitIfStatement(ir::IfStatement *ifStmt) override + { + if (TypeIsBoxedPrimitive(ifStmt->Test()->TsType())) { + ifStmt->SetTest(InsertUnboxing(uctx_, ifStmt->Test())); + } + } + + void VisitWhileStatement(ir::WhileStatement *whStmt) override + { + if (TypeIsBoxedPrimitive(whStmt->Test()->TsType())) { + whStmt->SetTest(InsertUnboxing(uctx_, whStmt->Test())); + } + } + + void VisitSwitchStatement(ir::SwitchStatement *swtch) override + { + auto *discType = uctx_->checker->MaybeUnboxType(swtch->Discriminant()->TsType()); + if (!discType->IsETSPrimitiveType()) { // should be string + return; + } + swtch->SetDiscriminant(AdjustType(uctx_, swtch->Discriminant(), discType)); + for (auto *scase : swtch->Cases()) { + scase->SetTest(AdjustType(uctx_, scase->Test(), discType)); + } + } + + void HandleDynamicCall(ir::CallExpression *call) + { + auto *sig = call->Signature(); + auto numSysParams = checker::DynamicCall::IsByValue(uctx_->varbinder, call->Callee()) ? 2 : 3; + for (size_t ix = 0; ix < call->Arguments().size(); ix++) { + auto *expectedType = sig->Params()[numSysParams + ix]->TsType(); + call->Arguments()[ix] = AdjustType(uctx_, call->Arguments()[ix], expectedType); + } + } + + // CC-OFFNXT(huge_method,G.FUN.01-CPP) solid logic + void VisitCallExpression(ir::CallExpression *call) override + { + if (call->Callee()->TsType()->IsETSDynamicType()) { + HandleDynamicCall(call); + return; + } + + auto *func = call->Signature()->Function(); + if (func == nullptr) { + // some lambda call, all arguments and return type need to be boxed + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t i = 0; i < call->Arguments().size(); i++) { + auto *arg = call->Arguments()[i]; + call->Arguments()[i] = AdjustType(uctx_, arg, uctx_->checker->MaybeBoxType(arg->TsType())); + } + return; + } + + HandleDeclarationNode(uctx_, func); + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t i = 0; i < call->Arguments().size(); i++) { + auto *arg = call->Arguments()[i]; + + if (i >= func->Signature()->Params().size()) { + auto *restVar = call->Signature()->RestVar(); + if (restVar != nullptr && + !arg->IsSpreadElement()) { // NOTE(gogabr) should we try to unbox spread elements? + auto *restElemType = restVar->TsType()->AsETSArrayType()->ElementType(); + call->Arguments()[i] = AdjustType(uctx_, arg, restElemType); + } + } else { + auto *origSigType = func->Signature()->Params()[i]->TsType(); + if (origSigType->IsETSPrimitiveType()) { + call->Signature()->Params()[i]->SetTsType(origSigType); + call->Arguments()[i] = AdjustType(uctx_, arg, origSigType); + } else { + call->Arguments()[i] = AdjustType(uctx_, arg, call->Signature()->Params()[i]->TsType()); + } + } + } + + if (func->Signature()->ReturnType()->IsETSPrimitiveType()) { + call->Signature()->SetReturnType(func->Signature()->ReturnType()); + } else { + call->Signature()->SetReturnType(NormalizeType(uctx_, call->Signature()->ReturnType())); + } + + if (call->Signature()->HasSignatureFlag(checker::SignatureFlags::THIS_RETURN_TYPE)) { + auto *callee = call->Callee(); + auto isFuncRefCall = [&callee]() { + if (!callee->IsMemberExpression()) { + return false; + }; + auto *calleeObject = callee->AsMemberExpression()->Object(); + return (calleeObject) + ->TsType() + ->IsETSFunctionType() || // NOTE(gogabr): How can this happen after lambdaLowering? + (calleeObject->TsType()->IsETSObjectType() && + calleeObject->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::FUNCTIONAL)); + }(); + if (callee->IsMemberExpression() && !isFuncRefCall) { + call->SetTsType(callee->AsMemberExpression()->Object()->TsType()); + } else { + // Either a functional reference call, or + // function with receiver called in a "normal", "function-like" way: + // function f(x: this) : this { return this } + // f(new A) + ES2PANDA_ASSERT(!call->Arguments().empty()); + call->SetTsType(call->Arguments()[0]->TsType()); + } + } else { + call->SetTsType(call->Signature()->ReturnType()); + } + } + + void HandleDynamicConstructorCall(ir::ETSNewClassInstanceExpression *call) + { + auto *sig = call->GetSignature(); + auto numSysParams = checker::DynamicCall::IsByValue(uctx_->varbinder, call->GetTypeRef()) ? 2 : 3; + for (size_t ix = 0; ix < call->GetArguments().size(); ix++) { + auto *expectedType = sig->Params()[numSysParams + ix]->TsType(); + call->GetArguments()[ix] = AdjustType(uctx_, call->GetArguments()[ix], expectedType); + } + } + + void VisitETSNewClassInstanceExpression(ir::ETSNewClassInstanceExpression *call) override + { + if (call->GetTypeRef()->TsType()->IsETSDynamicType()) { + HandleDynamicConstructorCall(call); + return; + } + + auto *func = call->GetSignature()->Function(); + HandleDeclarationNode(uctx_, func); + + for (size_t i = 0; i < call->GetArguments().size(); i++) { + auto *arg = call->GetArguments()[i]; + + if (i >= func->Signature()->Params().size()) { + auto *restVar = call->GetSignature()->RestVar(); + if (restVar != nullptr && + !arg->IsSpreadElement()) { // NOTE(gogabr) should we try to unbox spread elements? + auto *restElemType = restVar->TsType()->AsETSArrayType()->ElementType(); + call->GetArguments()[i] = AdjustType(uctx_, arg, restElemType); + } + } else { + auto *origSigType = func->Signature()->Params()[i]->TsType(); + if (origSigType->IsETSPrimitiveType()) { + call->GetSignature()->Params()[i]->SetTsType(origSigType); + call->GetArguments()[i] = AdjustType(uctx_, arg, origSigType); + } else { + call->GetArguments()[i] = AdjustType(uctx_, arg, call->GetSignature()->Params()[i]->TsType()); + } + } + } + + call->SetTsType(call->GetTypeRef()->TsType()); + } + + void VisitSpreadElement(ir::SpreadElement *spread) override + { + spread->SetTsType(spread->Argument()->TsType()); + } + + void VisitArrayExpression(ir::ArrayExpression *aexpr) override + { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx_, aexpr->TsType()); + aexpr->SetTsType(unboxedType); + + for (size_t i = 0; i < aexpr->Elements().size(); i++) { + checker::Type *expectedType; + if (aexpr->TsType()->IsETSTupleType()) { + expectedType = aexpr->TsType()->AsETSTupleType()->GetTypeAtIndex(i); + } else if (aexpr->TsType()->IsETSArrayType()) { + expectedType = aexpr->TsType()->AsETSArrayType()->ElementType(); + } else { + ES2PANDA_UNREACHABLE(); + } + aexpr->Elements()[i] = AdjustType(uctx_, aexpr->Elements()[i], expectedType); + } + } + + void HandleArithmeticLike(ir::BinaryExpression *bexpr) + { + bexpr->SetTsType(uctx_->checker->MaybeUnboxType(bexpr->TsType())); + bexpr->SetOperationType(uctx_->checker->MaybeUnboxType(bexpr->OperationType())); + if (TypeIsBoxedPrimitive(bexpr->Left()->TsType())) { + bexpr->SetLeft(InsertUnboxing(uctx_, bexpr->Left())); + } + if (TypeIsBoxedPrimitive(bexpr->Right()->TsType())) { + bexpr->SetRight(InsertUnboxing(uctx_, bexpr->Right())); + } + } + + void HandleEqualityOrInequality(ir::BinaryExpression *bexpr) + { + auto *leftTp = bexpr->Left()->TsType(); + auto *rightTp = bexpr->Right()->TsType(); + + checker::Type *opType = nullptr; + if ((leftTp->IsETSPrimitiveType() || TypeIsBoxedPrimitive(leftTp)) && + (rightTp->IsETSPrimitiveType() || TypeIsBoxedPrimitive(rightTp))) { + auto *newLeftTp = uctx_->checker->MaybeUnboxType(leftTp); + auto *newRightTp = uctx_->checker->MaybeUnboxType(rightTp); + bexpr->SetLeft(AdjustType(uctx_, bexpr->Left(), newLeftTp)); + bexpr->SetRight(AdjustType(uctx_, bexpr->Right(), newRightTp)); + + opType = EffectiveTypeOfNumericOrEqualsOp(uctx_->checker, newLeftTp, newRightTp); + bexpr->SetLeft(InsertConversionBetweenPrimitivesIfNeeded(uctx_, bexpr->Left(), opType)); + bexpr->SetRight(InsertConversionBetweenPrimitivesIfNeeded(uctx_, bexpr->Right(), opType)); + } else { + bexpr->SetLeft(AdjustType(uctx_, bexpr->Left(), uctx_->checker->MaybeBoxType(leftTp))); + bexpr->SetRight(AdjustType(uctx_, bexpr->Right(), uctx_->checker->MaybeBoxType(rightTp))); + opType = bexpr->OperationType(); + } + + bexpr->SetOperationType(opType); + bexpr->SetTsType(uctx_->checker->GlobalETSBooleanType()); + } + + void HandleLogical(ir::BinaryExpression *bexpr) + { + auto *leftType = bexpr->Left()->TsType(); + auto *rightType = bexpr->Right()->TsType(); + if (uctx_->checker->Relation()->IsIdenticalTo(leftType, rightType)) { + bexpr->SetTsType(leftType); + bexpr->SetOperationType(leftType); + } else { + // NOTE(gogabr): simplify codegen here. Lower logical operators. + auto *oldLeft = bexpr->Left(); + auto *oldRight = bexpr->Right(); + auto *leftBoxed = uctx_->checker->MaybeBoxType(leftType); + auto *rightBoxed = uctx_->checker->MaybeBoxType(rightType); + auto *resType = uctx_->checker->MaybeUnboxType(uctx_->checker->CreateETSUnionType( + {leftBoxed, rightBoxed})); // currently CreateETSUnionType returns nonunion numeric type if you try to + // create a *Numeric*|*OtherNumeric* + bexpr->SetLeft(AdjustType(uctx_, oldLeft, resType)); + bexpr->SetRight(AdjustType(uctx_, oldRight, resType)); + if (bexpr->Result() == oldLeft) { + bexpr->SetResult(bexpr->Left()); + } else if (bexpr->Result() == oldRight) { + bexpr->SetResult(bexpr->Right()); + } + bexpr->SetTsType(resType); + bexpr->SetOperationType(bexpr->TsType()); + } + } + + void VisitBinaryExpression(ir::BinaryExpression *bexpr) override + { + if (bexpr->IsArithmetic() || bexpr->IsBitwise() || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LESS_THAN || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_GREATER_THAN || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT) { + HandleArithmeticLike(bexpr); + return; + } + if (bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_STRICT_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_EQUAL || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_NOT_EQUAL) { + HandleEqualityOrInequality(bexpr); + return; + } + if (bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_NULLISH_COALESCING) { + bexpr->SetLeft( + AdjustType(uctx_, bexpr->Left(), + uctx_->checker->CreateETSUnionType({bexpr->TsType(), uctx_->checker->GlobalETSNullType(), + uctx_->checker->GlobalETSUndefinedType()}))); + bexpr->SetRight(AdjustType(uctx_, bexpr->Right(), bexpr->TsType())); + return; + } + if (bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || + bexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_LOGICAL_OR) { + HandleLogical(bexpr); + return; + } + + if (bexpr->OperatorType() == lexer::TokenType::KEYW_INSTANCEOF) { + bexpr->SetLeft(AdjustType(uctx_, bexpr->Left(), uctx_->checker->MaybeBoxType(bexpr->Left()->TsType()))); + bexpr->SetTsType(uctx_->checker->GlobalETSBooleanType()); + return; + } + } + + void VisitUnaryExpression(ir::UnaryExpression *uexpr) override + { + if (uexpr->OperatorType() == lexer::TokenType::PUNCTUATOR_TILDE) { + uexpr->SetArgument(AdjustType(uctx_, uexpr->Argument(), uexpr->TsType())); + } + + uexpr->SetTsType(uctx_->checker->MaybeUnboxType(uexpr->TsType())); + if (TypeIsBoxedPrimitive(uexpr->Argument()->TsType())) { + uexpr->SetArgument(InsertUnboxing(uctx_, uexpr->Argument())); + } + } + + static bool IsStaticMemberExpression(ir::MemberExpression *mexpr) + { + ES2PANDA_ASSERT(mexpr->Kind() == ir::MemberExpressionKind::PROPERTY_ACCESS); + + auto *propDeclNode = mexpr->Property()->Variable()->Declaration()->Node(); + if (propDeclNode->IsMethodDefinition()) { + return propDeclNode->AsMethodDefinition()->IsStatic(); + } + if (propDeclNode->IsClassProperty()) { + return propDeclNode->AsClassProperty()->IsStatic(); + } + return propDeclNode->IsTSEnumMember(); + } + + static int GetNumberLiteral(ir::Expression *expr) // NOTE(gogabr): should use code from ConstantExpressionLowering + { + if (expr->IsNumberLiteral()) { + return static_cast(expr->AsNumberLiteral()->Number().GetDouble()); + } + // References to temp variables can appear in lowerings + if (expr->IsIdentifier()) { + auto *declNode = expr->Variable()->Declaration()->Node()->Parent()->AsVariableDeclarator(); + auto *initVal = declNode->Init(); + while (initVal->IsTSAsExpression()) { + initVal = initVal->AsTSAsExpression()->Expr(); + } + ES2PANDA_ASSERT(initVal->IsNumberLiteral()); + return initVal->AsNumberLiteral()->Number().GetInt(); + } + ES2PANDA_UNREACHABLE(); + } + + // CC-OFFNXT(huge_depth,huge_method,huge_cyclomatic_complexity,G.FUN.01-CPP) solid logic + void VisitMemberExpression(ir::MemberExpression *mexpr) override + { + if (mexpr->Object()->TsType()->IsETSDynamicType()) { + return; + } + if (mexpr->Kind() == ir::MemberExpressionKind::PROPERTY_ACCESS) { + if (mexpr->Property()->Variable() != nullptr) { + checker::Type *propType = nullptr; + if (mexpr->Property()->Variable()->Declaration() != nullptr && + mexpr->Property()->Variable()->Declaration()->Node() != nullptr && + mexpr->Property()->Variable()->Declaration()->Node()->IsTyped() && + mexpr->Property()->Variable()->Declaration()->Node()->AsTyped()->TsType() != nullptr) { + HandleDeclarationNode(uctx_, mexpr->Property()->Variable()->Declaration()->Node()); + propType = mexpr->Property()->Variable()->Declaration()->Node()->AsTyped()->TsType(); + } else if (mexpr->Property()->Variable()->TsType() != nullptr) { + propType = mexpr->Property()->Variable()->TsType(); + } else { + propType = mexpr->Property()->TsType(); + } + ES2PANDA_ASSERT(propType != nullptr); + + /* Special handling for getters/setters. */ + if (propType->IsETSMethodType()) { + bool needSetter = mexpr->Parent()->IsAssignmentExpression() && + mexpr == mexpr->Parent()->AsAssignmentExpression()->Left(); + if (needSetter) { + if (auto *setterSig = propType->AsETSFunctionType()->FindSetter(); setterSig != nullptr) { + HandleDeclarationNode(uctx_, setterSig->Function()); + propType = setterSig->Params()[0]->TsType(); + } + } else if (auto *getterSig = propType->AsETSFunctionType()->FindGetter(); getterSig != nullptr) { + HandleDeclarationNode(uctx_, getterSig->Function()); + propType = getterSig->ReturnType(); + } + } else if (mexpr->Property()->Variable() != nullptr) { + /* Adjustment needed for Readonly types and possibly some other cases */ + mexpr->Property()->Variable()->SetTsType(propType); + } + + if (IsRecursivelyUnboxed(propType)) { + mexpr->Property()->SetTsType(propType); + mexpr->SetTsType(propType); + } + } else if (mexpr->Property()->Variable() == nullptr && mexpr->Object()->TsType()->IsETSArrayType() && + mexpr->Property()->AsIdentifier()->Name() == "length") { + mexpr->SetTsType(uctx_->checker->GlobalIntType()); + } + if (mexpr->Object()->TsType()->IsETSPrimitiveType() && !IsStaticMemberExpression(mexpr)) { + // NOTE(gogabr): need to handle some elementary method calls as intrinsics + mexpr->SetObject(InsertBoxing(uctx_, mexpr->Object())); + } + } else if (mexpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS) { + /* Getters are already handled in a lowering, we need a primtive as an index */ + if (TypeIsBoxedPrimitive(mexpr->Property()->TsType())) { + mexpr->SetProperty(InsertUnboxing(uctx_, mexpr->Property())); + } + + if (mexpr->Object()->TsType()->IsETSTupleType()) { + auto tupType = mexpr->Object()->TsType()->AsETSTupleType(); + auto index = GetNumberLiteral(mexpr->Property()); + ES2PANDA_ASSERT(index >= 0 && (size_t)index < tupType->GetTupleSize()); + mexpr->SetTsType(tupType->GetTupleTypesList()[index]); + } else if (mexpr->Object()->TsType()->IsETSArrayType()) { + auto *objTp = mexpr->Object()->TsType()->AsETSArrayType(); + mexpr->SetTsType(objTp->ElementType()); + } + /* mexpr->Object() may also have never type; nothing needs to be done in that case */ + } else { + ES2PANDA_UNREACHABLE(); + } + } + + void VisitTSAsExpression(ir::TSAsExpression *asExpr) override + { + auto *exprType = asExpr->Expr()->TsType(); + auto *targetType = asExpr->TypeAnnotation()->TsType(); + if (targetType->IsETSPrimitiveType() || TypeIsBoxedPrimitive(targetType)) { + if (exprType->IsETSPrimitiveType() || TypeIsBoxedPrimitive(exprType)) { + auto *primTargetType = MaybeRecursivelyUnboxType(uctx_, targetType); + asExpr->TypeAnnotation()->SetTsType(primTargetType); + asExpr->SetExpr(AdjustType(uctx_, asExpr->Expr(), MaybeRecursivelyUnboxType(uctx_, exprType))); + asExpr->SetTsType(primTargetType); + } else { + auto *boxedTargetType = uctx_->checker->MaybeBoxType(targetType); + asExpr->TypeAnnotation()->SetTsType(boxedTargetType); + asExpr->SetTsType(boxedTargetType); + } + } else if (exprType->IsETSPrimitiveType()) { + asExpr->SetExpr(AdjustType(uctx_, asExpr->Expr(), targetType)); + } + asExpr->SetTsType(asExpr->TypeAnnotation()->TsType()); + } + + void VisitConditionalExpression(ir::ConditionalExpression *cexpr) override + { + if (TypeIsBoxedPrimitive(cexpr->Test()->TsType())) { + cexpr->SetTest(InsertUnboxing(uctx_, cexpr->Test())); + } + + auto *tp = cexpr->TsType(); + if (!tp->IsETSPrimitiveType() && !TypeIsBoxedPrimitive(tp)) { + // Box if needed + cexpr->SetConsequent(AdjustType(uctx_, cexpr->Consequent(), tp)); + cexpr->SetAlternate(AdjustType(uctx_, cexpr->Alternate(), tp)); + } else { + // Unbox if needed + auto *primTp = uctx_->checker->MaybeUnboxType(tp); + cexpr->SetConsequent(AdjustType(uctx_, cexpr->Consequent(), primTp)); + cexpr->SetAlternate(AdjustType(uctx_, cexpr->Alternate(), primTp)); + cexpr->SetTsType(primTp); + } + } + + void VisitETSNewArrayInstanceExpression(ir::ETSNewArrayInstanceExpression *nexpr) override + { + auto unboxedType = MaybeRecursivelyUnboxType(uctx_, nexpr->TsType()); + nexpr->SetTsType(unboxedType); + nexpr->TypeReference()->SetTsType(unboxedType->AsETSArrayType()->ElementType()); + + nexpr->SetDimension( + AdjustType(uctx_, nexpr->Dimension(), uctx_->checker->MaybeUnboxType(nexpr->Dimension()->TsType()))); + } + + void VisitETSNewMultiDimArrayInstanceExpression(ir::ETSNewMultiDimArrayInstanceExpression *nexpr) override + { + auto *unboxedType = MaybeRecursivelyUnboxType(uctx_, nexpr->TsType()); + nexpr->SetTsType(unboxedType); + + auto toUnbox = unboxedType; + for (auto &dim : nexpr->Dimensions()) { + dim = AdjustType(uctx_, dim, uctx_->checker->MaybeUnboxType(dim->TsType())); + toUnbox = toUnbox->AsETSArrayType()->ElementType(); + } + + nexpr->TypeReference()->SetTsType(toUnbox); + nexpr->SetSignature( + uctx_->checker->CreateBuiltinArraySignature(unboxedType->AsETSArrayType(), nexpr->Dimensions().size())); + } + + void VisitBlockExpression(ir::BlockExpression *bexpr) override + { + auto &stmts = bexpr->Statements(); + auto *lastStmt = stmts[stmts.size() - 1]; + ES2PANDA_ASSERT(lastStmt->IsExpressionStatement()); + + bexpr->SetTsType(lastStmt->AsExpressionStatement()->GetExpression()->TsType()); + } + + void VisitSequenceExpression(ir::SequenceExpression *sexpr) override + { + sexpr->SetTsType(sexpr->Sequence().back()->TsType()); + } + + void HandleLiteral(ir::Literal *lit) + { + if (lit->TsType() == nullptr) { + return; + } + lit->SetTsType(uctx_->checker->MaybeUnboxType(lit->TsType())); + } + + void VisitBooleanLiteral(ir::BooleanLiteral *blit) override + { + HandleLiteral(blit); + } + void VisitCharLiteral(ir::CharLiteral *clit) override + { + HandleLiteral(clit); + } + void VisitNumberLiteral(ir::NumberLiteral *nlit) override + { + HandleLiteral(nlit); + } + + void HandleVariableRef(ir::Expression *expr) + { + auto *var = expr->Variable(); + if (var == nullptr || var->TsType() == nullptr || expr->TsType() == nullptr || + var->Declaration() == nullptr) { // lambda invoke function + return; + } + auto *declNode = var->Declaration()->Node(); + if (declNode->IsClassProperty()) { + HandleDeclarationNode(uctx_, declNode); + } + if (declNode->IsClassDeclaration() || declNode->IsTSEnumDeclaration() || declNode->IsTSInterfaceDeclaration()) { + return; + } + if (expr->Variable()->TsType()->IsETSPrimitiveType()) { + expr->SetTsType(expr->Variable()->TsType()); + } else if (expr->TsType()->IsETSPrimitiveType()) { + expr->SetTsType(uctx_->checker->MaybeBoxType(expr->TsType())); + } else { + expr->SetTsType(NormalizeType(uctx_, expr->TsType())); + } + } + + void VisitIdentifier(ir::Identifier *id) override + { + HandleVariableRef(id); + } + + void VisitTSQualifiedName(ir::TSQualifiedName *qname) override + { + HandleVariableRef(qname); + } + + void VisitAssignmentExpression(ir::AssignmentExpression *aexpr) override + { + aexpr->SetRight(AdjustType(uctx_, aexpr->Right(), aexpr->Left()->TsType())); + aexpr->SetTsType(aexpr->Left()->TsType()); + } + + void VisitClassProperty(ir::ClassProperty *prop) override + { + prop->SetValue(AdjustType(uctx_, prop->Value(), prop->Key()->Variable()->TsType())); + } + + void VisitETSParameterExpression(ir::ETSParameterExpression *pexpr) override + { + pexpr->AsETSParameterExpression()->SetInitializer( + AdjustType(uctx_, pexpr->Initializer(), pexpr->Ident()->TsType())); + } + + void VisitVariableDeclarator(ir::VariableDeclarator *vdecl) override + { + if (vdecl->Init() != nullptr) { + vdecl->SetInit(AdjustType(uctx_, vdecl->Init(), vdecl->Id()->Variable()->TsType())); + } + } + + void VisitTSNonNullExpression(ir::TSNonNullExpression *nnexpr) override + { + if (nnexpr->Expr()->TsType()->IsETSPrimitiveType()) { + ReplaceInParent(nnexpr, nnexpr->Expr()); + return; + } + nnexpr->SetTsType(uctx_->checker->GetNonNullishType(nnexpr->Expr()->TsType())); + nnexpr->SetOriginalType(nnexpr->TsType()); + } + + // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes, readability-identifier-naming) + UnboxContext *uctx_; +}; +} // namespace + +// Extracted just to avoid large depth of method 'SetUpBuiltinConstructorsAndMethods(UnboxContext *uctx)'. +static void HandleInstanceMethodsDeclaration(checker::Type *tp, UnboxContext *uctx) +{ + for (auto [_, var] : tp->AsETSObjectType()->InstanceMethods()) { + auto *nd = var->Declaration()->Node(); + HandleDeclarationNode(uctx, nd); + if (nd->IsMethodDefinition()) { + for (auto overload : nd->AsMethodDefinition()->Overloads()) { + HandleDeclarationNode(uctx, overload); + } + } + } +} + +// Extracted just to avoid large depth of method 'SetUpBuiltinConstructorsAndMethods(UnboxContext *uctx)'. +static void HandleStaticMethodDeclaration(checker::Type *tp, UnboxContext *uctx) +{ + for (auto [_, var] : tp->AsETSObjectType()->StaticMethods()) { + auto *nd = var->Declaration()->Node(); + HandleDeclarationNode(uctx, nd); + if (nd->IsMethodDefinition()) { + for (auto overload : nd->AsMethodDefinition()->Overloads()) { + HandleDeclarationNode(uctx, overload); + } + } + } +} + +// We need to convert function declarations that can be referenced even without explicit mention +// in the source code. +void SetUpBuiltinConstructorsAndMethods(UnboxContext *uctx) +{ + auto *checker = uctx->checker; + auto setUpType = [&uctx](checker::Type *tp) { + if (tp == nullptr || !tp->IsETSObjectType()) { + return; + } + for (auto *sig : tp->AsETSObjectType()->ConstructSignatures()) { + HandleDeclarationNode(uctx, sig->Function()); + } + HandleInstanceMethodsDeclaration(tp, uctx); + HandleStaticMethodDeclaration(tp, uctx); + }; + + for (auto tpix = (size_t)checker::GlobalTypeId::ETS_BOOLEAN; tpix < (size_t)checker::GlobalTypeId::ETS_BIG_INT; + tpix++) { + setUpType(checker->GetGlobalTypesHolder()->GlobalTypes()[tpix]); + } +} + +template +static void VisitExternalPrograms(UnboxVisitor *visitor, parser::Program *program) +{ + for (auto &[_, extPrograms] : program->ExternalSources()) { + (void)_; + for (auto *extProg : extPrograms) { + VisitExternalPrograms(visitor, extProg); + } + } + + if constexpr (!PROG_IS_EXTERNAL) { + return; + } + + auto annotationIterator = [visitor](auto *child) { + if (child->IsClassProperty()) { + auto prop = child->AsClassProperty(); + HandleClassProperty(visitor->uctx_, prop); + if (prop->Value() != nullptr) { + ES2PANDA_ASSERT(prop->Value()->IsLiteral() || prop->Value()->IsArrayExpression()); + prop->Value()->Accept(visitor); + } + visitor->VisitClassProperty(child->AsClassProperty()); + }; + }; + + program->Ast()->IterateRecursivelyPostorder([&annotationIterator](ir::AstNode *ast) { + if (ast->IsAnnotationDeclaration() || ast->IsAnnotationUsage()) { + // visitAnnotation(ast); + ast->Iterate(annotationIterator); + } + }); +} + +bool UnboxPhase::PerformForModule(public_lib::Context *ctx, parser::Program *program) +{ + auto uctx = UnboxContext(ctx->parser->AsETSParser(), ctx->checker->VarBinder()->AsETSBinder(), + ctx->checker->AsETSChecker()); + + SetUpBuiltinConstructorsAndMethods(&uctx); + + NormalizeAllTypes(&uctx, program->Ast()); + + program->Ast()->IterateRecursivelyPostorder([&uctx](ir::AstNode *ast) { + if (ast->IsClassProperty() || ast->IsScriptFunction() || ast->IsVariableDeclarator()) { + HandleDeclarationNode(&uctx, ast); + } else if (ast->IsForOfStatement()) { + HandleForOfStatement(&uctx, ast->AsForOfStatement()); + } + }); + + UnboxVisitor visitor(&uctx); + program->Ast()->IterateRecursivelyPostorder([&visitor](ir::AstNode *ast) { + ast->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); + ast->Accept(&visitor); + }); + VisitExternalPrograms(&visitor, program); + + for (auto *stmt : program->Ast()->Statements()) { + RefineSourceRanges(stmt); + } + uctx.checker->ClearApparentTypes(); + + return true; +} + +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.h b/ets2panda/compiler/lowering/ets/unboxLowering.h new file mode 100644 index 0000000000..d266f77905 --- /dev/null +++ b/ets2panda/compiler/lowering/ets/unboxLowering.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_LOWERING_UNBOX_LOWERING_H +#define ES2PANDA_COMPILER_LOWERING_UNBOX_LOWERING_H + +#include "compiler/lowering/phase.h" + +namespace ark::es2panda::compiler { + +class UnboxPhase : public PhaseForBodies { +public: + std::string_view Name() const override + { + return "Unbox"; + } + + bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; + // bool PostconditionForModule(public_lib::Context *ctx, const parser::Program *program) override; +}; + +} // namespace ark::es2panda::compiler + +#endif diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 0343d86635..b1f01312ad 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -32,6 +32,7 @@ #include "compiler/lowering/ets/dynamicImportLowering.h" #include "compiler/lowering/ets/enumLowering.h" #include "compiler/lowering/ets/enumPostCheckLowering.h" +#include "compiler/lowering/ets/enumPropertiesInAnnotationsLowering.h" #include "compiler/lowering/ets/restTupleLowering.h" #include "compiler/lowering/ets/expandBrackets.h" #include "compiler/lowering/ets/expressionLambdaLowering.h" @@ -59,6 +60,7 @@ #include "compiler/lowering/ets/stringConstantsLowering.h" #include "compiler/lowering/ets/stringConstructorLowering.h" #include "compiler/lowering/ets/topLevelStmts/topLevelStmts.h" +#include "compiler/lowering/ets/unboxLowering.h" #include "compiler/lowering/ets/unionLowering.h" #include "compiler/lowering/ets/typeFromLowering.h" #include "compiler/lowering/plugin_phase.h" @@ -84,6 +86,7 @@ static ConstStringToCharLowering g_constStringToCharLowering; static InterfacePropertyDeclarationsPhase g_interfacePropDeclPhase; // NOLINT(fuchsia-statically-constructed-objects) static EnumLoweringPhase g_enumLoweringPhase; static EnumPostCheckLoweringPhase g_enumPostCheckLoweringPhase; +static EnumPropertiesInAnnotationsLoweringPhase g_enumPropertiesInAnnotationsLowering; static RestTupleConstructionPhase g_restTupleConstructionPhase; static SpreadConstructionPhase g_spreadConstructionPhase; static ExtensionAccessorPhase g_extensionAccessorPhase; @@ -117,6 +120,7 @@ static AsyncMethodLowering g_asyncMethodLowering; static TypeFromLowering g_typeFromLowering; static ResizableArrayConvert g_resizableArrayConvert; static RestArgsLowering g_restArgsLowering; +static UnboxPhase g_unboxPhase; static PluginPhase g_pluginsAfterParse {"plugins-after-parse", ES2PANDA_STATE_PARSED, &util::Plugin::AfterParse}; static PluginPhase g_pluginsAfterBind {"plugins-after-bind", ES2PANDA_STATE_BOUND, &util::Plugin::AfterBind}; static PluginPhase g_pluginsAfterCheck {"plugins-after-check", ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck}; @@ -163,6 +167,7 @@ std::vector GetETSPhaseList() &g_asyncMethodLowering, &g_declareOverloadLowering, &g_enumPostCheckLoweringPhase, + &g_enumPropertiesInAnnotationsLowering, &g_spreadConstructionPhase, &g_restArgsLowering, &g_arrayLiteralLowering, @@ -187,6 +192,7 @@ std::vector GetETSPhaseList() &g_optionalArgumentsLowering, // #22952 could be moved to earlier phase &g_genericBridgesLowering, &g_typeFromLowering, + &g_unboxPhase, &g_pluginsAfterLowerings, // pluginsAfterLowerings has to come at the very end, nothing should go after it }; // NOLINTEND diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index 013f4b7e6e..5d030192cb 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -100,6 +100,23 @@ void ClearTypesVariablesAndScopes(ir::AstNode *node) noexcept doNode(node); } +ir::AstNode *RefineSourceRanges(ir::AstNode *node) +{ + auto const isDummyLoc = [](lexer::SourceRange const &range) { + return (range.start.index == 0 && range.start.line == 0) || (range.start.index > range.end.index); + }; + + auto const refine = [isDummyLoc](ir::AstNode *n) { + if (isDummyLoc(n->Range())) { + n->SetRange(n->Parent()->Range()); + }; + }; + + refine(node); + node->IterateRecursively(refine); + return node; +} + ArenaSet FindCaptured(ArenaAllocator *allocator, ir::AstNode *scopeBearer) noexcept { auto result = ArenaSet {allocator->Adapter()}; diff --git a/ets2panda/compiler/lowering/util.h b/ets2panda/compiler/lowering/util.h index 423035454f..7ec26ad44f 100644 --- a/ets2panda/compiler/lowering/util.h +++ b/ets2panda/compiler/lowering/util.h @@ -33,6 +33,7 @@ util::UString GenName(ArenaAllocator *allocator); void ClearTypesVariablesAndScopes(ir::AstNode *node) noexcept; ArenaSet FindCaptured(ArenaAllocator *allocator, ir::AstNode *scopeBearer) noexcept; void SetSourceRangesRecursively(ir::AstNode *node, const lexer::SourceRange &range); +ir::AstNode *RefineSourceRanges(ir::AstNode *node); // Rerun varbinder on the node. varbinder::Scope *Rebind(PhaseManager *phaseManager, varbinder::ETSBinder *varBinder, ir::AstNode *node); diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index 2ce7f512ad..e8c75c93ee 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -1439,6 +1439,12 @@ signatures: return_type: BUILTIN_JSVALUE ref: BUILTIN_JSRUNTIME_GET_UNDEFINED + - callee: BUILTIN_JSRUNTIME + method_name: getNull + params: [] + return_type: BUILTIN_JSVALUE + ref: BUILTIN_JSRUNTIME_GET_NULL + - callee: BUILTIN_JSRUNTIME method_name: strictEqual params: [BUILTIN_JSVALUE, BUILTIN_JSVALUE] @@ -1766,3 +1772,4 @@ dynamiclangs: - type: dynamic builtin: BUILTIN_JSRUNTIME_SET_ELEMENT_JSVALUE get_undefined: BUILTIN_JSRUNTIME_GET_UNDEFINED + get_null: BUILTIN_JSRUNTIME_GET_NULL diff --git a/ets2panda/compiler/templates/signatures.h.erb b/ets2panda/compiler/templates/signatures.h.erb index 8f09ce2292..afd5719623 100644 --- a/ets2panda/compiler/templates/signatures.h.erb +++ b/ets2panda/compiler/templates/signatures.h.erb @@ -162,6 +162,17 @@ public: ES2PANDA_UNREACHABLE(); } + static std::string_view GetNullBuiltin(Language lang) + { + ES2PANDA_ASSERT(IsSupported(lang)); +% Signatures::DYNAMIC.each do |lang, data| + if (lang.GetId() == Language::Id::<%= lang.upcase %>) { + return <%= data.builtins.get_null %>; + } +% end + ES2PANDA_UNREACHABLE(); + } + % def generate(attr, pref) % builtins = Hash.new() % Signatures::DYNAMIC.each do |lang, data| diff --git a/ets2panda/evaluate/irCheckHelper.cpp b/ets2panda/evaluate/irCheckHelper.cpp index b963be112b..2ae79653f3 100644 --- a/ets2panda/evaluate/irCheckHelper.cpp +++ b/ets2panda/evaluate/irCheckHelper.cpp @@ -65,15 +65,16 @@ void IrCheckHelper::PreCheck() isPrecheckPassed_ = true; } +// NOLINTBEGIN(readability-identifier-naming) void IrCheckHelper::CheckDecls() { // All dependent user-classes must be created at this point, so we can run checker. while (!recursiveDecls_.empty()) { auto [program, scope, parent, node] = recursiveDecls_.front(); recursiveDecls_.pop_front(); - helpers::DoScopedAction(checker_, varBinder_, program, scope, parent, [this, node = node, scope = scope]() { - varBinder_->ResolveReferencesForScope(node, scope); - node->Check(checker_); + helpers::DoScopedAction(checker_, varBinder_, program, scope, parent, [this, node_ = node, scope_ = scope]() { + varBinder_->ResolveReferencesForScope(node_, scope_); + node_->Check(checker_); }); } } @@ -87,10 +88,11 @@ void IrCheckHelper::HandleCustomNodes() // Hence we delay `ETSChecker::Check` until all required classes are built and initialized in varbinder. auto [program, scope, parent, node] = *iter; helpers::DoScopedAction(checker_, varBinder_, program, scope, parent, - [varBinder = varBinder_, node = node]() { varBinder->HandleCustomNodes(node); }); + [varBinder = varBinder_, node_ = node]() { varBinder->HandleCustomNodes(node_); }); ++iter; } } +// NOLINTEND(readability-identifier-naming) void IrCheckHelper::CheckGlobalEntity(parser::Program *program, ir::AstNode *node, bool mustCheck) { diff --git a/ets2panda/ir/ets/etsFunctionType.cpp b/ets2panda/ir/ets/etsFunctionType.cpp index da4e93b20c..89de5eee97 100644 --- a/ets2panda/ir/ets/etsFunctionType.cpp +++ b/ets2panda/ir/ets/etsFunctionType.cpp @@ -160,10 +160,6 @@ ETSFunctionType *ETSFunctionType::Clone(ArenaAllocator *const allocator, AstNode clone->SetAnnotations(std::move(annotationUsages)); } - // If the scope is set to empty, it will result in the inability to retrieve the scope after clone, - // and an error cannot find type will be reported - clone->SetScope(this->scope_); - return clone; } } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ets/etsPrimitiveType.cpp b/ets2panda/ir/ets/etsPrimitiveType.cpp index c18f743502..3809054d94 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.cpp +++ b/ets2panda/ir/ets/etsPrimitiveType.cpp @@ -111,35 +111,35 @@ checker::Type *ETSPrimitiveType::GetType([[maybe_unused]] checker::ETSChecker *c { switch (type_) { case PrimitiveType::BYTE: { - SetTsType(checker->GlobalByteType()); + SetTsType(checker->GlobalByteBuiltinType()); return TsType(); } case PrimitiveType::SHORT: { - SetTsType(checker->GlobalShortType()); + SetTsType(checker->GlobalShortBuiltinType()); return TsType(); } case PrimitiveType::INT: { - SetTsType(checker->GlobalIntType()); + SetTsType(checker->GlobalIntBuiltinType()); return TsType(); } case PrimitiveType::LONG: { - SetTsType(checker->GlobalLongType()); + SetTsType(checker->GlobalLongBuiltinType()); return TsType(); } case PrimitiveType::FLOAT: { - SetTsType(checker->GlobalFloatType()); + SetTsType(checker->GlobalFloatBuiltinType()); return TsType(); } case PrimitiveType::DOUBLE: { - SetTsType(checker->GlobalDoubleType()); + SetTsType(checker->GlobalDoubleBuiltinType()); return TsType(); } case PrimitiveType::BOOLEAN: { - SetTsType(checker->GlobalETSBooleanType()); + SetTsType(checker->GlobalETSBooleanBuiltinType()); return TsType(); } case PrimitiveType::CHAR: { - SetTsType(checker->GlobalCharType()); + SetTsType(checker->GlobalCharBuiltinType()); return TsType(); } case PrimitiveType::VOID: { diff --git a/ets2panda/ir/ets/etsTuple.cpp b/ets2panda/ir/ets/etsTuple.cpp index a9ee2ee9d5..9fb5061662 100644 --- a/ets2panda/ir/ets/etsTuple.cpp +++ b/ets2panda/ir/ets/etsTuple.cpp @@ -97,10 +97,8 @@ checker::Type *ETSTuple::GetHolderTypeForTuple(checker::ETSChecker *const checke return typeList[0]; } - std::for_each(typeList.begin(), typeList.end(), [checker](auto &t) { t = checker->MaybeBoxType(t); }); - - auto ctypes = typeList; - return checker->CreateETSUnionType(std::move(ctypes)); + /* NOTE(gogabr): if we compute a union type, we'll lose smaller numeric types, so just return Object */ + return checker->GlobalETSNullishObjectType(); } checker::Type *ETSTuple::GetType(checker::ETSChecker *const checker) diff --git a/ets2panda/ir/expressions/binaryExpression.h b/ets2panda/ir/expressions/binaryExpression.h index e7accbe3b4..97de660fce 100644 --- a/ets2panda/ir/expressions/binaryExpression.h +++ b/ets2panda/ir/expressions/binaryExpression.h @@ -114,21 +114,18 @@ public: { left_ = expr; left_->SetParent(this); - SetStart(left_->Start()); } void SetRight(Expression *expr) noexcept { right_ = expr; right_->SetParent(this); - SetEnd(right_->End()); } void SetResult(Expression *expr) noexcept { result_ = expr; result_->SetParent(this); - SetStart(result_->Start()); } void SetOperator(lexer::TokenType operatorType) noexcept diff --git a/ets2panda/ir/expressions/identifier.cpp b/ets2panda/ir/expressions/identifier.cpp index 3234d31f5d..dc9f18f9e2 100644 --- a/ets2panda/ir/expressions/identifier.cpp +++ b/ets2panda/ir/expressions/identifier.cpp @@ -443,7 +443,8 @@ bool Identifier::CheckDeclarationsPart2(const ir::AstNode *parent, ScriptExtensi } if (parent->Parent() != nullptr) { - if (parent->Parent()->IsTSEnumDeclaration()) { + if (parent->Parent()->IsTSEnumDeclaration() && + !(parent->IsTSEnumMember() && parent->AsTSEnumMember()->Init() == this)) { return true; } } diff --git a/ets2panda/ir/expressions/literals/charLiteral.cpp b/ets2panda/ir/expressions/literals/charLiteral.cpp index c97c0216f0..16f519fc71 100644 --- a/ets2panda/ir/expressions/literals/charLiteral.cpp +++ b/ets2panda/ir/expressions/literals/charLiteral.cpp @@ -35,13 +35,7 @@ void CharLiteral::Dump(ir::AstDumper *dumper) const void CharLiteral::Dump(ir::SrcDumper *dumper) const { - std::string utf8Str = util::Helpers::UTF16toUTF8(char_); - if (UNLIKELY(utf8Str.empty())) { - dumper->Add(std::to_string(char_)); - return; - } - - dumper->Add("c\'" + util::Helpers::CreateEscapedString(utf8Str) + "\'"); + dumper->Add("c\'" + ToString() + "\'"); } void CharLiteral::Compile([[maybe_unused]] compiler::PandaGen *pg) const @@ -77,8 +71,11 @@ CharLiteral *CharLiteral::Clone(ArenaAllocator *const allocator, AstNode *const std::string CharLiteral::ToString() const { - std::string charStr; - util::StringView::Mutf8Encode(&charStr, char_); - return charStr; + std::string utf8Str = util::Helpers::UTF16toUTF8(char_); + if (UNLIKELY(utf8Str.empty())) { + return std::to_string(char_); + } + return util::Helpers::CreateEscapedString(utf8Str); } + } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/expressions/literals/numberLiteral.cpp b/ets2panda/ir/expressions/literals/numberLiteral.cpp index 7a2c2267dc..7fe2c22143 100644 --- a/ets2panda/ir/expressions/literals/numberLiteral.cpp +++ b/ets2panda/ir/expressions/literals/numberLiteral.cpp @@ -62,6 +62,16 @@ void NumberLiteral::Dump(ir::SrcDumper *dumper) const dumper->Add(number_.GetDouble()); return; } + + if (number_.IsShort()) { + dumper->Add(number_.GetShort()); + return; + } + + if (number_.IsByte()) { + dumper->Add(number_.GetByte()); + return; + } } dumper->Add(std::string(number_.Str())); } @@ -387,6 +397,14 @@ std::string NumberLiteral::ToString() const FpToString(number_.GetFloat(), result); } + if (number_.IsShort()) { + IntegerToString(number_.GetShort(), result); + } + + if (number_.IsByte()) { + IntegerToString(static_cast(number_.GetByte()), result); + } + ES2PANDA_ASSERT(!result.empty()); return result; } diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index fa676f54d2..8fb25780f2 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -285,33 +285,10 @@ checker::Type *MemberExpression::SetAndAdjustType(checker::ETSChecker *checker, std::optional MemberExpression::GetTupleIndexValue() const { - auto *propType = property_->TsType(); - if (object_->TsType() == nullptr || !object_->TsType()->IsETSTupleType() || - !propType->HasTypeFlag(checker::TypeFlag::CONSTANT | checker::TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { + if (object_->TsType() == nullptr || !object_->TsType()->IsETSTupleType() || !property_->IsNumberLiteral()) { return std::nullopt; } - - if (propType->IsByteType()) { - return propType->AsByteType()->GetValue(); - } - - if (propType->IsShortType()) { - return propType->AsShortType()->GetValue(); - } - - if (propType->IsIntType()) { - return propType->AsIntType()->GetValue(); - } - - if (propType->IsLongType()) { - if (auto val = propType->AsLongType()->GetValue(); - val <= std::numeric_limits::max() && val >= std::numeric_limits::min()) { - return static_cast(val); - } - return std::nullopt; - } - - ES2PANDA_UNREACHABLE(); + return property_->AsNumberLiteral()->Number().GetValueAndCastTo(); } bool MemberExpression::CheckArrayIndexValue(checker::ETSChecker *checker) const @@ -321,7 +298,7 @@ bool MemberExpression::CheckArrayIndexValue(checker::ETSChecker *checker) const auto const &number = property_->AsNumberLiteral()->Number(); if (number.IsInteger()) { - auto const value = number.GetLong(); + auto const value = number.GetValueAndCastTo(); if (value < 0) { checker->LogError(diagnostic::NEGATIVE_INDEX, {}, property_->Start()); return false; @@ -329,8 +306,7 @@ bool MemberExpression::CheckArrayIndexValue(checker::ETSChecker *checker) const index = static_cast(value); } else { ES2PANDA_ASSERT(number.IsReal()); - - double value = number.GetDouble(); + double value = number.GetValueAndCastTo(); double fraction = std::modf(value, &value); if (value < 0.0 || fraction >= std::numeric_limits::epsilon()) { checker->LogError(diagnostic::INDEX_NEGATIVE_OR_FRACTIONAL, {}, property_->Start()); @@ -419,15 +395,15 @@ checker::Type *MemberExpression::CheckIndexAccessMethod(checker::ETSChecker *che checker::Type *MemberExpression::GetTypeOfTupleElement(checker::ETSChecker *checker, checker::Type *baseType) { ES2PANDA_ASSERT(baseType->IsETSTupleType()); - checker::Type *type = nullptr; + ir::Expression *expr = nullptr; if (Property()->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { ES2PANDA_ASSERT(Property()->Variable()->Declaration()->Node()->AsClassElement()->Value()); - type = Property()->Variable()->Declaration()->Node()->AsClassElement()->Value()->TsType(); + expr = Property()->Variable()->Declaration()->Node()->AsClassElement()->Value(); } else { - type = Property()->TsType(); + expr = Property(); } - auto idxIfAny = checker->GetTupleElementAccessValue(type); + auto idxIfAny = checker->GetTupleElementAccessValue(expr); if (!idxIfAny.has_value()) { return nullptr; } diff --git a/ets2panda/ir/expressions/unaryExpression.h b/ets2panda/ir/expressions/unaryExpression.h index ac4d753d4e..18ae810939 100644 --- a/ets2panda/ir/expressions/unaryExpression.h +++ b/ets2panda/ir/expressions/unaryExpression.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -63,6 +63,11 @@ public: return argument_; } + void SetArgument(Expression *arg) + { + argument_ = arg; + } + [[nodiscard]] UnaryExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; diff --git a/ets2panda/ir/srcDump.cpp b/ets2panda/ir/srcDump.cpp index cd690492fc..b1b410f190 100644 --- a/ets2panda/ir/srcDump.cpp +++ b/ets2panda/ir/srcDump.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Huawei Device Co., Ltd. 2021-2024. All rights reserved. + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -55,6 +55,16 @@ void SrcDumper::Add(const std::string &str) ss_ << str; } +void SrcDumper::Add(int8_t i) +{ + ss_ << static_cast(i); +} + +void SrcDumper::Add(int16_t i) +{ + ss_ << i; +} + void SrcDumper::Add(int32_t i) { ss_ << i; diff --git a/ets2panda/ir/srcDump.h b/ets2panda/ir/srcDump.h index a60b6fe885..427a5cb4b9 100644 --- a/ets2panda/ir/srcDump.h +++ b/ets2panda/ir/srcDump.h @@ -31,6 +31,8 @@ public: explicit SrcDumper(const ir::AstNode *node); void Add(const std::string &str); + void Add(int8_t i); + void Add(int16_t i); void Add(int32_t i); void Add(int64_t l); void Add(float f); diff --git a/ets2panda/ir/statements/annotationUsage.cpp b/ets2panda/ir/statements/annotationUsage.cpp index f45e552769..3ef4f21faf 100644 --- a/ets2panda/ir/statements/annotationUsage.cpp +++ b/ets2panda/ir/statements/annotationUsage.cpp @@ -23,7 +23,7 @@ void AnnotationUsage::TransformChildren(const NodeTransformer &cb, std::string_v { if (auto *transformedNode = cb(expr_); expr_ != transformedNode) { expr_->SetTransformedNode(transformationName, transformedNode); - expr_ = transformedNode->AsIdentifier(); + expr_ = transformedNode->AsExpression(); } for (auto *&it : VectorIterationGuard(properties_)) { diff --git a/ets2panda/ir/statements/ifStatement.h b/ets2panda/ir/statements/ifStatement.h index 31860fefa6..8d6eaffbaa 100644 --- a/ets2panda/ir/statements/ifStatement.h +++ b/ets2panda/ir/statements/ifStatement.h @@ -49,6 +49,11 @@ public: return test_; } + void SetTest(Expression *test) noexcept + { + test_ = test; + } + [[nodiscard]] const Statement *Consequent() const noexcept { return consequent_; diff --git a/ets2panda/ir/statements/switchCaseStatement.cpp b/ets2panda/ir/statements/switchCaseStatement.cpp index f81b7c5409..712190e1be 100644 --- a/ets2panda/ir/statements/switchCaseStatement.cpp +++ b/ets2panda/ir/statements/switchCaseStatement.cpp @@ -103,7 +103,7 @@ void SwitchCaseStatement::CheckAndTestCase(checker::ETSChecker *checker, checker checker::Type *unboxedDiscType, ir::Expression *node, bool &isDefaultCase) { if (test_ != nullptr) { - auto caseType = test_->Check(checker); + auto *caseType = checker->MaybeUnboxType(test_->Check(checker)); bool validCaseType = true; if (caseType->HasTypeFlag(checker::TypeFlag::CHAR)) { diff --git a/ets2panda/ir/statements/whileStatement.h b/ets2panda/ir/statements/whileStatement.h index 7fe2484669..7280ef306b 100644 --- a/ets2panda/ir/statements/whileStatement.h +++ b/ets2panda/ir/statements/whileStatement.h @@ -42,6 +42,11 @@ public: return test_; } + void SetTest(Expression *test) + { + test_ = test; + } + const Statement *Body() const { return body_; diff --git a/ets2panda/lexer/lexer.h b/ets2panda/lexer/lexer.h index 94b10631ce..f547761901 100644 --- a/ets2panda/lexer/lexer.h +++ b/ets2panda/lexer/lexer.h @@ -613,6 +613,7 @@ bool Lexer::ScanNumberRadix(bool leadingMinus, bool allowNumericSeparator) } GetToken().number_ = lexer::Number(number); + GetToken().number_.SetStr(SourceView(GetToken().Start().index, Iterator().Index())); return true; } diff --git a/ets2panda/lexer/token/number.h b/ets2panda/lexer/token/number.h index 47d8b2d0d1..3dc1b3c5f3 100644 --- a/ets2panda/lexer/token/number.h +++ b/ets2panda/lexer/token/number.h @@ -64,6 +64,10 @@ public: // NOLINTNEXTLINE(bugprone-exception-escape) explicit Number(util::StringView str, NumberFlags flags) noexcept; explicit Number(util::StringView str, double num) noexcept : str_(str), num_(num) {} + explicit Number(uint8_t num) noexcept : Number(static_cast(num)) {} + explicit Number(int8_t num) noexcept : num_(num) {} + explicit Number(uint16_t num) noexcept : Number(static_cast(num)) {} + explicit Number(int16_t num) noexcept : num_(num) {} explicit Number(uint32_t num) noexcept : Number(static_cast(num)) {} explicit Number(int32_t num) noexcept : num_(num) {} explicit Number(uint64_t num) noexcept : Number(static_cast(num)) {} @@ -75,6 +79,16 @@ public: ~Number() = default; // NOLINTEND(cppcoreguidelines-pro-type-member-init) + bool IsByte() const noexcept + { + return std::holds_alternative(num_); + } + + bool IsShort() const noexcept + { + return std::holds_alternative(num_); + } + bool IsInt() const noexcept { return std::holds_alternative(num_); @@ -87,7 +101,7 @@ public: bool IsInteger() const noexcept { - return IsInt() || IsLong(); + return IsByte() || IsShort() || IsInt() || IsLong(); } bool IsFloat() const noexcept @@ -110,19 +124,44 @@ public: return (flags_ & NumberFlags::ERROR) != 0; } + int8_t GetByte() const + { + ES2PANDA_ASSERT(IsByte()); + return std::get(num_); + } + + int16_t GetShort() const + { + return std::visit(overloaded {[](int16_t value) { return value; }, + [](int8_t value) { return static_cast(value); }, + []([[maybe_unused]] auto value) { + ES2PANDA_ASSERT(false); + return static_cast(value); + }}, + num_); + } + int32_t GetInt() const { - ES2PANDA_ASSERT(IsInt()); - return std::get(num_); + return std::visit(overloaded {[](int32_t value) { return value; }, + [](int16_t value) { return static_cast(value); }, + [](int8_t value) { return static_cast(value); }, + []([[maybe_unused]] auto value) { + ES2PANDA_ASSERT(false); + return static_cast(value); + }}, + num_); } int64_t GetLong() const { return std::visit(overloaded {[](int64_t value) { return value; }, [](int32_t value) { return static_cast(value); }, + [](int16_t value) { return static_cast(value); }, + [](int8_t value) { return static_cast(value); }, []([[maybe_unused]] auto value) { ES2PANDA_ASSERT(false); - return static_cast(0); + return static_cast(value); }}, num_); } @@ -145,6 +184,11 @@ public: return str_; } + void SetStr(util::StringView str) + { + str_ = str; + } + void Negate() { std::visit(overloaded {[](auto &value) { value = -value; }}, num_); @@ -156,6 +200,12 @@ public: } } + bool IsZero() const + { + return std::visit(overloaded {[](auto &value) { return value == 0; }}, num_); + } + + // NOLINTBEGIN(readability-else-after-return) template bool CanGetValue() const noexcept { @@ -164,11 +214,15 @@ public: if constexpr (std::is_same_v) { return IsInteger(); } else if constexpr (std::is_same_v) { - return IsInt(); + return IsInt() || IsShort() || IsByte(); } else if constexpr (std::is_same_v) { return true; } else if constexpr (std::is_same_v) { return IsFloat(); + } else if constexpr (std::is_same_v) { + return IsShort() || IsByte(); + } else if constexpr (std::is_same_v) { + return IsByte(); } else { return false; } @@ -187,18 +241,42 @@ public: return GetDouble(); } else if constexpr (std::is_same_v) { return GetFloat(); + } else if constexpr (std::is_same_v) { + return GetShort(); + } else if constexpr (std::is_same_v) { + return GetByte(); } else { static_assert(dependent_false_v, "Invalid value type was requested for Number."); } } + template + TargetType GetValueAndCastTo() const + { + if (IsByte()) { + return static_cast(GetByte()); + } else if (IsShort()) { + return static_cast(GetShort()); + } else if (IsInt()) { + return static_cast(GetInt()); + } else if (IsLong()) { + return static_cast(GetLong()); + } else if (IsFloat()) { + return static_cast(GetFloat()); + } else if (IsDouble()) { + return static_cast(GetDouble()); + } + ES2PANDA_UNREACHABLE(); + } + // NOLINTEND(readability-else-after-return) + template void SetValue(RT &&value) { using T = typename std::remove_cv_t>; - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v) { + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v) { num_ = std::forward(value); } else { static_assert(dependent_false_v, "Invalid value type was requested for Number."); @@ -207,7 +285,7 @@ public: private: util::StringView str_ {}; - std::variant num_; + std::variant num_; NumberFlags flags_ {NumberFlags::NONE}; }; } // namespace ark::es2panda::lexer diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 091f63ce30..750c7d34b6 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -149,6 +149,7 @@ ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFla char32_t beginningChar = Lexer()->Lookahead(); auto start = Lexer()->GetToken().Start(); + auto const inParenthesis = Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_PAREN; Lexer()->NextToken(tokenFlags); ir::Expression *argument = ResolveArgumentUnaryExpr(flags); diff --git a/ets2panda/public/public.h b/ets2panda/public/public.h index ba457ce992..acc4a8f421 100644 --- a/ets2panda/public/public.h +++ b/ets2panda/public/public.h @@ -23,7 +23,7 @@ #include "compiler/core/compileQueue.h" #include "parser/ETSparser.h" -#include "checker/checker.h" +#include "checker/ETSchecker.h" #include "compiler/core/emitter.h" namespace ark::es2panda::util { diff --git a/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets b/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets index 00f05b825e..9e0ebf92e4 100644 --- a/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets +++ b/ets2panda/test/ast/compiler/ets/DeclareCheckAssign.ets @@ -26,7 +26,7 @@ export declare const int_17 = 12345 export declare const int_18: number = 12345 declare const x1: int = 5 declare const x2: int = -5 -declare const y1: float = 5.55 +declare const y1: float = 5.55f declare const y2: double = -5.55 declare const x3: int = 0x5 declare const x4: int = 0b101 @@ -50,7 +50,6 @@ declare const x51 = "abc" /* @@? 18:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_13 */ /* @@? 18:70 Error TypeError: Initializers are not allowed in ambient contexts: byte_23 */ /* @@? 19:38 Error TypeError: Initializers are not allowed in ambient contexts: byte_14 */ -/* @@? 20:30 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: int_1 */ /* @@? 22:31 Error TypeError: A 'const' initializer in an ambient context must be a string or numeric literal: int_12 */ /* @@? 24:36 Error TypeError: Initializers are not allowed in ambient contexts: int_16 */ /* @@? 26:39 Error TypeError: Initializers are not allowed in ambient contexts: int_18 */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets index 3de0187673..abbbc6bcca 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationDecl_bad_initializer08.ets @@ -24,10 +24,10 @@ enum Size{S, M, L, XL, XXL} testProperty5: FixedArray = [Color.GREEN, Color.BLUE] } -/* @@? 20:29 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 22:39 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'int' */ -/* @@? 22:44 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'int' */ +/* @@? 20:29 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'Boolean' */ +/* @@? 22:39 Error TypeError: Array element at index 0 with type 'Double' is not compatible with the target array element type 'Int' */ +/* @@? 22:44 Error TypeError: Array element at index 1 with type 'Double' is not compatible with the target array element type 'Int' */ /* @@? 23:28 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ /* @@? 24:40 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ /* @@? 24:53 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets index dc97fe475c..5199df48ef 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/annotation_tests/annotationUsage_bad_param09.ets @@ -35,10 +35,10 @@ class B{ foo(){} } -/* @@? 29:24 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 31:25 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'int' */ -/* @@? 31:30 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'int' */ +/* @@? 29:24 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'Boolean' */ +/* @@? 31:25 Error TypeError: Array element at index 0 with type 'Double' is not compatible with the target array element type 'Int' */ +/* @@? 31:30 Error TypeError: Array element at index 1 with type 'Double' is not compatible with the target array element type 'Int' */ /* @@? 32:24 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ /* @@? 33:25 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ /* @@? 33:38 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets b/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets index e53edf414f..05c91630b4 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets @@ -17,7 +17,7 @@ class C { public met(...p: FixedArray): string { return "nR" } - public met(...p: FixedArray): string { + public met(...p: FixedArray): string { return "NR" } } diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets b/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets index 2af023757f..9c64efd7b2 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/same_assembly_overload/overload_signature_pos_2.ets @@ -15,11 +15,8 @@ //With rest parameter export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number export declare function foo(a:int, b:int):void export declare function foo(a:double):void export declare function foo(...args:FixedArray):void - -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ - diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets b/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets new file mode 100644 index 0000000000..7fa539e519 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/FixedArray/spreadMultiArrayInTuple.ets @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function main() { + let x1 = [1, "a"] + let y1: [int, string, int, string] = /* @@ label */[/* @@ label1 */...x1, /* @@ label2 */...x1] + let x2 = [2] + let x3 = ["abc", "abc"] + let y2: [boolean, int, string, string] = /* @@ label3 */[true, /* @@ label4 */...x2, /* @@ label5 */...x3] +} + +/* @@? 18:56 Error TypeError: Initializer has 2 elements, but tuple requires 4 */ +/* @@? 18:72 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ +/* @@? 18:94 Error TypeError: '(Int|String)[]' cannot be spread in tuple. */ +/* @@? 21:61 Error TypeError: Initializer has 3 elements, but tuple requires 4 */ +/* @@? 21:83 Error TypeError: 'Double[]' cannot be spread in tuple. */ +/* @@? 21:105 Error TypeError: 'String[]' cannot be spread in tuple. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets index 83dfc9bcf5..a6a67b7da7 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_5_neg.ets @@ -24,8 +24,6 @@ function main(): void { /* @@? 18:32 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 18:32 Error SyntaxError: Unexpected token '>'. */ /* @@? 18:32 Error SyntaxError: Unexpected token '>'. */ -/* @@? 18:32 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 18:32 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 18:35 Error TypeError: Type name 'number' used in the wrong context */ /* @@? 18:42 Error SyntaxError: Unexpected token ']'. */ /* @@? 18:42 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets index de7338a66b..063b903dd0 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/tuple_types_9_neg.ets @@ -24,8 +24,6 @@ function main(): void { /* @@? 18:40 Error SyntaxError: Unexpected token, expected ',' or ']'. */ /* @@? 18:40 Error SyntaxError: Unexpected token '>'. */ /* @@? 18:40 Error SyntaxError: Unexpected token '>'. */ -/* @@? 18:40 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 18:40 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 18:43 Error TypeError: Class name 'Int' used in the wrong context */ /* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ /* @@? 18:47 Error SyntaxError: Unexpected token ']'. */ diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets b/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets index 616aaac57f..bffcc4a776 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/unionCommonMember_neg.ets @@ -42,7 +42,7 @@ function getUnion(): A | B { function main() { const u = getUnion() assertEQ(/* @@ label1 */u.fld1, 42) - assertEQ(/* @@ label2 */u.fld2, 42.0) + assertEQ(u.fld2, 42.0) assertEQ(/* @@ label3 */u.fld3[0], "abc") assertEQ(/* @@ label4 */u.fld4[0], "def") assertEQ(/* @@ label5 */u.fld5, 42.0) @@ -52,7 +52,6 @@ function main() { } /* @@@ label1 Error TypeError: Member type must be the same for all union objects. */ -/* @@@ label2 Error TypeError: Member type must be the same for all union objects. */ /* @@@ label3 Error TypeError: Member type must be the same for all union objects. */ /* @@@ label4 Error TypeError: Member type must be the same for all union objects. */ /* @@@ label5 Error TypeError: Member type must be the same for all union objects. */ diff --git a/ets2panda/test/ast/compiler/ets/FunctionType10.ets b/ets2panda/test/ast/compiler/ets/FunctionType10.ets index 2c1abfa1d1..fc1a41058c 100644 --- a/ets2panda/test/ast/compiler/ets/FunctionType10.ets +++ b/ets2panda/test/ast/compiler/ets/FunctionType10.ets @@ -21,4 +21,4 @@ function main() { let goo : int = /* @@ label */foo } -/* @@@ label Error TypeError: Type '() => Int' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '() => Int' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/FunctionType3.ets b/ets2panda/test/ast/compiler/ets/FunctionType3.ets index b4524e83ec..0e68f79c69 100644 --- a/ets2panda/test/ast/compiler/ets/FunctionType3.ets +++ b/ets2panda/test/ast/compiler/ets/FunctionType3.ets @@ -24,4 +24,4 @@ function main(): void { } /* @@@ label1 Error TypeError: Type '"foo"' is not compatible with type 'Int' at index 2 */ -/* @@@ label Error TypeError: No matching call signature for (int, "foo") */ +/* @@@ label Error TypeError: No matching call signature for (Int, "foo") */ diff --git a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets index f3352a60e9..367544573f 100644 --- a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets +++ b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_1.ets @@ -16,4 +16,4 @@ class A>{} class B{} class C extends A/* @@ label */{} -/* @@@ label Error TypeError: Type B is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'B' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets index 9b39a2bf97..da65d44cd5 100644 --- a/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets +++ b/ets2panda/test/ast/compiler/ets/TypeError_recursive_parameter_2.ets @@ -17,4 +17,4 @@ class A>{} class P2{} class P1 extends A/* @@ label */{} -/* @@@ label Error TypeError: Type P2 is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'P2' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets index 6e6a14c6ef..23c49fd00f 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationDecl_bad_initializer08.ets @@ -24,10 +24,10 @@ enum Size{S, M, L, XL, XXL} testProperty5: Size[] = [Color.GREEN, Color.BLUE] } -/* @@? 20:29 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 22:29 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'Int' */ -/* @@? 22:34 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'Int' */ +/* @@? 20:29 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 21:30 Error TypeError: Type '"false"' cannot be assigned to type 'Boolean' */ +/* @@? 22:39 Error TypeError: Array element at index 0 with type 'Double' is not compatible with the target array element type 'Int' */ +/* @@? 22:44 Error TypeError: Array element at index 1 with type 'Double' is not compatible with the target array element type 'Int' */ /* @@? 23:28 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ /* @@? 24:30 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ /* @@? 24:43 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets index 09e201db4e..679bc167bb 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_as_type10.ets @@ -19,6 +19,4 @@ let a = 1 instanceof MyAnno /* @@? 19:22 Error TypeError: Annotations cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ -/* @@? 19:22 Error TypeError: Annotations cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ \ No newline at end of file +/* @@? 19:22 Error TypeError: Annotations cannot be used as a type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets index b18eb027e5..4904fabba8 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param07.ets @@ -21,5 +21,5 @@ @MyAnno({testProperty1: /* @@ label */1, testProperty2: /* @@ label1 */""}) function foo(){} -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@@ label1 Error TypeError: Type '""' cannot be assigned to type 'double' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@@ label1 Error TypeError: Type '""' cannot be assigned to type 'Double' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets index ba05db9e13..09bee29a1d 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_bad_param09.ets @@ -35,10 +35,10 @@ class B{ foo(){} } -/* @@? 29:24 Error TypeError: Type 'int' cannot be assigned to type 'String' */ -/* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'boolean' */ -/* @@? 31:25 Error TypeError: Array element at index 0 with type 'double' is not compatible with the target array element type 'Int' */ -/* @@? 31:30 Error TypeError: Array element at index 1 with type 'double' is not compatible with the target array element type 'Int' */ +/* @@? 29:24 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ +/* @@? 30:24 Error TypeError: Type '"false"' cannot be assigned to type 'Boolean' */ +/* @@? 31:25 Error TypeError: Array element at index 0 with type 'Double' is not compatible with the target array element type 'Int' */ +/* @@? 31:30 Error TypeError: Array element at index 1 with type 'Double' is not compatible with the target array element type 'Int' */ /* @@? 32:24 Error TypeError: Type 'Size' cannot be assigned to type 'Color' */ /* @@? 33:25 Error TypeError: Array element at index 0 with type 'Color' is not compatible with the target array element type 'Size' */ /* @@? 33:38 Error TypeError: Array element at index 1 with type 'Color' is not compatible with the target array element type 'Size' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets index 065c6baad1..a61fa5db89 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotationUsage_unordered_params.ets @@ -21,5 +21,5 @@ @MyAnno({testProperty2: /* @@ label */"Bob", testProperty1: /* @@ label1 */1}) class A{} -/* @@@ label Error TypeError: Type '"Bob"' cannot be assigned to type 'double' */ -/* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type '"Bob"' cannot be assigned to type 'Double' */ +/* @@@ label1 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets index e358f9440e..3de515f15a 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_as_negative_case.ets @@ -20,6 +20,6 @@ class A {} } -/* @@? 18:18 Error TypeError: Cannot cast type 'int' to 'String' */ -/* @@? 19:15 Error TypeError: Cannot cast type 'int' to 'A' */ -/* @@? 19:15 Error TypeError: Type 'A' cannot be assigned to type 'int' */ \ No newline at end of file +/* @@? 18:18 Error TypeError: Cannot cast type 'Int' to 'String' */ +/* @@? 19:15 Error TypeError: Cannot cast type 'Int' to 'A' */ +/* @@? 19:15 Error TypeError: Type 'A' cannot be assigned to type 'Int' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/assert_bad.ets b/ets2panda/test/ast/compiler/ets/assert_bad.ets index 0e9743b4bd..2e425b5250 100644 --- a/ets2panda/test/ast/compiler/ets/assert_bad.ets +++ b/ets2panda/test/ast/compiler/ets/assert_bad.ets @@ -19,5 +19,5 @@ function main(): int { return 0; } -/* @@@ label1 Error TypeError: No matching call signature for assertEQ(int, int, int) */ -/* @@@ label2 Error TypeError: Type 'int' is not compatible with type 'String|undefined' at index 3 */ \ No newline at end of file +/* @@@ label1 Error TypeError: No matching call signature for assertEQ(Int, Int, Int) */ +/* @@@ label2 Error TypeError: Type 'Int' is not compatible with type 'String|undefined' at index 3 */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/async_import_3.ets b/ets2panda/test/ast/compiler/ets/async_import_3.ets index 3622080a97..165c0f7649 100644 --- a/ets2panda/test/ast/compiler/ets/async_import_3.ets +++ b/ets2panda/test/ast/compiler/ets/async_import_3.ets @@ -16,4 +16,4 @@ import {foo} from './async_import_4' let prop: int = foo() /* @@? 16:17 Error TypeError: Cannot use type 'void' as value. */ -/* @@? 16:17 Error TypeError: Type 'void' cannot be assigned to type 'int' */ \ No newline at end of file +/* @@? 16:17 Error TypeError: Type 'void' cannot be assigned to type 'Int' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts b/ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts new file mode 100644 index 0000000000..8e8a1ea0ff --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/boxed_primitives_overloading.sts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + func(a: Double): String { return a.toExponential() } + func(a: Float): String { return a.toString() } + func(a: Int): String { return a.toString() } +} + +function main(): int{ + let c1: A = new A(); + let helpbyte: Byte = new Byte(1 as byte); + let helpdouble: Double = new Double(1 as double); + if (c1.func(helpbyte) != helpdouble.toExponential()) { + return 1; + } + return 0; +} diff --git a/ets2panda/test/ast/compiler/ets/boxingConversion1.ets b/ets2panda/test/ast/compiler/ets/boxingConversion1.ets index c4d703e4a2..668502185a 100644 --- a/ets2panda/test/ast/compiler/ets/boxingConversion1.ets +++ b/ets2panda/test/ast/compiler/ets/boxingConversion1.ets @@ -18,4 +18,4 @@ function main() : void { let b: Byte = /* @@ label */new Byte(2); } -/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(int) */ +/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/boxingConversion4.ets b/ets2panda/test/ast/compiler/ets/boxingConversion4.ets index 219921314b..b26c8b8c52 100644 --- a/ets2panda/test/ast/compiler/ets/boxingConversion4.ets +++ b/ets2panda/test/ast/compiler/ets/boxingConversion4.ets @@ -23,6 +23,6 @@ function main() : void { refInt(b); // primitive widening before boxing is not allowed } -/* @@@ label Error TypeError: No matching construct signature for std.core.Short(int) */ -/* @@@ label1 Error TypeError: Type 'int' cannot be assigned to type 'short' */ -/* @@@ label2 Error TypeError: Type 'int' cannot be assigned to type 'short' */ +/* @@@ label Error TypeError: No matching construct signature for std.core.Short(Int) */ +/* @@@ label1 Error TypeError: Type 'Int' cannot be assigned to type 'Short' */ +/* @@@ label2 Error TypeError: Type 'Int' cannot be assigned to type 'Short' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets index a19a44352a..020e690781 100644 --- a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets +++ b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType1.ets @@ -16,5 +16,3 @@ function foo(data : T): void { let aNumber = data! as boolean } - -/* @@? 17:19 Error TypeError: Cannot cast type 'NonNullable' to 'boolean' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets index 1494ec034e..e2f0327a04 100644 --- a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets +++ b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType2.ets @@ -16,5 +16,3 @@ function foo(data : T): void { let aNumber = data! as int } - -/* @@? 17:19 Error TypeError: Cannot cast type 'NonNullable' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets index 5a6a68e66b..235ac7461a 100644 --- a/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets +++ b/ets2panda/test/ast/compiler/ets/cast_NonNullishType_to_PrimitiveType3.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data! as number } -/* @@? 17:19 Error TypeError: Cannot cast type 'NonNullable' to 'double' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets index a2c9561af5..41fa96e0b9 100644 --- a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets +++ b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType1.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data as boolean } -/* @@? 17:19 Error TypeError: Cannot cast type 'T' to 'boolean' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets index 6ee459478d..7b3d28faf8 100644 --- a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets +++ b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType2.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data as int } -/* @@? 17:19 Error TypeError: Cannot cast type 'T' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets index c07d310c30..89bcb6c610 100644 --- a/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets +++ b/ets2panda/test/ast/compiler/ets/cast_TypeParameter_to_PrimitiveType3.ets @@ -17,4 +17,3 @@ function foo(data : T): void { let aNumber = data as number } -/* @@? 17:19 Error TypeError: Cannot cast type 'T' to 'double' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets index 55d610c6b9..252c90bce1 100644 --- a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets +++ b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType1.ets @@ -16,5 +16,3 @@ function foo(data: T | boolean | null): void { let aNumber = data as int } - -/* @@? 17:19 Error TypeError: Cannot cast type 'T|Boolean|null' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets index 8a088bee5f..5400381949 100644 --- a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets +++ b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType2.ets @@ -19,4 +19,3 @@ function foo(data: T | A): void { let aNumber = data as int } -/* @@? 19:19 Error TypeError: Cannot cast type 'T|A' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets index 5c261ef099..9c91b473e7 100644 --- a/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets +++ b/ets2panda/test/ast/compiler/ets/cast_UnionType_to_PrimitiveType3.ets @@ -18,4 +18,3 @@ function foo(data: T, x: boolean): void { let aNumber = data2 as int } -/* @@? 18:19 Error TypeError: Cannot cast type 'Boolean|NonNullable' to 'int' */ diff --git a/ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.sts b/ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.sts new file mode 100644 index 0000000000..5e498766bb --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/cast_boxed_primitives_invoke_context_and_unions.sts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A {} + +function foo(a: Float): Float { + return a; +} + +function main(): int { + let c: A | Double = new Double(10.0 as double); + let b: Int = new Int(9 as int); + c = b + if (c != 9) { + return 1; + } + let k: Int = new Int(10 as int); + let v: Float = foo(k) + if (v.isNaN()) { + return 1; + } + return 0; +} diff --git a/ets2panda/test/ast/compiler/ets/circular_variable_init.ets b/ets2panda/test/ast/compiler/ets/circular_variable_init.ets index af59760eb5..fc6881da7f 100644 --- a/ets2panda/test/ast/compiler/ets/circular_variable_init.ets +++ b/ets2panda/test/ast/compiler/ets/circular_variable_init.ets @@ -47,7 +47,7 @@ function main() { /* @@? 23:19 Error TypeError: Circular dependency detected for identifier: b */ /* @@? 31:15 Error TypeError: Unresolved reference globalb */ /* @@? 33:5 Error TypeError: Circular dependency detected for identifier: globalc */ -/* @@? 37:7 Error TypeError: Circular dependency detected for identifier: constb */ +/* @@? 36:7 Error TypeError: Circular dependency detected for identifier: consta */ /* @@? 40:17 Error TypeError: Unresolved reference mainb */ /* @@? 42:17 Error TypeError: Variable 'maind' is accessed before it's initialization. */ /* @@? 43:9 Error TypeError: Circular dependency detected for identifier: maind */ diff --git a/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets b/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets index 8be10405f5..49d1373772 100644 --- a/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets +++ b/ets2panda/test/ast/compiler/ets/conversion_call-context_Int-to-Double_typeerror.ets @@ -17,9 +17,7 @@ function foo(x: Double) {} function main(): void { let a : Int = new Int(2); - /* @@ label */foo(/* @@ label1 */a); + foo(a); return; } -/* @@@ label1 Error TypeError: Type 'Int' is not compatible with type 'Double' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/division-by-zero.ets b/ets2panda/test/ast/compiler/ets/division-by-zero.ets new file mode 100644 index 0000000000..85b5646d73 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/division-by-zero.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function main() : void { + let div_int : int = /* @@ label1 */1 / 0; + let div_long: long = /* @@ label2 */1 / 0; + let mod_int : int = /* @@ label3 */1 % 0; + let mod_long: long = /* @@ label4 */1 % 0; +} + +/* @@@ label1 Error SyntaxError: Division by zero is not allowed. */ +/* @@@ label2 Error SyntaxError: Division by zero is not allowed. */ +/* @@@ label3 Error SyntaxError: Division by zero is not allowed. */ +/* @@@ label4 Error SyntaxError: Division by zero is not allowed. */ diff --git a/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets b/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets index ace31b83f7..1100d5c9d1 100644 --- a/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets +++ b/ets2panda/test/ast/compiler/ets/enum-to-int-conversion.ets @@ -20,4 +20,4 @@ let a: int = /* @@ label */E.FIRST - /* @@@ label Error TypeError: Type 'long' cannot be assigned to type 'int' */ \ No newline at end of file + /* @@@ label Error TypeError: Type 'Long' cannot be assigned to type 'Int' */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets b/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets index b7deb047d7..dda6ea9f3c 100644 --- a/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets +++ b/ets2panda/test/ast/compiler/ets/enum_not_constant_var.ets @@ -20,5 +20,4 @@ enum Color { Red = /* @@ label */b, } -/* @@@ label Error SyntaxError: Only constant expression is expected in the field */ /* @@@ label Error SyntaxError: Invalid enum initialization value */ diff --git a/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets b/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets index a04bb52e2b..724f1b214d 100644 --- a/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets +++ b/ets2panda/test/ast/compiler/ets/etsObjectToString0.ets @@ -20,4 +20,4 @@ function test(): int{ return /* @@ label */a; } -/* @@@ label Error TypeError: Type 'A|null' is not compatible with the enclosing method's return type 'int' */ +/* @@@ label Error TypeError: Type 'A|null' is not compatible with the enclosing method's return type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets b/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets index e5873018c8..d46422e571 100644 --- a/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets +++ b/ets2panda/test/ast/compiler/ets/etsObjectToString4.ets @@ -17,4 +17,4 @@ class A{} let f: (() => int) | null = /* @@ label */5; -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type '() => Int|null' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type '() => Int|null' */ diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets index df828b5b40..c97f4b9e8b 100644 --- a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets +++ b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithExtensionFunction.ets @@ -20,14 +20,13 @@ class B { function name(b: B) {} function name(b: B, n: string) {} -get name/* @@ label1 */(this: B): string { - return this.name_; +get name(this: B): string { + return this.name_; } -set name/* @@ label2 */(this: B, n: string) { +set name/* @@ label */(this: B, n: string) { this.name_ = n; } -/* @@@ label1 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ diff --git a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets index df828b5b40..c97f4b9e8b 100644 --- a/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets +++ b/ets2panda/test/ast/compiler/ets/extension_accessor_tests/extensionAccessorNameDuplicatedWithFunction.ets @@ -20,14 +20,13 @@ class B { function name(b: B) {} function name(b: B, n: string) {} -get name/* @@ label1 */(this: B): string { - return this.name_; +get name(this: B): string { + return this.name_; } -set name/* @@ label2 */(this: B, n: string) { +set name/* @@ label */(this: B, n: string) { this.name_ = n; } -/* @@@ label1 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ -/* @@@ label2 Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ +/* @@@ label Error TypeError: Function name with this assembly signature already declared. */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets index c3060b1928..6e0fe6102b 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_access_protected_field.ets @@ -28,5 +28,5 @@ function main() { console.println(banana.name()); } -/* @@@ label Error TypeError: Signature price(): int is not visible here. */ +/* @@@ label Error TypeError: Signature price(): Int is not visible here. */ /* @@@ label Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets index 4ce3aa69d4..a122118882 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets @@ -28,4 +28,4 @@ function main() { console.println(/* @@label */banana.name(2)); } -/* @@? 28:34 Error TypeError: No matching call signature for name(int) */ +/* @@@ label Error TypeError: No matching call signature for name(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets index e35530840d..2e8df50de7 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_miss_signature.ets @@ -39,6 +39,6 @@ function main() { asMethodCall(); } -/* @@? 30:5 Error TypeError: Expected 2 arguments, got 3. */ -/* @@? 30:5 Error TypeError: No matching call signature for foo(Fruit, double, double) */ -/* @@? 34:5 Error TypeError: No matching call signature for foo(double, double) */ +/* @@? 30:5 Error TypeError: Expected 2 arguments, got 3. */ +/* @@? 30:5 Error TypeError: No matching call signature for foo(Fruit, Double, Double) */ +/* @@? 34:5 Error TypeError: No matching call signature for foo(Double, Double) */ diff --git a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets index b41dbe9f88..1c4439bcc7 100644 --- a/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets +++ b/ets2panda/test/ast/compiler/ets/extension_function_tests/extension_function_return_this_neg.ets @@ -21,4 +21,4 @@ function foo(this: B): this { return /* @@ label */2; } -/* @@@ label Error TypeError: Type 'int' is not compatible with the enclosing method's return type 'B' */ +/* @@@ label Error TypeError: Type 'Int' is not compatible with the enclosing method's return type 'B' */ diff --git a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets index fe79788787..11b245f328 100644 --- a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_1.ets @@ -22,4 +22,4 @@ function main(): void { let b : Person ={name: /* @@ label */42, age:25} } -/* @@@ label Error TypeError: Type 'int' is not compatible with type 'String' at property 'name' */ +/* @@@ label Error TypeError: Type 'Int' is not compatible with type 'String' at property 'name' */ diff --git a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets index 0980e0579b..d12d67284b 100644 --- a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_2.ets @@ -22,4 +22,4 @@ function main(): void { let b : Person/* @@ label */ ={name: "John", age:25} } -/* @@@ label Error TypeError: Type String is not assignable to constraint type Double */ +/* @@@ label Error TypeError: Type argument 'String' should be a subtype of 'Double'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets index 87ee607302..fd7eed0b9e 100644 --- a/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets +++ b/ets2panda/test/ast/compiler/ets/genericObjectLiteral_neg_3.ets @@ -22,5 +22,5 @@ function main(): void { let b : Person/* @@ label */ ={name: "John", age:/* @@ label1 */"25"} } -/* @@@ label Error TypeError: Type Double is not assignable to constraint type String */ +/* @@@ label Error TypeError: Type argument 'Double' should be a subtype of 'String'-constraint */ /* @@@ label1 Error TypeError: Type '"25"' is not compatible with type 'Double' at property 'age' */ diff --git a/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets b/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets index 0bfcb0ae7d..1905464507 100644 --- a/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets +++ b/ets2panda/test/ast/compiler/ets/generic_typealias_5_neg.ets @@ -22,4 +22,4 @@ function main(): void { let a: A/* @@ label */; } -/* @@@ label Error TypeError: Type B is not assignable to constraint type Comparable */ +/* @@@ label Error TypeError: Type argument 'B' should be a subtype of 'Comparable'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets b/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets index a698d21b0f..c8f046fedf 100644 --- a/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/generics_primitive_type_param_neg_1.ets @@ -22,10 +22,9 @@ function main(): void { let prim_int = 5; switch(prim_int) { - /* @@ label */case /* @@ label1 */a_int.value: // not allowed, because type of a_int.value is Int + /* @@ label */case a_int.value: // not allowed, because type of a_int.value is Int default: } } -/* @@@ label1 Error TypeError: Switch case type 'Int' is not comparable to discriminant type 'int' */ /* @@@ label Error TypeError: Constant expression required */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference10.ets b/ets2panda/test/ast/compiler/ets/identifierReference10.ets index 161213981b..bb75765d53 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference10.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference10.ets @@ -25,4 +25,4 @@ class A { } } -/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference12.ets b/ets2panda/test/ast/compiler/ets/identifierReference12.ets index 6b2358f878..1c34cf4214 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference12.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference12.ets @@ -25,4 +25,4 @@ class A { } } -/* @@@ label Error TypeError: Type 'int' has no call signatures. */ +/* @@@ label Error TypeError: Type 'Int' has no call signatures. */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference16.ets b/ets2panda/test/ast/compiler/ets/identifierReference16.ets index e21f088772..aefc534f96 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference16.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference16.ets @@ -45,4 +45,4 @@ class A extends B { /* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 41:7 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? 41:7 Error TypeError: No matching call signature for foo(int) */ +/* @@? 41:7 Error TypeError: No matching call signature for foo(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference3.ets b/ets2panda/test/ast/compiler/ets/identifierReference3.ets index 69a7d28c11..ddc353921b 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference3.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference3.ets @@ -21,4 +21,4 @@ class A { } } -/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'int' */ +/* @@@ label Error TypeError: Type '"foo"' cannot be assigned to type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/identifierReference9.ets b/ets2panda/test/ast/compiler/ets/identifierReference9.ets index 6303c2f318..006fc0197d 100644 --- a/ets2panda/test/ast/compiler/ets/identifierReference9.ets +++ b/ets2panda/test/ast/compiler/ets/identifierReference9.ets @@ -25,4 +25,4 @@ class A { } } -/* @@? 24:16 Error TypeError: Type 'int' cannot be assigned to type '() => void' */ +/* @@? 24:16 Error TypeError: Type 'Int' cannot be assigned to type '() => void' */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets index 35ac4831a4..810b288169 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_1.ets @@ -17,4 +17,4 @@ package mypackage; let myvar: number = exist_but_checker_fails_in_file; -/* @@? package_module_2.ets:19:39 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? package_module_2.ets:19:39 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets index ba854d07c8..cf77170f19 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_6/package_module_2.ets @@ -18,4 +18,4 @@ package mypackage; let exist_but_checker_fails_in_file: number = 8; let wong_type: string = /* @@ label */9; -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets index 3fb40e5499..e5cd10f675 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module.ets @@ -17,7 +17,7 @@ package mypack; // That is the main file, from which we will compile full package -/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ +/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'Int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets index efd03230be..f4149768ba 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_semantic_error.ets @@ -17,7 +17,7 @@ package mypack; let a: int = "I am a number, I promise..."; -/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ +/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'Int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets index 16e73a0143..fd775ce3a1 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_module_with_syntax_error.ets @@ -17,7 +17,7 @@ package mypack; =) -/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ +/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'Int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets index e7896830c2..77699feb87 100644 --- a/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets +++ b/ets2panda/test/ast/compiler/ets/implicit_package_import/package_test_9/package_with_both_errors.ets @@ -21,7 +21,7 @@ function foo(): Day { return new good Day(); } -/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'int' */ +/* @@? package_module_with_semantic_error.ets:18:14 Error TypeError: Type '"I am a number, I promise..."' cannot be assigned to type 'Int' */ /* @@? package_module_with_syntax_error.ets:18:1 Error SyntaxError: Unexpected token '='. */ /* @@? package_module_with_syntax_error.ets:18:2 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets index c53d4298ef..6c96c0deea 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_1.ets @@ -24,9 +24,9 @@ export class A { let 1: number // First level import with both types of error -/* @@? import_1.ets:21:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_1.ets:21:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_1.ets:24:5 Error SyntaxError: Identifier expected, got 'number literal'. */ // Second level import import with both types of error -/* @@? import_2.ets:17:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_2.ets:17:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_2.ets:20:5 Error SyntaxError: Unexpected token 'not_ok'. */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets index 5cfa82f173..ee8446260e 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/import_2.ets @@ -20,7 +20,7 @@ export class B { var not_ok = false // Second level import import with both types of error -/* @@? import_2.ets:17:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_2.ets:17:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_2.ets:20:1 Error TypeError: Unresolved reference var */ /* @@? import_2.ets:20:5 Error SyntaxError: Unexpected token 'not_ok'. */ /* @@? import_2.ets:20:5 Error TypeError: Unresolved reference not_ok */ diff --git a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets index a516db7333..b3b38186ec 100644 --- a/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets +++ b/ets2panda/test/ast/compiler/ets/import_tests/import_chain_with_errors/master_file.ets @@ -18,15 +18,15 @@ import {A, B} from "./import_1.ets" let b = new B(10); // First level import with both types of error -/* @@? import_1.ets:21:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_1.ets:21:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_1.ets:24:5 Error SyntaxError: Identifier expected, got 'number literal'. */ // Second level import import with both types of error -/* @@? import_2.ets:17:17 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? import_2.ets:17:17 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? import_2.ets:20:5 Error SyntaxError: Unexpected token 'not_ok'. */ // Error in main file based on class from the most distant file /* @@? master_file.ets:18:9 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(int) */ +/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(Int) */ /* @@? master_file.ets:18:9 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(int) */ \ No newline at end of file +/* @@? master_file.ets:18:9 Error TypeError: No matching construct signature for import_2.B(Int) */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets b/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets index 821efecc9a..2d98d9ee73 100644 --- a/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets +++ b/ets2panda/test/ast/compiler/ets/infinityNarrowing.ets @@ -13,9 +13,12 @@ * limitations under the License. */ -export const floatInf: float = 1.0 / 0.0 +export const floatInf: float = /* @@ label2 */1.0 / 0.0 export const byteInf: byte = /* @@ label */1.0 / 0.0 export const shortInf: short = /* @@ label1 */1.0 / 0.0 -/* @@@ label Error TypeError: Type 'double' cannot be assigned to type 'byte' */ -/* @@@ label1 Error TypeError: Type 'double' cannot be assigned to type 'short' */ +/* @@@ label Error TypeError: Type 'Double' cannot be assigned to type 'Byte' */ +/* @@@ label1 Error TypeError: Type 'Double' cannot be assigned to type 'Short' */ +/* @@@ label2 Error TypeError: Floating-point value cannot be converted */ +/* @@@ label1 Error TypeError: Floating-point value cannot be converted */ +/* @@@ label Error TypeError: Floating-point value cannot be converted */ diff --git a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets index 8615346ac5..ee01f2ea07 100644 --- a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets +++ b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromClass.ets @@ -34,5 +34,5 @@ function main(): void { assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from class C, because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets index f9dca62195..7fdc5051d5 100644 --- a/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets +++ b/ets2panda/test/ast/compiler/ets/invalidIndirectInheritanceFromInterface.ets @@ -34,5 +34,5 @@ function main(): void { assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from class C, because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets index 0569baa08c..1e78d0e9b2 100644 --- a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets +++ b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromClass.ets @@ -30,5 +30,5 @@ function main(): void { let instance: B = new B(); assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from class A, because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets index f06ab002a2..781569a6a1 100644 --- a/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets +++ b/ets2panda/test/ast/compiler/ets/invalidInheritanceFromInterface.ets @@ -30,5 +30,5 @@ function main(): void { let instance: B = new B(); assertEQ(instance.getX(), true); } -/* @@@ label1 Error TypeError: Type 'boolean' has no call signatures. */ +/* @@@ label1 Error TypeError: Type 'Boolean' has no call signatures. */ /* @@@ label Error TypeError: Cannot inherit from interface A because field x is inherited with a different declaration type */ diff --git a/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets b/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets index b9c050c4e8..30a62660c7 100644 --- a/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets +++ b/ets2panda/test/ast/compiler/ets/lambdaExpressionWithoutBlockStatementDifferentTypeInfunction.ets @@ -22,4 +22,4 @@ function main(): void { test1() } -/* @@@ label Error TypeError: Type 'String' is not compatible with the enclosing method's return type 'int' */ +/* @@@ label Error TypeError: Type 'String' is not compatible with the enclosing method's return type 'Int' */ diff --git a/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets b/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets index bfd45ae78c..259a8abf16 100644 --- a/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets +++ b/ets2panda/test/ast/compiler/ets/lambdaFunction5.ets @@ -36,4 +36,4 @@ function main(): void { } /* @@@ label1 Error TypeError: Type '"foo"' is not compatible with type 'Int' at index 2 */ -/* @@@ label Error TypeError: No matching call signature for (int, "foo") */ +/* @@@ label Error TypeError: No matching call signature for (Int, "foo") */ diff --git a/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets b/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets index 0f6a071170..b1c80e1dbe 100644 --- a/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets +++ b/ets2panda/test/ast/compiler/ets/method-resolution-class-and-interface-in-signatures_6.ets @@ -42,4 +42,4 @@ function main(): int { let asd5: double = /* @@ label */foo(new A(), 2.1); return 0; } -/* @@@ label Error TypeError: Call to `foo` is ambiguous as `2` versions of `foo` are available: `foo(a: J, d: double): double` and `foo(a: I, d: double): double` */ +/* @@@ label Error TypeError: Call to `foo` is ambiguous as `2` versions of `foo` are available: `foo(a: J, d: Double): Double` and `foo(a: I, d: Double): Double` */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets index c81755739a..0b828cc131 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_access_violation_import_conflicts.ets @@ -24,6 +24,6 @@ Space1.foo(); // CTE Space1.foo(1234); //ok /* @@? 19:31 Error TypeError: Property 'constant' does not exist on type 'Space2' */ -/* @@? 20:23 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? 20:23 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ /* @@? 23:1 Error TypeError: Expected 1 arguments, got 0. */ /* @@? 23:1 Error TypeError: No matching call signature */ diff --git a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets index 713dbc66bc..89f6b4e676 100644 --- a/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets +++ b/ets2panda/test/ast/compiler/ets/namespace_tests/namespace_as_type10.ets @@ -19,6 +19,4 @@ namespace MySpace { let a = 1 instanceof MySpace /* @@? 19:22 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ -/* @@? 19:22 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ -/* @@? 19:9 Error TypeError: Bad operand type, the types of the operands must be same type. */ \ No newline at end of file +/* @@? 19:22 Error TypeError: Namespace 'MySpace' cannot be used as a type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets b/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets index 44c12cb3bf..f703cbe4a9 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteralPrimitiveContextType.ets @@ -14,4 +14,4 @@ */ let x: int = /* @@ label */{}; -/* @@@ label Error TypeError: Target type for class composite needs to be an object type, found 'int' */ + diff --git a/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets b/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets index 38d5711cf9..ce025f5c2a 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteralWrongValueType.ets @@ -21,4 +21,4 @@ let c: C = { f: /* @@ label */"ouch" }; -/* @@@ label Error TypeError: Type '"ouch"' is not compatible with type 'int' at property 'f' */ +/* @@@ label Error TypeError: Type '"ouch"' is not compatible with type 'Int' at property 'f' */ diff --git a/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets b/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets index 80d6e71482..ef3b7fd38f 100644 --- a/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets +++ b/ets2panda/test/ast/compiler/ets/objectLiteral_abstract_class.ets @@ -40,6 +40,6 @@ function main(){ /* @@@ label Error TypeError: type C has no property named field3 */ /* @@@ label2 Error TypeError: Property field2 is not visible here. */ -/* @@@ label3 Error TypeError: Type '"some str"' is not compatible with type 'double' at property 'field1' */ +/* @@@ label3 Error TypeError: Type '"some str"' is not compatible with type 'Double' at property 'field1' */ /* @@@ label4 Error TypeError: type C2 has no parameterless constructor */ /* @@@ label5 Error TypeError: Signature constructor(): void is not visible here. */ diff --git a/ets2panda/test/ast/compiler/ets/override11.ets b/ets2panda/test/ast/compiler/ets/override11.ets index 1bf873cd54..2c43199671 100644 --- a/ets2panda/test/ast/compiler/ets/override11.ets +++ b/ets2panda/test/ast/compiler/ets/override11.ets @@ -21,5 +21,5 @@ class B extends A { override fn(t: int): void { } } -/* @@? 21:14 Error TypeError: fn(t: int): void in B cannot override fn(t: int): int in A because overriding return type is not compatible with the other return type. */ -/* @@? 21:14 Error TypeError: Method fn(t: int): void in B not overriding any method */ +/* @@? 21:14 Error TypeError: fn(t: Int): void in B cannot override fn(t: Int): Int in A because overriding return type is not compatible with the other return type. */ +/* @@? 21:14 Error TypeError: Method fn(t: Int): void in B not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override14.ets b/ets2panda/test/ast/compiler/ets/override14.ets index 70cdd59cb7..59bca85ba3 100644 --- a/ets2panda/test/ast/compiler/ets/override14.ets +++ b/ets2panda/test/ast/compiler/ets/override14.ets @@ -21,5 +21,3 @@ class B extends A { override fn(t: Object): int { return 1} } -/* @@? 21:14 Error TypeError: fn(t: Object): int in B cannot override fn(t: T): T in A because overriding return type is not compatible with the other return type. */ -/* @@? 21:14 Error TypeError: Method fn(t: Object): int in B not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override15.ets b/ets2panda/test/ast/compiler/ets/override15.ets index 3a910c970c..22632b2eef 100644 --- a/ets2panda/test/ast/compiler/ets/override15.ets +++ b/ets2panda/test/ast/compiler/ets/override15.ets @@ -21,5 +21,5 @@ interface I2 extends I { fn(): float; } -/* @@? 21:5 Error TypeError: fn(): float in I2 cannot override fn(): int in I because overriding return type is not compatible with the other return type. */ -/* @@? 21:5 Error TypeError: Method fn(): float in I2 not overriding any method */ +/* @@? 21:5 Error TypeError: fn(): Float in I2 cannot override fn(): Int in I because overriding return type is not compatible with the other return type. */ +/* @@? 21:5 Error TypeError: Method fn(): Float in I2 not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override3.ets b/ets2panda/test/ast/compiler/ets/override3.ets index 0ed1c28b81..4031d36c0c 100644 --- a/ets2panda/test/ast/compiler/ets/override3.ets +++ b/ets2panda/test/ast/compiler/ets/override3.ets @@ -17,5 +17,5 @@ interface I { toString(): int; } -/* @@? 17:11 Error TypeError: toString(): int in I cannot override toString(): String in Object because overriding return type is not compatible with the other return type. */ -/* @@? 17:11 Error TypeError: Method toString(): int in I not overriding any method */ +/* @@? 17:11 Error TypeError: toString(): Int in I cannot override toString(): String in Object because overriding return type is not compatible with the other return type. */ +/* @@? 17:11 Error TypeError: Method toString(): Int in I not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/override7.ets b/ets2panda/test/ast/compiler/ets/override7.ets index 18900c1e84..aca0ae3a32 100644 --- a/ets2panda/test/ast/compiler/ets/override7.ets +++ b/ets2panda/test/ast/compiler/ets/override7.ets @@ -23,5 +23,5 @@ abstract class A implements I { public override fn(): int { return 1; } } -/* @@? 23:21 Error TypeError: fn(): int in A cannot override fn(): void in J because overriding return type is not compatible with the other return type. */ -/* @@? 23:21 Error TypeError: Method fn(): int in A not overriding any method */ +/* @@? 23:21 Error TypeError: fn(): Int in A cannot override fn(): void in J because overriding return type is not compatible with the other return type. */ +/* @@? 23:21 Error TypeError: Method fn(): Int in A not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets b/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets index 268606ee2e..abc1ea4562 100644 --- a/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets +++ b/ets2panda/test/ast/compiler/ets/overrideModifierNotOverriding.ets @@ -25,4 +25,4 @@ class B { } } -/* @@@ label Error TypeError: Method foo(a: int): int in B not overriding any method */ +/* @@@ label Error TypeError: Method foo(a: Int): Int in B not overriding any method */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets b/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets index a7d08982f9..f2f1b08aa9 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_class_neg.ets @@ -17,6 +17,6 @@ class A>>{} class C extends A/* @@ label1 */>{} /* A does not satisfy the constraint due to invariance of T */ -/* @@@ label Error TypeError: Type A is not assignable to constraint type A>> */ -/* @@@ label2 Error TypeError: Type C is not assignable to constraint type A> */ -/* @@@ label1 Error TypeError: Type A is not assignable to constraint type A>> */ +/* @@@ label Error TypeError: Type argument 'A' should be a subtype of 'A>>'-constraint */ +/* @@@ label2 Error TypeError: Type argument 'C' should be a subtype of 'A>'-constraint */ +/* @@@ label1 Error TypeError: Type argument 'A' should be a subtype of 'A>>'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets index 7bfe478c30..9ee831177a 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_1.ets @@ -16,4 +16,4 @@ interface A>{} interface D{} interface B extends A/* @@ label */{} -/* @@@ label Error TypeError: Type D is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'D' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets index fb2f281725..3596a49b97 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_interface_neg_2.ets @@ -16,4 +16,4 @@ interface A,T2 extends A>{} interface D{} interface B extends A/* @@ label */{} -/* @@@ label Error TypeError: Type D is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'D' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets b/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets index 7a588b42f8..0238b2626c 100644 --- a/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/recursive_union_neg_1.ets @@ -19,4 +19,4 @@ class T

{} class C extends A/* @@ label */{} /* Constraint: B|D|C <: A, but B is not a subtype of A due to T invariance */ -/* @@@ label Error TypeError: Type B|D|C is not assignable to constraint type A */ +/* @@@ label Error TypeError: Type argument 'B|D|C' should be a subtype of 'A'-constraint */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets index df5bce8676..78955a8122 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_1.ets @@ -15,8 +15,7 @@ //declare function has body export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number {} -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ /* @@? 19:49 Error TypeError: Native, Abstract and Declare methods cannot have body. */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets index 227dab0f78..27671485ba 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_neg_2.ets @@ -15,7 +15,7 @@ //Not support non-declare function has same assembly code export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export function foo(a:A):number {} -/* @@? 19:8 Error TypeError: Function foo with this assembly signature already declared. */ \ No newline at end of file +/* @@? 19:17 Error TypeError: Function with a non void return type must return a value. */ diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets index 5440079d8e..31d4512f58 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_1.ets @@ -15,10 +15,7 @@ //Without rest parameter export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number export declare function foo(a:int, b:int):void export declare function foo(a:double):void - -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ - diff --git a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets index 9900d58e0c..a35dbbffd6 100644 --- a/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets +++ b/ets2panda/test/ast/compiler/ets/same_assembly_overload/overload_signature_pos_2.ets @@ -15,11 +15,8 @@ //With rest parameter export class A {} -export declare function foo(a:A):void +export declare function foo(a:A):void export declare function foo(a:A):number export declare function foo(a:int, b:int):void export declare function foo(a:double):void export declare function foo(...args:string[]):void - -/* @@? 18:8 Warning Warning: Function foo with this assembly signature already declared. */ - diff --git a/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets b/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets index 116c419830..9f1621021f 100644 --- a/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets +++ b/ets2panda/test/ast/compiler/ets/switchcaseDuplicate.ets @@ -22,13 +22,13 @@ class IndexStr { indexField: string = "title" foo() { switch (this.indexField) { - /* @@ label */case IndexField.TITLE: + case IndexField.TITLE: assertEQ(this.indexField, IndexField.TITLE) break; - case IndexField.TITLE: + /* @@ label */case IndexField.TITLE: assertEQ(this.indexField, IndexField.TITLE) } } } -/* @@@ label Error TypeError: Variable has same value with another switch case */ \ No newline at end of file +/* @@@ label Error TypeError: Case duplicate */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets index d874643b8f..b03095bb29 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_10_neg.ets @@ -19,4 +19,4 @@ function main(): void { let b: [number, number, number] = /* @@ label */a; } -/* @@@ label Error TypeError: Type '[double, double]' cannot be assigned to type '[double, double, double]' */ +/* @@@ label Error TypeError: Type '[Double, Double]' cannot be assigned to type '[Double, Double, Double]' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets index 5c6ff60fea..b6a37f7126 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_11_neg.ets @@ -19,4 +19,4 @@ function main(): void { let b: [number, number] = /* @@ label */a; } -/* @@@ label Error TypeError: Type '[double, double, double]' cannot be assigned to type '[double, double]' */ +/* @@@ label Error TypeError: Type '[Double, Double, Double]' cannot be assigned to type '[Double, Double]' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets index 55c0a6e370..ea8e9d99a5 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_1_neg.ets @@ -18,4 +18,4 @@ function main(): void { const array: (number|boolean) [] = tuple } -/* @@? 18:40 Error TypeError: Type '[double, double, boolean]' cannot be assigned to type 'Array' */ +/* @@? 18:40 Error TypeError: Type '[Double, Double, Boolean]' cannot be assigned to type 'Array' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets index 7f792a64d5..0d723e75d4 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_6_neg.ets @@ -16,7 +16,6 @@ function main(): void { let a: [number] = [1]; - let b: [Number] = /* @@ label */a; + let b: [Number] = a; } -/* @@@ label Error TypeError: Type '[double]' cannot be assigned to type '[Double]' */ diff --git a/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets b/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets index 44d8b2071e..3bf4b2c6e5 100644 --- a/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets +++ b/ets2panda/test/ast/compiler/ets/tuple_types_9_neg.ets @@ -28,4 +28,4 @@ function main(): void { /* @@? 18:37 Error SyntaxError: Unexpected token ']'. */ /* @@? 18:37 Error SyntaxError: Unexpected token ']'. */ /* @@? 18:39 Error SyntaxError: Unexpected token '='. */ -/* @@? 19:50 Error TypeError: Type '[double, String, *ERROR_TYPE*]' cannot be assigned to type '[double, String, Int]' */ +/* @@@ label Error TypeError: Type '[Double, String, *ERROR_TYPE*]' cannot be assigned to type '[Double, String, Int]' */ diff --git a/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets b/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets index 7e42c8c105..f3cc9e64c3 100644 --- a/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets +++ b/ets2panda/test/ast/compiler/ets/type_error_processing/type_handlers.ets @@ -40,14 +40,11 @@ type T15 = Required /* @@? 22:18 Error TypeError: Invalid number of type parameters for Partial type, should be 1. */ /* @@? 24:18 Error TypeError: Invalid number of type parameters for Partial type, should be 1. */ /* @@? 25:18 Error TypeError: Invalid number of type parameters for Partial type, should be 1. */ -/* @@? 26:18 Error TypeError: Only reference types can be converted to utility types. */ /* @@? 28:19 Error TypeError: Invalid number of type parameters for Readonly type, should be 1. */ /* @@? 30:19 Error TypeError: Invalid number of type parameters for Readonly type, should be 1. */ /* @@? 31:19 Error TypeError: Invalid number of type parameters for Readonly type, should be 1. */ -/* @@? 32:20 Error TypeError: Only reference types can be converted to utility types. */ /* @@? 34:20 Error TypeError: Invalid number of type parameters for Required type, should be 1. */ /* @@? 36:20 Error TypeError: Invalid number of type parameters for Required type, should be 1. */ /* @@? 37:20 Error TypeError: Invalid number of type parameters for Required type, should be 1. */ -/* @@? 38:20 Error TypeError: Only reference types can be converted to utility types. */ diff --git a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets index 61acb173f6..1563fd56e4 100644 --- a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets +++ b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error.ets @@ -17,4 +17,4 @@ function main() : void { let a: Byte = /* @@ label */new Byte(2); } -/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(int) */ +/* @@@ label Error TypeError: No matching construct signature for std.core.Byte(Int) */ diff --git a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets index 2727c5fe2c..38e048b382 100644 --- a/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets +++ b/ets2panda/test/ast/compiler/ets/validate_signatures_throw_type_error_more_param.ets @@ -17,4 +17,4 @@ function main() : void { let e: Float = /* @@ label */new Float(6,"3"); } -/* @@@ label Error TypeError: No matching construct signature for std.core.Float(int, "3") */ +/* @@@ label Error TypeError: No matching construct signature for std.core.Float(Int, "3") */ diff --git a/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets b/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets index 14947fde7e..37e9904ba6 100644 --- a/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets +++ b/ets2panda/test/ast/compiler/ets/voidTypeInBinaryOperation.ets @@ -22,4 +22,4 @@ function main(): void { /* @@? 20:3 Error TypeError: No matching call signature for assertTrue(void) */ /* @@? 20:23 Error TypeError: Cannot use type 'void' as value. */ -/* @@? 20:23 Error TypeError: Type 'void' is not compatible with type 'boolean' at index 1 */ \ No newline at end of file +/* @@? 20:23 Error TypeError: Type 'void' is not compatible with type 'Boolean' at index 1 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets b/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets index 76ed96a9db..bbd4601ec7 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/StringFasta.ets @@ -122,15 +122,10 @@ function main(): void { a.run(); } -/* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 18:18 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 19:22 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 21:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 22:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 23:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ @@ -150,6 +145,7 @@ function main(): void { /* @@? 37:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 38:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 39:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ +/* @@? 41:26 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 47:13 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:21 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:28 Error TypeError: Static property 'A' must be accessed through it's class 'Random' */ @@ -157,30 +153,30 @@ function main(): void { /* @@? 47:37 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ /* @@? 48:26 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 48:33 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ +/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 53:27 Error TypeError: Type 'null' cannot be assigned to type 'Char' */ +/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 54:57 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 71:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 71:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 72:24 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 77:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 78:24 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 71:33 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 72:24 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 77:33 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 78:24 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 86:9 Error TypeError: Static property 'makeCumulative' must be accessed through it's class 'StringFasta' */ /* @@? 94:34 Error TypeError: Static property 'Random' must be accessed through it's class 'StringFasta' */ +/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 95:65 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 103:20 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 103:20 Error TypeError: Type 'Double' has no call signatures. */ /* @@? 112:16 Error TypeError: Static property 'fastaRepeat' must be accessed through it's class 'StringFasta' */ -/* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 112:48 Error TypeError: Static property 'ALU' must be accessed through it's class 'StringFasta' */ /* @@? 113:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ -/* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 113:46 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 114:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ -/* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 114:46 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 116:28 Error TypeError: 'expected' is a static property of 'StringFasta' */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets b/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets index da4c91a29a..6b8efd8afe 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets @@ -25,5 +25,5 @@ function foo(): number { } return n! } -/* @@? 23:17 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ + /* @@? 26:12 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets index fd74b049d9..25779dcb62 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/for_of_02.ets @@ -32,4 +32,4 @@ function main(): void { } } -/* @@? 30:17 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'float'. */ +/* @@@ label Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Float'. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets b/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets index 8e4083148a..a49879c670 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/illegal_union_member_exp.ets @@ -21,3 +21,5 @@ function main(): void { let b = s ?? a; b.toString(); } + +/* @@? 22:19 Error TypeError: Type String|Int[] is illegal in union member expression. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets b/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets index 6d3751d902..7f0a390e84 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/nonIntegralIndex.ets @@ -19,4 +19,4 @@ export class Test { } } -/* @@@ label Error TypeError: Type 'double' cannot be used as an index type. Only primitive or unboxable integral types can be used as index. */ +/* @@@ label Error TypeError: Type 'Double' cannot be used as an index type. Only primitive or unboxable integral types can be used as index. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets b/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets index b4ef18b4e9..010a140b3b 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/predefined_non_primitive_types.ets @@ -37,4 +37,4 @@ let a: FixedArray = new int[5]; /* @@@ label Error TypeError: Variable 'non_prim_b' has already been declared. */ /* @@? 27:31 Error TypeError: Cannot find type 'Bool'. */ -/* @@? 27:38 Error TypeError: Type 'boolean' cannot be assigned to type 'Byte' */ +/* @@? 27:38 Error TypeError: Type 'Boolean' cannot be assigned to type 'Byte' */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets b/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets index 90442a1300..a7f6f9a173 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/record_object_value.ets @@ -57,7 +57,7 @@ function main(){ "Mary":["20", "30"] }; } -/* @@@ label Error TypeError: Type '"10"' is not compatible with type 'double' at property 'age' */ -/* @@@ label1 Error TypeError: Type '"100"' is not compatible with type 'double' at property 'salary' */ +/* @@@ label Error TypeError: Type '"10"' is not compatible with type 'Double' at property 'age' */ +/* @@@ label1 Error TypeError: Type '"100"' is not compatible with type 'Double' at property 'salary' */ /* @@@ label2 Error TypeError: type PersonInfoInterface has no property named agee */ /* @@@ label3 Error TypeError: type PersonInfoInterface has no property named other */ diff --git a/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets b/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets index 0790ded53c..c50834ca9b 100644 --- a/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets +++ b/ets2panda/test/ast/parser/ets/MultipleClassErrors.ets @@ -32,7 +32,7 @@ class /* @@ label4 */{/* @@ label5 */} /* @@? 17:19 Error SyntaxError: Unexpected token 'function'. */ /* @@? 21:20 Error SyntaxError: Unexpected token 'let'. */ /* @@? 22:20 Error SyntaxError: Unexpected token 'let'. */ -/* @@? 24:17 Error TypeError: Type '"abc"' cannot be assigned to type 'double' */ +/* @@? 24:17 Error TypeError: Type '"abc"' cannot be assigned to type 'Double' */ /* @@? 28:22 Error SyntaxError: Identifier expected, got 'number literal'. */ /* @@? 30:22 Error SyntaxError: Identifier expected, got '{'. */ /* @@? 30:38 Error SyntaxError: Expected '{', got '}'. */ diff --git a/ets2panda/test/ast/parser/ets/StringFasta.ets b/ets2panda/test/ast/parser/ets/StringFasta.ets index a536da1d47..b19171c455 100644 --- a/ets2panda/test/ast/parser/ets/StringFasta.ets +++ b/ets2panda/test/ast/parser/ets/StringFasta.ets @@ -122,15 +122,10 @@ function main(): void { a.run(); } -/* @@@ label Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 18:18 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 18:46 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 19:22 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ -/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ +/* @@? 19:50 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 21:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 22:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 23:9 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ @@ -150,6 +145,7 @@ function main(): void { /* @@? 37:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 38:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 39:9 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ +/* @@? 41:26 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ /* @@? 47:13 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:21 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 47:28 Error TypeError: Static property 'A' must be accessed through it's class 'Random' */ @@ -157,30 +153,30 @@ function main(): void { /* @@? 47:37 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ /* @@? 48:26 Error TypeError: Static property 'last' must be accessed through it's class 'Random' */ /* @@? 48:33 Error TypeError: Static property 'M' must be accessed through it's class 'Random' */ +/* @@? 52:35 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 53:27 Error TypeError: Type 'null' cannot be assigned to type 'Char' */ +/* @@? 54:26 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 54:57 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 71:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 71:17 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ -/* @@? 72:24 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 77:33 Error TypeError: Type 'double' has no call signatures. */ -/* @@? 78:24 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 71:33 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 72:24 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 77:33 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 78:24 Error TypeError: Type 'Double' has no call signatures. */ +/* @@? 84:41 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 86:9 Error TypeError: Static property 'makeCumulative' must be accessed through it's class 'StringFasta' */ /* @@? 94:34 Error TypeError: Static property 'Random' must be accessed through it's class 'StringFasta' */ +/* @@? 95:34 Error TypeError: Cannot find type 'HashMap'. */ /* @@? 95:65 Error TypeError: 'For-of' statement source expression is not of iterable type. */ -/* @@? 103:20 Error TypeError: Type 'double' has no call signatures. */ +/* @@? 103:20 Error TypeError: Type 'Double' has no call signatures. */ /* @@? 112:16 Error TypeError: Static property 'fastaRepeat' must be accessed through it's class 'StringFasta' */ -/* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 112:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 112:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 112:48 Error TypeError: Static property 'ALU' must be accessed through it's class 'StringFasta' */ /* @@? 113:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ -/* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 113:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 113:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 113:46 Error TypeError: Static property 'IUB' must be accessed through it's class 'StringFasta' */ /* @@? 114:16 Error TypeError: Static property 'fastaRandom' must be accessed through it's class 'StringFasta' */ -/* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ -/* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ /* @@? 114:28 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 114:32 Error TypeError: Function name 'count' used in the wrong context */ /* @@? 114:46 Error TypeError: Static property 'HomoSap' must be accessed through it's class 'StringFasta' */ /* @@? 116:28 Error TypeError: 'expected' is a static property of 'StringFasta' */ diff --git a/ets2panda/test/ast/parser/ets/UnexpectedToken.ets b/ets2panda/test/ast/parser/ets/UnexpectedToken.ets index 6f85639581..a7ee95c6e4 100644 --- a/ets2panda/test/ast/parser/ets/UnexpectedToken.ets +++ b/ets2panda/test/ast/parser/ets/UnexpectedToken.ets @@ -20,7 +20,6 @@ function main(): void { } } -/* @@? 18:19 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 18:25 Error SyntaxError: Unexpected token 'let'. */ /* @@? 18:25 Error SyntaxError: Unexpected token, expected ')'. */ /* @@? 18:29 Error SyntaxError: Expected ';', got 'identification literal'. */ diff --git a/ets2panda/test/ast/parser/ets/accessor_call.ets b/ets2panda/test/ast/parser/ets/accessor_call.ets index 030d431499..918aaffe39 100644 --- a/ets2panda/test/ast/parser/ets/accessor_call.ets +++ b/ets2panda/test/ast/parser/ets/accessor_call.ets @@ -21,4 +21,4 @@ function main(): void { /* @@ label */new A().x(); } -/* @@@ label Error TypeError: Type 'int' has no call signatures. */ +/* @@@ label Error TypeError: Type 'Int' has no call signatures. */ diff --git a/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets b/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets index 27a91515bc..4d3d2c8539 100644 --- a/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets +++ b/ets2panda/test/ast/parser/ets/ambiguous_call_2.ets @@ -27,5 +27,5 @@ function main (): void { goo (0, new X(), "ambiguous") } -/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: int, p1: I1, s: String): void` and `goo(i: int, p2: I5, s: String): void` */ -/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: int, p1: I1, s: String): void` and `goo(i: int, p2: I2, s: String): void` */ +/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: Int, p1: I1, s: String): void` and `goo(i: Int, p2: I5, s: String): void` */ +/* @@? 27:5 Error TypeError: Call to `goo` is ambiguous as `2` versions of `goo` are available: `goo(i: Int, p1: I1, s: String): void` and `goo(i: Int, p2: I2, s: String): void` */ diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets index cd104710cf..477f372752 100644 --- a/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotationUsage_bad_param04.ets @@ -21,4 +21,4 @@ @MyAnno({testProperty1: "1", testProperty2: [1, 2, a]}) class B{} -/* @@? 21:45 Error TypeError: Expected type for array literal should be an array type, got double */ +/* @@? 21:45 Error TypeError: Expected type for array literal should be an array type, got Double */ diff --git a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets index 4f43f45947..2ee2aaef91 100644 --- a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets +++ b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_1.ets @@ -18,4 +18,4 @@ function main(): void { } /* @@@ label1 Error TypeError: No matching call signature for assertTrue("true") */ -/* @@@ label2 Error TypeError: Type '"true"' is not compatible with type 'boolean' at index 1 */ \ No newline at end of file +/* @@@ label2 Error TypeError: Type '"true"' is not compatible with type 'Boolean' at index 1 */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets index e63562d1a0..425510b440 100644 --- a/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets +++ b/ets2panda/test/ast/parser/ets/assert_with_not_boolean_type_2.ets @@ -17,5 +17,5 @@ function main(): void { /* @@ label1 */assertTrue(/* @@ label2 */1) } -/* @@@ label1 Error TypeError: No matching call signature for assertTrue(int) */ -/* @@@ label2 Error TypeError: Type 'int' is not compatible with type 'boolean' at index 1 */ +/* @@@ label1 Error TypeError: No matching call signature for assertTrue(Int) */ +/* @@@ label2 Error TypeError: Type 'Int' is not compatible with type 'Boolean' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets b/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets index d19b824b7b..2d9c1d6732 100644 --- a/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets +++ b/ets2panda/test/ast/parser/ets/assignment_non-functional_variable_to_functional_type_1.ets @@ -20,4 +20,4 @@ function main() a = /* @@ label */b } -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type '() => Int' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type '() => Int' */ diff --git a/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets b/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets index 1ff5c330df..fca951695d 100644 --- a/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets +++ b/ets2panda/test/ast/parser/ets/call_expression_for_non_functional_type.ets @@ -27,4 +27,5 @@ function main() /* @@ label */b(1, 2) } -/* @@@ label Error TypeError: This expression is not callable. */ +/* @@@ label Error TypeError: No static $_invoke method and static $_instantiate method in b. b() is not allowed. */ +/* @@@ label Error TypeError: Type 'Int' has no call signatures. */ diff --git a/ets2panda/test/ast/parser/ets/class_optional_property.ets b/ets2panda/test/ast/parser/ets/class_optional_property.ets index ce1be206b3..a0c0ea2857 100644 --- a/ets2panda/test/ast/parser/ets/class_optional_property.ets +++ b/ets2panda/test/ast/parser/ets/class_optional_property.ets @@ -17,4 +17,4 @@ class A { applyNormalAttribute ?: () => void = /* @@ label */1 } -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type '() => void|undefined' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type '() => void|undefined' */ diff --git a/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets b/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets index f77025113d..627345cdb3 100644 --- a/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets +++ b/ets2panda/test/ast/parser/ets/constant_expression_divide_zero.ets @@ -25,5 +25,5 @@ enum Color { } -/* @@? 20:14 Error SyntaxError: Division by zero are not allowed in Enum or Annotation. */ -/* @@? 24:11 Error SyntaxError: Division by zero are not allowed in Enum or Annotation. */ +/* @@? 20:14 Error SyntaxError: Division by zero are not allowed. */ +/* @@? 24:11 Error SyntaxError: Division by zero are not allowed. */ diff --git a/ets2panda/test/ast/parser/ets/cycle_constructor.ets b/ets2panda/test/ast/parser/ets/cycle_constructor.ets index cfcd15c371..4574098af6 100644 --- a/ets2panda/test/ast/parser/ets/cycle_constructor.ets +++ b/ets2panda/test/ast/parser/ets/cycle_constructor.ets @@ -27,6 +27,6 @@ class B extends A { } /* @@? 25:9 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? 25:9 Error TypeError: No matching call signature for cycle_constructor.B(int) */ +/* @@? 25:9 Error TypeError: No matching call signature for cycle_constructor.B(Int) */ /* @@? 25:9 Error TypeError: No matching call signature for constructor */ /* @@? 25:14 Error TypeError: Using super is not allowed in constructor */ diff --git a/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets b/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets index 0c45ca27f6..29c95eb7e7 100644 --- a/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets +++ b/ets2panda/test/ast/parser/ets/declare_class_bad_1.ets @@ -20,4 +20,4 @@ declare class A { /* @@@ label Error SyntaxError: Initializers are not allowed in ambient contexts. */ /* @@? 17:18 Error TypeError: Initializers are not allowed in ambient contexts: f1 */ -/* @@? 17:18 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? 17:18 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets b/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets index 175aac24e6..d826e1d205 100644 --- a/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets +++ b/ets2panda/test/ast/parser/ets/declare_class_bad_3.ets @@ -20,4 +20,4 @@ declare class A { /* @@@ label Error SyntaxError: Initializers are not allowed in ambient contexts. */ /* @@? 17:25 Error TypeError: Initializers are not allowed in ambient contexts: f1 */ -/* @@? 17:25 Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@? 17:25 Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/declare_namespace_5.ets b/ets2panda/test/ast/parser/ets/declare_namespace_5.ets index 61605b9c0d..d517891950 100644 --- a/ets2panda/test/ast/parser/ets/declare_namespace_5.ets +++ b/ets2panda/test/ast/parser/ets/declare_namespace_5.ets @@ -49,6 +49,7 @@ class B { } /* @@? 17:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ +/* @@? 18:9 Error TypeError: Unresolved reference dfdfsfdf */ /* @@? 20:5 Error SyntaxError: Namespace is allowed only at the top level or inside a namespace. */ /* @@? 23:20 Error TypeError: Unresolved reference foo */ /* @@? 27:11 Error TypeError: Property 'getInstance' does not exist on type 'B' */ diff --git a/ets2panda/test/ast/parser/ets/differentTypeCompare.ets b/ets2panda/test/ast/parser/ets/differentTypeCompare.ets index e41197292f..bc6decc66b 100644 --- a/ets2panda/test/ast/parser/ets/differentTypeCompare.ets +++ b/ets2panda/test/ast/parser/ets/differentTypeCompare.ets @@ -23,4 +23,4 @@ function main(): void { foo(/* @@ label */a == b); } -/* @@@ label Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ +/* @@@ label Error TypeError: Operator '==' cannot be applied to types 'String' and 'Int'. */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets index e01a4ddc3b..349d936094 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets @@ -22,5 +22,5 @@ import { A } from "dynamic_import_tests/modules/module" function main(): void { let x = /* @@ label */new A(/* @@ label1 */"abc", 10) } -/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'double' at index 1 */ -/* @@@ label Error TypeError: No matching construct signature for module.A("abc", int) */ +/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'Double' at index 1 */ +/* @@@ label Error TypeError: No matching construct signature for module.A("abc", Int) */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets index 6d872c4eab..c2356b47e2 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_1.ets @@ -22,4 +22,4 @@ import { A } from "dynamic_import_tests/modules/module" function foo(p: A): void { p.f1 = /* @@ label */10 } -/* @@@ label Error TypeError: Type 'int' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Int' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets index 39bac5dcae..20edcbd465 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_field_decl_import_bad_2.ets @@ -22,4 +22,4 @@ import { A } from "dynamic_import_tests/modules/module" function foo(): void { let x: string = /* @@ label */A.f2 } -/* @@@ label Error TypeError: Type 'double' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Double' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets index 23eb4a01ec..db83b85465 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_1.ets @@ -22,5 +22,5 @@ import { A } from "dynamic_import_tests/modules/module" function foo(p: A): void { /* @@ label */p.foo(/* @@ label1 */"abc") } -/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'double' at index 1 */ +/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'Double' at index 1 */ /* @@@ label Error TypeError: No matching call signature for foo("abc") */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets index 3acfee0bea..bb4b9e0c59 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_method_decl_import_bad_2.ets @@ -22,4 +22,4 @@ import { A } from "dynamic_import_tests/modules/module" function foo(): void { let x: string = /* @@ label */A.bar() } -/* @@@ label Error TypeError: Type 'double' cannot be assigned to type 'String' */ +/* @@@ label Error TypeError: Type 'Double' cannot be assigned to type 'String' */ diff --git a/ets2panda/test/ast/parser/ets/enum15.ets b/ets2panda/test/ast/parser/ets/enum15.ets index 94ef7cd8c0..a673de147f 100644 --- a/ets2panda/test/ast/parser/ets/enum15.ets +++ b/ets2panda/test/ast/parser/ets/enum15.ets @@ -21,5 +21,4 @@ enum InvalidInitTypeEnum { /* @@? 18:11 Error SyntaxError: Invalid enum initialization value */ -/* @@? 19:7 Error SyntaxError: Only constant expression is expected in the field */ -/* @@? 19:7 Error SyntaxError: Invalid enum initialization value */ +/* @@? 19:7 Error SyntaxError: Invalid enum initialization value */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/enum_default_negative1.ets b/ets2panda/test/ast/parser/ets/enum_default_negative1.ets index 4b7f2a8fec..a96b68ddd4 100644 --- a/ets2panda/test/ast/parser/ets/enum_default_negative1.ets +++ b/ets2panda/test/ast/parser/ets/enum_default_negative1.ets @@ -23,7 +23,6 @@ enum B { } -/* @@? 17:9 Error SyntaxError: Unsupported operator for String. */ /* @@? 17:9 Error SyntaxError: Invalid enum initialization value */ -/* @@? 22:9 Error SyntaxError: Only constant expression is expected in the field */ +/* @@? 17:9 Error TypeError: Wrong type of operands for binary expression */ /* @@? 22:9 Error SyntaxError: Invalid enum initialization value */ diff --git a/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets b/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets index 6593711c1c..9981dd14b1 100644 --- a/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets +++ b/ets2panda/test/ast/parser/ets/ets_never_type_without_affect_other.ets @@ -25,5 +25,5 @@ function foo(): number { } return n! } -/* @@? 23:17 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ + /* @@? 26:12 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/for_await_of_loop.ets b/ets2panda/test/ast/parser/ets/for_await_of_loop.ets index aad9c94018..3b41c8b661 100644 --- a/ets2panda/test/ast/parser/ets/for_await_of_loop.ets +++ b/ets2panda/test/ast/parser/ets/for_await_of_loop.ets @@ -19,7 +19,6 @@ for await (let k: int /* @@ label1 */= 0; /* @@ label2 */k < d.length; k++) { /* @@@ label1 Error SyntaxError: for-await-of loop variable declaration may not have an initializer. */ /* @@@ label2 Error SyntaxError: Unexpected token 'k'. */ -/* @@? 16:58 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ /* @@? 16:62 Error TypeError: Unresolved reference d */ /* @@? 17:5 Error TypeError: Cannot reference 'this' in this context. */ /* @@? 17:10 Error TypeError: Property '$_set_unsafe' does not exist on type 'Error' */ diff --git a/ets2panda/test/ast/parser/ets/for_of_02.ets b/ets2panda/test/ast/parser/ets/for_of_02.ets index 535270a596..b30a1e168d 100644 --- a/ets2panda/test/ast/parser/ets/for_of_02.ets +++ b/ets2panda/test/ast/parser/ets/for_of_02.ets @@ -32,4 +32,4 @@ function main(): void { } } -/* @@? 30:17 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'float'. */ +/* @@@ label Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Float'. */ diff --git a/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets b/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets index 167d3297a1..58952390f7 100644 --- a/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets +++ b/ets2panda/test/ast/parser/ets/for_of_loop_variable.ets @@ -30,7 +30,7 @@ for (let value = 40 /* @@ label2 */of iterable2) { console.log(value); } -/* @@? 18:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'int'. */ -/* @@? 18:38 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ -/* @@? 28:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'int'. */ -/* @@? 28:36 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ +/* @@@ label1 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ +/* @@@ label2 Error SyntaxError: for-of loop variable declaration may not have an initializer. */ +/* @@? 18:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Int'. */ +/* @@? 28:1 Error TypeError: Source element type 'Double' is not assignable to the loop iterator type 'Int'. */ diff --git a/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets b/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets index 2d256845c7..89efc28509 100644 --- a/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets +++ b/ets2panda/test/ast/parser/ets/function_implicit_return_type4.ets @@ -22,5 +22,5 @@ final class B extends A { public override fn(): int { return 42; } } -/* @@? 22:21 Error TypeError: fn(): int in B cannot override fn(): void in A because overriding return type is not compatible with the other return type. */ -/* @@? 22:21 Error TypeError: Method fn(): int in B not overriding any method */ +/* @@? 22:21 Error TypeError: fn(): Int in B cannot override fn(): void in A because overriding return type is not compatible with the other return type. */ +/* @@? 22:21 Error TypeError: Method fn(): Int in B not overriding any method */ diff --git a/ets2panda/test/ast/parser/ets/generic_error.ets b/ets2panda/test/ast/parser/ets/generic_error.ets index 1f5ee0a251..195bb99fa6 100644 --- a/ets2panda/test/ast/parser/ets/generic_error.ets +++ b/ets2panda/test/ast/parser/ets/generic_error.ets @@ -23,4 +23,4 @@ function main(): void { let m = new OldMap/* @@ label */(); } -/* @@@ label Error TypeError: Type C is not assignable to constraint type Comparable */ +/* @@@ label Error TypeError: Type argument 'C' should be a subtype of 'Comparable'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets b/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets index 9268e2c5eb..3b5e329f91 100644 --- a/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets +++ b/ets2panda/test/ast/parser/ets/generics_type_param_constraint_8.ets @@ -19,4 +19,4 @@ function main(){ const myCharClass = new X/* @@ label */(); } -/* @@@ label Error TypeError: Type Char is not assignable to constraint type Comparable */ +/* @@@ label Error TypeError: Type argument 'Char' should be a subtype of 'Comparable'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets b/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets index d1fa3f8e04..ba846261ac 100644 --- a/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets +++ b/ets2panda/test/ast/parser/ets/getter_setter_access_modifiers_2.ets @@ -39,7 +39,7 @@ class Hex extends Core { } } -/* @@? 33:22 Error TypeError: size(s: int): void in Hex cannot override size(s: int): void in Core because overridden method is final. */ -/* @@? 33:22 Error TypeError: Method size(s: int): void in Hex not overriding any method */ -/* @@? 37:22 Error TypeError: size(): int in Hex cannot override size(): int in Core because overridden method is final. */ -/* @@? 37:22 Error TypeError: Method size(): int in Hex not overriding any method */ +/* @@? 33:22 Error TypeError: size(s: Int): void in Hex cannot override size(s: Int): void in Core because overridden method is final. */ +/* @@? 33:22 Error TypeError: Method size(s: Int): void in Hex not overriding any method */ +/* @@? 37:22 Error TypeError: size(): Int in Hex cannot override size(): Int in Core because overridden method is final. */ +/* @@? 37:22 Error TypeError: Method size(): Int in Hex not overriding any method */ diff --git a/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets b/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets index fbf2024f41..d49ec5f228 100644 --- a/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets +++ b/ets2panda/test/ast/parser/ets/illegal_union_member_exp.ets @@ -21,3 +21,6 @@ function main(): void { let b = s ?? a; b.toString(); } + + +/* @@@ label Error TypeError: Type String|Int[] is illegal in union member expression. */ diff --git a/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets index b5508f11e4..cfbfbd87ed 100644 --- a/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets +++ b/ets2panda/test/ast/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -export const flt: float = 2.345; +export const flt: float = 2.345f; export let c: int = 3; diff --git a/ets2panda/test/ast/parser/ets/keyof_constraint.ets b/ets2panda/test/ast/parser/ets/keyof_constraint.ets index b3265d6059..ed208c3516 100644 --- a/ets2panda/test/ast/parser/ets/keyof_constraint.ets +++ b/ets2panda/test/ast/parser/ets/keyof_constraint.ets @@ -30,6 +30,6 @@ function main():void{ /* @@ label2 */getProperty(/* @@ label3 */"field12345"); } -/* @@@ label1 Error TypeError: Type "field12345" is not assignable to constraint type "method1"|"field1"|"field2" */ +/* @@@ label1 Error TypeError: Type argument '"field12345"' should be a subtype of '"method1"|"field1"|"field2"'-constraint */ /* @@@ label2 Error TypeError: No matching call signature for getProperty("field12345") */ /* @@@ label3 Error TypeError: Type '"field12345"' is not compatible with type '"method1"|"field1"|"field2"' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets b/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets index c424831940..75cc29a912 100644 --- a/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets +++ b/ets2panda/test/ast/parser/ets/lambda-type-inference-neg.ets @@ -20,10 +20,9 @@ function foo(callback: (x: boolean) => void): void { } function main(): void { - /* @@ label1 */foo((x) => { + foo((x) => { }); } /* @@@ label Error TypeError: Function foo with this assembly signature already declared. */ -/* @@@ label1 Error TypeError: Reference to foo is ambiguous */ diff --git a/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets b/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets index fbeb2cd8c7..8ab267434d 100644 --- a/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets +++ b/ets2panda/test/ast/parser/ets/lambda-type-inference-overloaded-1.ets @@ -29,10 +29,10 @@ function main(): void { return y.length == x; }); // Should report an error - /* @@ label1 */foo((x, y) => { + foo((x, y) => /* @@ label1 */{ console.println("hello"); }); } /* @@@ label Error TypeError: Function foo with this assembly signature already declared. */ -/* @@@ label1 Error TypeError: Reference to foo is ambiguous */ +/* @@@ label1 Error TypeError: Type 'void' is not compatible with the enclosing method's return type 'Boolean' */ diff --git a/ets2panda/test/ast/parser/ets/loops.ets b/ets2panda/test/ast/parser/ets/loops.ets index 027c90e682..b615b0ecd6 100644 --- a/ets2panda/test/ast/parser/ets/loops.ets +++ b/ets2panda/test/ast/parser/ets/loops.ets @@ -65,4 +65,3 @@ function labeledcontinue(): void { } /* @@? 19:15 Error TypeError: Unresolved reference i */ -/* @@? 19:15 Error TypeError: Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type. */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets index 7fbea40572..7656872082 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test2.ets @@ -19,5 +19,5 @@ function foo (p: [int, string]) { let x: Readonly<[int, string]> = [] /* @@ label */foo(/* @@ label1 */x) -/* @@@ label1 Error TypeError: Type 'readonly [int, String]' is not compatible with type '[int, String]' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(readonly [int, String]) */ +/* @@@ label1 Error TypeError: Type 'readonly [Int, String]' is not compatible with type '[Int, String]' at index 1 */ +/* @@@ label Error TypeError: No matching call signature for foo(readonly [Int, String]) */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets index 0953054d47..1d321b90e4 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test3.ets @@ -17,4 +17,4 @@ function foo (x: Readonly<[int, string]>) { let y: [int, string] = /* @@ label */x } -/* @@@ label Error TypeError: Type 'readonly [int, String]' cannot be assigned to type '[int, String]' */ +/* @@@ label Error TypeError: Type 'readonly [Int, String]' cannot be assigned to type '[Int, String]' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets index fd6e6d8419..12e4c37fed 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test2.ets @@ -18,4 +18,4 @@ function foo (x: readonly [int, string]) { let y: [int, string] = /* @@ label */x } -/* @@@ label Error TypeError: Type 'readonly [int, String]' cannot be assigned to type '[int, String]' */ +/* @@@ label Error TypeError: Type 'readonly [Int, String]' cannot be assigned to type '[Int, String]' */ diff --git a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets index 448f5ebcdb..c070f2aba9 100644 --- a/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets +++ b/ets2panda/test/ast/parser/ets/readonly-parameter-test/readonly-parameter-test5.ets @@ -19,5 +19,5 @@ function foo (p: [int, string]) { let x: readonly [int, string] = [] /* @@ label */foo(/* @@ label1 */x) -/* @@@ label1 Error TypeError: Type 'readonly [int, String]' is not compatible with type '[int, String]' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(readonly [int, String]) */ +/* @@@ label Error TypeError: No matching call signature for foo(readonly [Int, String]) */ +/* @@@ label1 Error TypeError: Type 'readonly [Int, String]' is not compatible with type '[Int, String]' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets index 982bba0c4e..2dd0f6a4a1 100644 --- a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets +++ b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck01.ets @@ -19,4 +19,3 @@ function main(){ "key2": 2 } } -/* @@@ label Error TypeError: Type Char|String is not assignable to constraint type Numeric|String */ diff --git a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets index 71687363c5..d1e722c345 100644 --- a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets +++ b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck02.ets @@ -21,4 +21,4 @@ function main(){ 2: 2 } } -/* @@@ label Error TypeError: Type A|Double is not assignable to constraint type Numeric|String */ +/* @@@ label Error TypeError: Type argument 'A|Double' should be a subtype of 'Numeric|String'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets index 316c665343..70e71e1254 100644 --- a/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets +++ b/ets2panda/test/ast/parser/ets/recordKeyTypeCheck03.ets @@ -18,4 +18,4 @@ class A{} function main(){ let a: Record/* @@ label */ } -/* @@@ label Error TypeError: Type BigInt is not assignable to constraint type Numeric|String */ +/* @@@ label Error TypeError: Type argument 'BigInt' should be a subtype of 'Numeric|String'-constraint */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_06.ets b/ets2panda/test/ast/parser/ets/rest_parameter_06.ets index 969c4fc10f..7a59b5b5ed 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_06.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_06.ets @@ -19,4 +19,4 @@ function sum(...numbers: [number, number, number]): number { /* @@ label */sum(10, 20, 30, 40) -/* @@@ label Error TypeError: No matching call signature for sum(int, int, int, int) */ +/* @@@ label Error TypeError: No matching call signature for sum(Int, Int, Int, Int) */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_07.ets b/ets2panda/test/ast/parser/ets/rest_parameter_07.ets index 922f5eeac9..450b5b113b 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_07.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_07.ets @@ -17,6 +17,6 @@ function sum(...numbers: [number, number, number]): number { return numbers[0] + numbers[1] + numbers[2] } -/* @@ label1 */sum(10, 20, /* @@ label2 */"one") +/* @@ label1 */sum(10, 20, "one") -/* @@@ label1 Error TypeError: No matching call signature for sum(int, int, "one") */ +/* @@@ label1 Error TypeError: No matching call signature for sum(Int, Int, "one") */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_08.ets b/ets2panda/test/ast/parser/ets/rest_parameter_08.ets index 9d88285846..b3b1cab78b 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_08.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_08.ets @@ -23,6 +23,6 @@ function sum(a: int, ...numbers: [number, number, number]): number { /* @@ label4 */sum(11,12,13,15,16) /* @@@ label1 Error TypeError: No matching call signature */ -/* @@@ label2 Error TypeError: No matching call signature for sum(int) */ -/* @@@ label3 Error TypeError: No matching call signature for sum(int, int, int) */ -/* @@@ label4 Error TypeError: No matching call signature for sum(int, int, int, int, int) */ +/* @@@ label2 Error TypeError: No matching call signature for sum(Int) */ +/* @@@ label3 Error TypeError: No matching call signature for sum(Int, Int, Int) */ +/* @@@ label4 Error TypeError: No matching call signature for sum(Int, Int, Int, Int, Int) */ diff --git a/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets b/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets index 6504bba423..f527a78056 100644 --- a/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets +++ b/ets2panda/test/ast/parser/ets/type_decution_unnecessary_boxing.ets @@ -19,5 +19,4 @@ x = true ? x:():long=>32 let y:()=>int = ()=>16 as int y = true ? y:():int=>32 y = true ? ():int=>32:y -x = /* @@ label */true ? x:"apple" -/* @@@ label Error TypeError: Type '() => Long|"apple"' cannot be assigned to type '() => Long' */ \ No newline at end of file +x = true ? x:"apple" \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_43.ets b/ets2panda/test/ast/parser/ets/unexpected_token_43.ets index 5b223d199e..0453dad9ad 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_43.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_43.ets @@ -16,12 +16,9 @@ let v2 = `--- ${y + abc /* @@ label */${y} = ${ n*2 }!`/* @@ label1 */} ---`;` /* @@? 16:17 Error TypeError: Unresolved reference y */ -/* @@? 16:17 Error TypeError: Unresolved reference y */ -/* @@? 16:21 Error TypeError: Unresolved reference abc */ /* @@? 16:21 Error TypeError: Unresolved reference abc */ -/* @@? 16:39 Error SyntaxError: Expected '}', got 'identification literal'. */ -/* @@? 16:49 Error TypeError: Unresolved reference n */ +/* @@@ label Error SyntaxError: Expected '}', got 'identification literal'. */ /* @@? 16:49 Error TypeError: Unresolved reference n */ -/* @@? 16:71 Error SyntaxError: Unexpected token '}'. */ -/* @@? 16:76 Error TypeError: Bad operand type, the type of the operand must be numeric type. */ -/* @@? 28:1 Error SyntaxError: Invalid left-hand side in prefix operation. */ +/* @@@ label1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 16:75 Error TypeError: Wrong operand type for unary expression */ +/* @@? 25:1 Error SyntaxError: Invalid left-hand side in prefix operation. */ diff --git a/ets2panda/test/compiler/ets/boxingConversion2-expected.txt b/ets2panda/test/compiler/ets/boxingConversion2-expected.txt index fd853951c7..0d27fe5b4d 100644 --- a/ets2panda/test/compiler/ets/boxingConversion2-expected.txt +++ b/ets2panda/test/compiler/ets/boxingConversion2-expected.txt @@ -731,7 +731,7 @@ }, "end": { "line": 23, - "column": 23, + "column": 24, "program": "boxingConversion2.ets" } } @@ -744,7 +744,7 @@ }, "end": { "line": 23, - "column": 23, + "column": 24, "program": "boxingConversion2.ets" } } @@ -759,7 +759,7 @@ }, "end": { "line": 23, - "column": 24, + "column": 25, "program": "boxingConversion2.ets" } } diff --git a/ets2panda/test/compiler/ets/boxingConversion2.ets b/ets2panda/test/compiler/ets/boxingConversion2.ets index 094438ca81..1da22d4fbd 100644 --- a/ets2panda/test/compiler/ets/boxingConversion2.ets +++ b/ets2panda/test/compiler/ets/boxingConversion2.ets @@ -20,7 +20,7 @@ function main() : void { let d: char = c'3'; let e: int = 4; let f: long = 5; - let g: float = 6.0; + let g: float = 6.0f; let h: double = 7.0; let i: Object = a; let j: Object = b; diff --git a/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt b/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt index 253a7e61b9..ee1717f7c1 100644 --- a/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt +++ b/ets2panda/test/compiler/ets/boxingUnboxingExpressions-expected.txt @@ -2190,7 +2190,7 @@ }, "end": { "line": 35, - "column": 28, + "column": 29, "program": "boxingUnboxingExpressions.ets" } } @@ -2203,7 +2203,7 @@ }, "end": { "line": 35, - "column": 28, + "column": 29, "program": "boxingUnboxingExpressions.ets" } } @@ -2218,7 +2218,7 @@ }, "end": { "line": 35, - "column": 29, + "column": 30, "program": "boxingUnboxingExpressions.ets" } } @@ -7597,7 +7597,7 @@ }, "end": { "line": 74, - "column": 28, + "column": 29, "program": "boxingUnboxingExpressions.ets" } } @@ -7610,7 +7610,7 @@ }, "end": { "line": 74, - "column": 28, + "column": 29, "program": "boxingUnboxingExpressions.ets" } } @@ -7625,7 +7625,7 @@ }, "end": { "line": 74, - "column": 29, + "column": 30, "program": "boxingUnboxingExpressions.ets" } } diff --git a/ets2panda/test/compiler/ets/boxingUnboxingExpressions.ets b/ets2panda/test/compiler/ets/boxingUnboxingExpressions.ets index d6aba0e0e0..5868f5f280 100644 --- a/ets2panda/test/compiler/ets/boxingUnboxingExpressions.ets +++ b/ets2panda/test/compiler/ets/boxingUnboxingExpressions.ets @@ -32,7 +32,7 @@ class A { let j: Int = 200000; let k: long = new Long(200000000000); let l: Long = 200000000000; - let m: float = 2.22; + let m: float = 2.22f; let n: float = new Float(m); let o: Float = m; let p: double = new Double(2.2222222222); @@ -71,7 +71,7 @@ class A { this.integerReference(200000); this.longPrimitive(new Long(200000000000000)); this.longReference(200000000000000); - let f: float = 2.22; + let f: float = 2.22f; this.floatPrimitive(new Float(f)); this.floatReference(f); this.doublePrimitive(new Double(2.2222222222)); diff --git a/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt b/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt index e77bd71287..7dfa6b132b 100644 --- a/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt +++ b/ets2panda/test/compiler/ets/conversion-w-ASExpr-expected.txt @@ -267,38 +267,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 17, - "column": 24, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 17, - "column": 25, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 29, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 17, - "column": 33, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0, "loc": { "start": { "line": 17, @@ -410,38 +380,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 18, - "column": 27, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 31, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 18, - "column": 36, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 18, @@ -553,38 +493,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 19, - "column": 24, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 19, - "column": 25, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 19, - "column": 29, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 19, - "column": 32, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 19, @@ -696,38 +606,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 20, - "column": 23, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 20, - "column": 24, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 28, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 20, - "column": 32, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 20, @@ -839,38 +719,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 4, - "loc": { - "start": { - "line": 21, - "column": 30, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 21, - "column": 31, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 35, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 21, - "column": 40, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 21, @@ -982,38 +832,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 4, - "loc": { - "start": { - "line": 22, - "column": 23, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 22, - "column": 26, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 22, - "column": 30, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 22, - "column": 35, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 22, @@ -1125,38 +945,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 23, - "column": 26, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 23, - "column": 27, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 31, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 23, - "column": 37, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 23, @@ -1268,38 +1058,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 24, - "column": 34, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 24, - "column": 37, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 24, - "column": 41, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 24, - "column": 47, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 24, @@ -1411,38 +1171,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 65, - "loc": { - "start": { - "line": 25, - "column": 29, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 25, - "column": 31, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 25, - "column": 35, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 25, - "column": 39, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "CharLiteral", + "value": "A", "loc": { "start": { "line": 25, @@ -1554,38 +1284,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 28, - "column": 29, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 28, - "column": 32, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 28, - "column": 36, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 28, - "column": 41, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 28, @@ -1697,38 +1397,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 29, - "column": 28, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 29, - "column": 31, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 29, - "column": 35, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 29, - "column": 38, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 29, @@ -1840,38 +1510,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 30, - "column": 25, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 30, - "column": 28, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 30, - "column": 32, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 30, - "column": 36, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 30, @@ -1983,38 +1623,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 65, - "loc": { - "start": { - "line": 31, - "column": 28, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 31, - "column": 32, - "program": "conversion-w-ASExpr.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 31, - "column": 36, - "program": "conversion-w-ASExpr.ets" - }, - "end": { - "line": 31, - "column": 40, - "program": "conversion-w-ASExpr.ets" - } - } - }, + "type": "CharLiteral", + "value": "A", "loc": { "start": { "line": 31, diff --git a/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt b/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt index 31f9c61384..7ae397c5d5 100644 --- a/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt +++ b/ets2panda/test/compiler/ets/dynamicLambdaJSValue-expected.txt @@ -797,7 +797,7 @@ "loc": { "start": { "line": 24, - "column": 56, + "column": 60, "program": "dynamicLambdaJSValue.ets" }, "end": { diff --git a/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt b/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt index 5c094ae9aa..0b4e83d3b2 100644 --- a/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt +++ b/ets2panda/test/compiler/ets/dynamic_instanceof_error-expected.txt @@ -677,5 +677,4 @@ } } } -TypeError: Using the 'instance of' operator with non-object type 'a' [dynamic_instanceof_error.ets:24:11] TypeError: Right-hand side of instanceof expression must represent a type. [dynamic_instanceof_error.ets:24:11] diff --git a/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt b/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt index 2fd3325638..0ae2590b83 100644 --- a/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt +++ b/ets2panda/test/compiler/ets/enum_as_class_member_getValue_call-expected.txt @@ -283,7 +283,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, @@ -5453,7 +5453,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, diff --git a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt index 8e5a6dcacb..cade247297 100644 --- a/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt +++ b/ets2panda/test/compiler/ets/generic_arrayaslist-expected.txt @@ -6914,9 +6914,8 @@ } }, "right": { - "type": "Identifier", - "name": "fastGrowThreshold", - "decorators": [], + "type": "NumberLiteral", + "value": 8192, "loc": { "start": { "line": 71, @@ -7004,9 +7003,8 @@ } }, "right": { - "type": "Identifier", - "name": "multiplier", - "decorators": [], + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 73, @@ -7052,7 +7050,7 @@ "loc": { "start": { "line": 73, - "column": 20, + "column": 44, "program": "generic_arrayaslist.ets" }, "end": { @@ -7115,9 +7113,8 @@ } }, "right": { - "type": "Identifier", - "name": "multiplier", - "decorators": [], + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 75, @@ -25303,4 +25300,4 @@ } } TypeError: Expected 1 arguments, got 3. [generic_arrayaslist.ets:115:9] -TypeError: No matching call signature for assertTrue(int, int, "No data to popBack in ArrayAsList!") [generic_arrayaslist.ets:115:9] +TypeError: No matching call signature for assertTrue(Int, Int, "No data to popBack in ArrayAsList!") [generic_arrayaslist.ets:115:9] diff --git a/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt b/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt index 4cc17d4052..b3990eb3d0 100644 --- a/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/enum_export-expected.txt @@ -177,7 +177,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, @@ -2661,7 +2661,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, @@ -7831,7 +7831,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, diff --git a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt index d04e570c0f..a6b4aa5d8a 100644 --- a/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt +++ b/ets2panda/test/compiler/ets/import_tests/infer_imported_function_return_type_lib-expected.txt @@ -409,7 +409,7 @@ "loc": { "start": { "line": 17, - "column": 9, + "column": 17, "program": "infer_imported_function_return_type_lib.ets" }, "end": { diff --git a/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt b/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt index bab47a98ee..44c942b99d 100644 --- a/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt +++ b/ets2panda/test/compiler/ets/instanceof_object_long-expected.txt @@ -542,4 +542,3 @@ } } } -TypeError: Bad operand type, the types of the operands must be same type. [instanceof_object_long.ets:21:12] diff --git a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt index 39e640a0ff..01cee98d0d 100644 --- a/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt +++ b/ets2panda/test/compiler/ets/lambda_infer_type/lambda_infer_type_param2-expected.txt @@ -331,38 +331,8 @@ { "type": "ReturnStatement", "argument": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 17, - "column": 49, - "program": "lambda_infer_type_param2.ets" - }, - "end": { - "line": 17, - "column": 50, - "program": "lambda_infer_type_param2.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 54, - "program": "lambda_infer_type_param2.ets" - }, - "end": { - "line": 17, - "column": 59, - "program": "lambda_infer_type_param2.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt b/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt index 2b5107c89e..e621a9bb8e 100644 --- a/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt +++ b/ets2panda/test/compiler/ets/switchStatementBoxing-expected.txt @@ -308,9 +308,8 @@ { "type": "SwitchCase", "test": { - "type": "Identifier", - "name": "b", - "decorators": [], + "type": "NumberLiteral", + "value": 20, "loc": { "start": { "line": 21, diff --git a/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt b/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt index 9fff8c798d..05138eb797 100644 --- a/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt +++ b/ets2panda/test/compiler/ets/switchStatementCorrectConversion-expected.txt @@ -717,9 +717,8 @@ { "type": "SwitchCase", "test": { - "type": "Identifier", - "name": "c", - "decorators": [], + "type": "NumberLiteral", + "value": 210000, "loc": { "start": { "line": 37, diff --git a/ets2panda/test/compiler/ets/tuple_types_1-expected.txt b/ets2panda/test/compiler/ets/tuple_types_1-expected.txt index d7a76bc740..43b1a9cac1 100644 --- a/ets2panda/test/compiler/ets/tuple_types_1-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_1-expected.txt @@ -2453,7 +2453,7 @@ "loc": { "start": { "line": 35, - "column": 19, + "column": 40, "program": "tuple_types_1.ets" }, "end": { diff --git a/ets2panda/test/compiler/ets/tuple_types_15-expected.txt b/ets2panda/test/compiler/ets/tuple_types_15-expected.txt index 410a698639..dfde229154 100644 --- a/ets2panda/test/compiler/ets/tuple_types_15-expected.txt +++ b/ets2panda/test/compiler/ets/tuple_types_15-expected.txt @@ -1291,7 +1291,7 @@ "loc": { "start": { "line": 31, - "column": 26, + "column": 44, "program": "tuple_types_15.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt b/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt index 59013f92d3..1284c1cdd2 100644 --- a/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt +++ b/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt @@ -1502,7 +1502,7 @@ "loc": { "start": { "line": 31, - "column": 14, + "column": 26, "program": "AccessBinaryTrees.ets" }, "end": { @@ -2236,7 +2236,7 @@ "loc": { "start": { "line": 43, - "column": 39, + "column": 41, "program": "AccessBinaryTrees.ets" }, "end": { @@ -2920,43 +2920,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessBinaryTrees", - "decorators": [], - "loc": { - "start": { - "line": 54, - "column": 23, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 54, - "column": 40, - "program": "AccessBinaryTrees.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "startDepth", - "decorators": [], - "loc": { - "start": { - "line": 54, - "column": 41, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 54, - "column": 51, - "program": "AccessBinaryTrees.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 54, @@ -3019,43 +2984,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessBinaryTrees", - "decorators": [], - "loc": { - "start": { - "line": 54, - "column": 58, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 54, - "column": 75, - "program": "AccessBinaryTrees.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "endDepth", - "decorators": [], - "loc": { - "start": { - "line": 54, - "column": 76, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 54, - "column": 84, - "program": "AccessBinaryTrees.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 7, "loc": { "start": { "line": 54, @@ -3157,43 +3087,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessBinaryTrees", - "decorators": [], - "loc": { - "start": { - "line": 55, - "column": 27, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 55, - "column": 44, - "program": "AccessBinaryTrees.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "startDepth", - "decorators": [], - "loc": { - "start": { - "line": 55, - "column": 45, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 55, - "column": 55, - "program": "AccessBinaryTrees.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 55, @@ -5128,43 +5023,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessBinaryTrees", - "decorators": [], - "loc": { - "start": { - "line": 75, - "column": 19, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 75, - "column": 36, - "program": "AccessBinaryTrees.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 75, - "column": 37, - "program": "AccessBinaryTrees.ets" - }, - "end": { - "line": 75, - "column": 45, - "program": "AccessBinaryTrees.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": -4, "loc": { "start": { "line": 75, diff --git a/ets2panda/test/parser/ets/AccessNBody-expected.txt b/ets2panda/test/parser/ets/AccessNBody-expected.txt index 83097faa8d..c3bb92a60e 100644 --- a/ets2panda/test/parser/ets/AccessNBody-expected.txt +++ b/ets2panda/test/parser/ets/AccessNBody-expected.txt @@ -197,7 +197,7 @@ "loc": { "start": { "line": 20, - "column": 36, + "column": 40, "program": "AccessNBody.ets" }, "end": { @@ -6671,7 +6671,7 @@ "loc": { "start": { "line": 78, - "column": 34, + "column": 39, "program": "AccessNBody.ets" }, "end": { @@ -7112,7 +7112,7 @@ "loc": { "start": { "line": 80, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -7311,7 +7311,7 @@ "loc": { "start": { "line": 81, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -7510,7 +7510,7 @@ "loc": { "start": { "line": 82, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -7709,7 +7709,7 @@ "loc": { "start": { "line": 83, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -7908,7 +7908,7 @@ "loc": { "start": { "line": 84, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -8107,7 +8107,7 @@ "loc": { "start": { "line": 85, - "column": 30, + "column": 35, "program": "AccessNBody.ets" }, "end": { @@ -10420,7 +10420,7 @@ "loc": { "start": { "line": 104, - "column": 39, + "column": 50, "program": "AccessNBody.ets" }, "end": { @@ -10564,7 +10564,7 @@ "loc": { "start": { "line": 104, - "column": 19, + "column": 25, "program": "AccessNBody.ets" }, "end": { @@ -11632,7 +11632,7 @@ "loc": { "start": { "line": 110, - "column": 34, + "column": 39, "program": "AccessNBody.ets" }, "end": { @@ -12227,7 +12227,7 @@ "loc": { "start": { "line": 119, - "column": 43, + "column": 47, "program": "AccessNBody.ets" }, "end": { @@ -12686,75 +12686,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00166008, - "loc": { - "start": { - "line": 125, - "column": 102, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 125, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 128, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 139, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 140, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 125, - "column": 128, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0.606326, "loc": { "start": { "line": 125, @@ -12769,75 +12702,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00769901, - "loc": { - "start": { - "line": 125, - "column": 155, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 178, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 192, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 193, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 125, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2.81199, "loc": { "start": { "line": 125, @@ -12852,75 +12718,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": -6.9046e-05, - "loc": { - "start": { - "line": 125, - "column": 208, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 232, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 235, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 246, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 125, - "column": 247, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 260, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 125, - "column": 235, - "program": "AccessNBody.ets" - }, - "end": { - "line": 125, - "column": 260, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": -0.0252184, "loc": { "start": { "line": 125, @@ -13298,21 +13097,69 @@ } } }, + { + "type": "NumberLiteral", + "value": -1.01077, + "loc": { + "start": { + "line": 128, + "column": 101, + "program": "AccessNBody.ets" + }, + "end": { + "line": 128, + "column": 153, + "program": "AccessNBody.ets" + } + } + }, + { + "type": "NumberLiteral", + "value": 1.82566, + "loc": { + "start": { + "line": 128, + "column": 155, + "program": "AccessNBody.ets" + }, + "end": { + "line": 128, + "column": 206, + "program": "AccessNBody.ets" + } + } + }, + { + "type": "NumberLiteral", + "value": 0.00841576, + "loc": { + "start": { + "line": 128, + "column": 208, + "program": "AccessNBody.ets" + }, + "end": { + "line": 128, + "column": 259, + "program": "AccessNBody.ets" + } + } + }, { "type": "BinaryExpression", "operator": "*", "left": { "type": "NumberLiteral", - "value": -0.00276743, + "value": 0.000285886, "loc": { "start": { "line": 128, - "column": 101, + "column": 261, "program": "AccessNBody.ets" }, "end": { "line": 128, - "column": 125, + "column": 284, "program": "AccessNBody.ets" } } @@ -13326,29 +13173,29 @@ "loc": { "start": { "line": 128, - "column": 128, + "column": 287, "program": "AccessNBody.ets" }, "end": { "line": 128, - "column": 139, + "column": 298, "program": "AccessNBody.ets" } } }, "property": { "type": "Identifier", - "name": "DAYS_PER_YEAR", + "name": "SOLAR_MASS", "decorators": [], "loc": { "start": { "line": 128, - "column": 140, + "column": 299, "program": "AccessNBody.ets" }, "end": { "line": 128, - "column": 153, + "column": 309, "program": "AccessNBody.ets" } } @@ -13358,12 +13205,12 @@ "loc": { "start": { "line": 128, - "column": 128, + "column": 287, "program": "AccessNBody.ets" }, "end": { "line": 128, - "column": 153, + "column": 309, "program": "AccessNBody.ets" } } @@ -13371,256 +13218,7 @@ "loc": { "start": { "line": 128, - "column": 101, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00499853, - "loc": { - "start": { - "line": 128, - "column": 155, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 178, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 192, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 193, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 128, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - "loc": { - "start": { - "line": 128, - "column": 155, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 2.30417e-05, - "loc": { - "start": { - "line": 128, - "column": 208, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 231, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 234, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 245, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 246, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 128, - "column": 234, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, - "loc": { - "start": { - "line": 128, - "column": 208, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, - { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.000285886, - "loc": { - "start": { - "line": 128, - "column": 261, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 284, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 287, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 298, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "SOLAR_MASS", - "decorators": [], - "loc": { - "start": { - "line": 128, - "column": 299, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 309, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 128, - "column": 287, - "program": "AccessNBody.ets" - }, - "end": { - "line": 128, - "column": 309, - "program": "AccessNBody.ets" - } - } - }, - "loc": { - "start": { - "line": 128, - "column": 261, + "column": 261, "program": "AccessNBody.ets" }, "end": { @@ -13912,158 +13510,24 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.0029646, - "loc": { - "start": { - "line": 131, - "column": 102, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 125, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 128, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 139, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 140, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 131, - "column": 128, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - "loc": { - "start": { - "line": 131, - "column": 102, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 153, - "program": "AccessNBody.ets" - } - } - }, - { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00237847, - "loc": { - "start": { - "line": 131, - "column": 155, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 178, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 192, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 193, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 206, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 131, - "column": 181, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 206, - "program": "AccessNBody.ets" - } + "type": "NumberLiteral", + "value": 1.08279, + "loc": { + "start": { + "line": 131, + "column": 102, + "program": "AccessNBody.ets" + }, + "end": { + "line": 131, + "column": 153, + "program": "AccessNBody.ets" } - }, + } + }, + { + "type": "NumberLiteral", + "value": 0.868713, "loc": { "start": { "line": 131, @@ -14078,75 +13542,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": -2.9659e-05, - "loc": { - "start": { - "line": 131, - "column": 208, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 232, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 235, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 246, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 131, - "column": 247, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 260, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 131, - "column": 235, - "program": "AccessNBody.ets" - }, - "end": { - "line": 131, - "column": 260, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": -0.0108326, "loc": { "start": { "line": 131, @@ -14525,75 +13922,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00268068, - "loc": { - "start": { - "line": 134, - "column": 101, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 124, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 127, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 138, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 139, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 152, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 134, - "column": 127, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 152, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0.979091, "loc": { "start": { "line": 134, @@ -14608,75 +13938,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.00162824, - "loc": { - "start": { - "line": 134, - "column": 154, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 177, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 180, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 191, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 192, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 205, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 134, - "column": 180, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 205, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0.594699, "loc": { "start": { "line": 134, @@ -14691,75 +13954,8 @@ } }, { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": -9.51592e-05, - "loc": { - "start": { - "line": 134, - "column": 207, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 231, - "program": "AccessNBody.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNBody", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 234, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 245, - "program": "AccessNBody.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "DAYS_PER_YEAR", - "decorators": [], - "loc": { - "start": { - "line": 134, - "column": 246, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 134, - "column": 234, - "program": "AccessNBody.ets" - }, - "end": { - "line": 134, - "column": 259, - "program": "AccessNBody.ets" - } - } - }, + "type": "NumberLiteral", + "value": -0.034756, "loc": { "start": { "line": 134, diff --git a/ets2panda/test/parser/ets/AccessNSieve-expected.txt b/ets2panda/test/parser/ets/AccessNSieve-expected.txt index bf181a0b4a..bca0f63108 100644 --- a/ets2panda/test/parser/ets/AccessNSieve-expected.txt +++ b/ets2panda/test/parser/ets/AccessNSieve-expected.txt @@ -513,178 +513,12 @@ } }, "dimension": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "BinaryExpression", - "operator": "<<", - "left": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 23, - "column": 41, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 42, - "program": "AccessNSieve.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 46, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 58, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n1", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 59, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 61, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 23, - "column": 46, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 61, - "program": "AccessNSieve.ets" - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 40, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 62, - "program": "AccessNSieve.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 65, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 77, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n2", - "decorators": [], - "loc": { - "start": { - "line": 23, - "column": 78, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 80, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 23, - "column": 65, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 80, - "program": "AccessNSieve.ets" - } - } - }, - "loc": { - "start": { - "line": 23, - "column": 40, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 80, - "program": "AccessNSieve.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 23, - "column": 83, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 23, - "column": 84, - "program": "AccessNSieve.ets" - } - } - }, + "type": "NumberLiteral", + "value": 80001, "loc": { "start": { "line": 23, - "column": 40, + "column": 65, "program": "AccessNSieve.ets" }, "end": { @@ -2395,43 +2229,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 46, - "column": 31, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 46, - "column": 43, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n1", - "decorators": [], - "loc": { - "start": { - "line": 46, - "column": 44, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 46, - "column": 46, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 46, @@ -2585,43 +2384,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 31, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 47, - "column": 43, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n2", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 44, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 47, - "column": 46, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 10000, "loc": { "start": { "line": 47, @@ -3164,43 +2928,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "AccessNSieve", - "decorators": [], - "loc": { - "start": { - "line": 55, - "column": 19, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 55, - "column": 31, - "program": "AccessNSieve.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 55, - "column": 32, - "program": "AccessNSieve.ets" - }, - "end": { - "line": 55, - "column": 40, - "program": "AccessNSieve.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 14302, "loc": { "start": { "line": 55, diff --git a/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt b/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt index 978b8c3d6e..e7dfdc922e 100644 --- a/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt +++ b/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt @@ -1948,43 +1948,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Bitops3BitBitsInByte", - "decorators": [], - "loc": { - "start": { - "line": 37, - "column": 19, - "program": "Bitops3BitBitsInByte.ets" - }, - "end": { - "line": 37, - "column": 39, - "program": "Bitops3BitBitsInByte.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 37, - "column": 40, - "program": "Bitops3BitBitsInByte.ets" - }, - "end": { - "line": 37, - "column": 48, - "program": "Bitops3BitBitsInByte.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 512000, "loc": { "start": { "line": 37, diff --git a/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt b/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt index 19b23b72af..b3997a5659 100644 --- a/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt +++ b/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt @@ -1690,43 +1690,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "BitopsBitsInByte", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 19, - "program": "BitopsBitsInByte.ets" - }, - "end": { - "line": 40, - "column": 35, - "program": "BitopsBitsInByte.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 36, - "program": "BitopsBitsInByte.ets" - }, - "end": { - "line": 40, - "column": 44, - "program": "BitopsBitsInByte.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 358400, "loc": { "start": { "line": 40, diff --git a/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt b/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt index 26c14b0b75..8211a2bca8 100644 --- a/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt +++ b/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt @@ -681,43 +681,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "BitopsBitwiseAnd", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 31, - "program": "BitopsBitwiseAnd.ets" - }, - "end": { - "line": 26, - "column": 47, - "program": "BitopsBitwiseAnd.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 48, - "program": "BitopsBitwiseAnd.ets" - }, - "end": { - "line": 26, - "column": 56, - "program": "BitopsBitwiseAnd.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 0, "loc": { "start": { "line": 26, diff --git a/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt b/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt index 8b1ab7c272..9cac89a156 100644 --- a/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt +++ b/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt @@ -586,7 +586,7 @@ "loc": { "start": { "line": 20, - "column": 21, + "column": 25, "program": "BitopsNSieveBits.ets" }, "end": { @@ -2259,7 +2259,7 @@ "loc": { "start": { "line": 37, - "column": 34, + "column": 47, "program": "BitopsNSieveBits.ets" }, "end": { @@ -3559,43 +3559,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "BitopsNSieveBits", - "decorators": [], - "loc": { - "start": { - "line": 53, - "column": 19, - "program": "BitopsNSieveBits.ets" - }, - "end": { - "line": 53, - "column": 35, - "program": "BitopsNSieveBits.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 53, - "column": 36, - "program": "BitopsNSieveBits.ets" - }, - "end": { - "line": 53, - "column": 44, - "program": "BitopsNSieveBits.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": -1286749544853, "loc": { "start": { "line": 53, diff --git a/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt b/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt index a2e875bc56..e9b661d180 100644 --- a/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt +++ b/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt @@ -2756,43 +2756,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "ControlFlowRecursive", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 23, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 47, - "column": 43, - "program": "ControlFlowRecursive.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n1", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 44, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 47, - "column": 46, - "program": "ControlFlowRecursive.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 47, @@ -2855,43 +2820,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "ControlFlowRecursive", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 53, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 47, - "column": 73, - "program": "ControlFlowRecursive.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n2", - "decorators": [], - "loc": { - "start": { - "line": 47, - "column": 74, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 47, - "column": 76, - "program": "ControlFlowRecursive.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 47, @@ -3418,7 +3348,7 @@ "loc": { "start": { "line": 50, - "column": 42, + "column": 46, "program": "ControlFlowRecursive.ets" }, "end": { @@ -3499,7 +3429,7 @@ "loc": { "start": { "line": 50, - "column": 53, + "column": 57, "program": "ControlFlowRecursive.ets" }, "end": { @@ -3666,43 +3596,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "ControlFlowRecursive", - "decorators": [], - "loc": { - "start": { - "line": 53, - "column": 22, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 53, - "column": 42, - "program": "ControlFlowRecursive.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 53, - "column": 43, - "program": "ControlFlowRecursive.ets" - }, - "end": { - "line": 53, - "column": 51, - "program": "ControlFlowRecursive.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 57775, "loc": { "start": { "line": 53, diff --git a/ets2panda/test/parser/ets/MathCordic-expected.txt b/ets2panda/test/parser/ets/MathCordic-expected.txt index c0750d7e2c..24aa1ecc17 100644 --- a/ets2panda/test/parser/ets/MathCordic-expected.txt +++ b/ets2panda/test/parser/ets/MathCordic-expected.txt @@ -2720,43 +2720,8 @@ "type": "BinaryExpression", "operator": "*", "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathCordic", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 32, - "program": "MathCordic.ets" - }, - "end": { - "line": 40, - "column": 42, - "program": "MathCordic.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "AG_CONST", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 43, - "program": "MathCordic.ets" - }, - "end": { - "line": 40, - "column": 51, - "program": "MathCordic.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 0.607253, "loc": { "start": { "line": 40, @@ -5061,43 +5026,8 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathCordic", - "decorators": [], - "loc": { - "start": { - "line": 63, - "column": 46, - "program": "MathCordic.ets" - }, - "end": { - "line": 63, - "column": 56, - "program": "MathCordic.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TARGET_ANGLE", - "decorators": [], - "loc": { - "start": { - "line": 63, - "column": 57, - "program": "MathCordic.ets" - }, - "end": { - "line": 63, - "column": 69, - "program": "MathCordic.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 28.027, "loc": { "start": { "line": 63, @@ -5707,43 +5637,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathCordic", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 25, - "program": "MathCordic.ets" - }, - "end": { - "line": 74, - "column": 35, - "program": "MathCordic.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 36, - "program": "MathCordic.ets" - }, - "end": { - "line": 74, - "column": 44, - "program": "MathCordic.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 10362.6, "loc": { "start": { "line": 74, diff --git a/ets2panda/test/parser/ets/MathPartialSums-expected.txt b/ets2panda/test/parser/ets/MathPartialSums-expected.txt index 5f16c7c110..7c3bcccd35 100644 --- a/ets2panda/test/parser/ets/MathPartialSums-expected.txt +++ b/ets2panda/test/parser/ets/MathPartialSums-expected.txt @@ -1190,40 +1190,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 33, - "column": 29, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 33, - "column": 32, - "program": "MathPartialSums.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 33, - "column": 35, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 33, - "column": 38, - "program": "MathPartialSums.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0.666667, "loc": { "start": { "line": 33, @@ -3734,7 +3702,7 @@ "loc": { "start": { "line": 59, - "column": 11, + "column": 16, "program": "MathPartialSums.ets" }, "end": { @@ -4202,7 +4170,7 @@ "loc": { "start": { "line": 69, - "column": 12, + "column": 17, "program": "MathPartialSums.ets" }, "end": { @@ -4498,43 +4466,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathPartialSums", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 23, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 74, - "column": 38, - "program": "MathPartialSums.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n1", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 39, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 74, - "column": 41, - "program": "MathPartialSums.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 1024, "loc": { "start": { "line": 74, @@ -4597,43 +4530,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathPartialSums", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 48, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 74, - "column": 63, - "program": "MathPartialSums.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n2", - "decorators": [], - "loc": { - "start": { - "line": 74, - "column": 64, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 74, - "column": 66, - "program": "MathPartialSums.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 16384, "loc": { "start": { "line": 74, @@ -4913,43 +4811,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathPartialSums", - "decorators": [], - "loc": { - "start": { - "line": 78, - "column": 19, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 78, - "column": 34, - "program": "MathPartialSums.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 78, - "column": 35, - "program": "MathPartialSums.ets" - }, - "end": { - "line": 78, - "column": 43, - "program": "MathPartialSums.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 60.0899, "loc": { "start": { "line": 78, @@ -5169,7 +5032,7 @@ "loc": { "start": { "line": 79, - "column": 14, + "column": 40, "program": "MathPartialSums.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt b/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt index 23db51eb62..bb875c96e8 100644 --- a/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt +++ b/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt @@ -6832,43 +6832,8 @@ } }, { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "MathSpectralNorm", - "decorators": [], - "loc": { - "start": { - "line": 87, - "column": 21, - "program": "MathSpectralNorm.ets" - }, - "end": { - "line": 87, - "column": 37, - "program": "MathSpectralNorm.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "expected", - "decorators": [], - "loc": { - "start": { - "line": 87, - "column": 38, - "program": "MathSpectralNorm.ets" - }, - "end": { - "line": 87, - "column": 46, - "program": "MathSpectralNorm.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 5.08669, "loc": { "start": { "line": 87, diff --git a/ets2panda/test/parser/ets/Morph3d-expected.txt b/ets2panda/test/parser/ets/Morph3d-expected.txt index 1ad08a5f9f..e915efc571 100644 --- a/ets2panda/test/parser/ets/Morph3d-expected.txt +++ b/ets2panda/test/parser/ets/Morph3d-expected.txt @@ -524,146 +524,12 @@ } }, "dimension": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 28, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 35, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 36, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 41, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 26, - "column": 28, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 41, - "program": "Morph3d.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 44, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 51, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 52, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 57, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 26, - "column": 44, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 57, - "program": "Morph3d.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 28, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 57, - "program": "Morph3d.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 26, - "column": 60, - "program": "Morph3d.ets" - }, - "end": { - "line": 26, - "column": 61, - "program": "Morph3d.ets" - } - } - }, + "type": "NumberLiteral", + "value": 43200, "loc": { "start": { "line": 26, - "column": 28, + "column": 44, "program": "Morph3d.ets" }, "end": { @@ -816,146 +682,12 @@ } }, "right": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 37, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 38, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 43, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 43, - "program": "Morph3d.ets" - } - } - }, - "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 46, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 53, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 54, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 59, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, - "loc": { - "start": { - "line": 27, - "column": 46, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 59, - "program": "Morph3d.ets" - } - } - }, - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 59, - "program": "Morph3d.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 27, - "column": 62, - "program": "Morph3d.ets" - }, - "end": { - "line": 27, - "column": 63, - "program": "Morph3d.ets" - } - } - }, + "type": "NumberLiteral", + "value": 43200, "loc": { "start": { "line": 27, - "column": 30, + "column": 46, "program": "Morph3d.ets" }, "end": { @@ -1434,43 +1166,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 33, - "column": 39, - "program": "Morph3d.ets" - }, - "end": { - "line": 33, - "column": 46, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 33, - "column": 47, - "program": "Morph3d.ets" - }, - "end": { - "line": 33, - "column": 52, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 33, @@ -1487,7 +1184,7 @@ "loc": { "start": { "line": 33, - "column": 30, + "column": 35, "program": "Morph3d.ets" }, "end": { @@ -1677,7 +1374,7 @@ "loc": { "start": { "line": 34, - "column": 36, + "column": 40, "program": "Morph3d.ets" }, "end": { @@ -1860,43 +1557,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 31, - "program": "Morph3d.ets" - }, - "end": { - "line": 36, - "column": 38, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 39, - "program": "Morph3d.ets" - }, - "end": { - "line": 36, - "column": 44, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 36, @@ -2064,43 +1726,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 37, - "column": 32, - "program": "Morph3d.ets" - }, - "end": { - "line": 37, - "column": 39, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 37, - "column": 40, - "program": "Morph3d.ets" - }, - "end": { - "line": 37, - "column": 45, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 37, @@ -2268,43 +1895,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 38, - "column": 28, - "program": "Morph3d.ets" - }, - "end": { - "line": 38, - "column": 35, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 38, - "column": 36, - "program": "Morph3d.ets" - }, - "end": { - "line": 38, - "column": 41, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 38, @@ -2825,43 +2417,8 @@ } }, "init": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 44, - "column": 22, - "program": "Morph3d.ets" - }, - "end": { - "line": 44, - "column": 29, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "n", - "decorators": [], - "loc": { - "start": { - "line": 44, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 44, - "column": 31, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 15, "loc": { "start": { "line": 44, @@ -3417,43 +2974,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 50, - "column": 30, - "program": "Morph3d.ets" - }, - "end": { - "line": 50, - "column": 37, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 50, - "column": 38, - "program": "Morph3d.ets" - }, - "end": { - "line": 50, - "column": 43, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 50, @@ -3638,43 +3160,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Morph3d", - "decorators": [], - "loc": { - "start": { - "line": 51, - "column": 40, - "program": "Morph3d.ets" - }, - "end": { - "line": 51, - "column": 47, - "program": "Morph3d.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "param", - "decorators": [], - "loc": { - "start": { - "line": 51, - "column": 48, - "program": "Morph3d.ets" - }, - "end": { - "line": 51, - "column": 53, - "program": "Morph3d.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "NumberLiteral", + "value": 120, "loc": { "start": { "line": 51, diff --git a/ets2panda/test/parser/ets/StringBase64-expected.txt b/ets2panda/test/parser/ets/StringBase64-expected.txt index a307f1139e..62d180759b 100644 --- a/ets2panda/test/parser/ets/StringBase64-expected.txt +++ b/ets2panda/test/parser/ets/StringBase64-expected.txt @@ -3179,43 +3179,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 25, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 25, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 25, @@ -3484,43 +3449,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 26, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 26, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 26, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 26, @@ -3987,43 +3917,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 27, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 27, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 27, @@ -4522,43 +4417,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 28, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 28, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 28, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 28, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 28, @@ -4898,7 +4758,7 @@ "loc": { "start": { "line": 30, - "column": 13, + "column": 22, "program": "StringBase64.ets" }, "end": { @@ -5102,43 +4962,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 32, - "column": 27, - "program": "StringBase64.ets" - }, - "end": { - "line": 32, - "column": 39, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 32, - "column": 40, - "program": "StringBase64.ets" - }, - "end": { - "line": 32, - "column": 55, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 32, @@ -5493,43 +5318,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 34, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 34, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 34, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 34, - "column": 59, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 34, @@ -5996,43 +5786,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 35, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 35, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 35, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 35, - "column": 59, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 35, @@ -6361,43 +6116,8 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 36, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BASE64PAD", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 36, - "column": 53, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "=", "loc": { "start": { "line": 36, @@ -6517,43 +6237,8 @@ "callee": { "type": "MemberExpression", "object": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 39, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 39, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "TO_BASE64_TABLE", - "decorators": [], - "loc": { - "start": { - "line": 39, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 39, - "column": 59, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "StringLiteral", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "loc": { "start": { "line": 39, @@ -6850,43 +6535,8 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 40, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BASE64PAD", - "decorators": [], - "loc": { - "start": { - "line": 40, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 40, - "column": 53, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "=", "loc": { "start": { "line": 40, @@ -6985,43 +6635,8 @@ }, "arguments": [ { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 41, - "column": 31, - "program": "StringBase64.ets" - }, - "end": { - "line": 41, - "column": 43, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BASE64PAD", - "decorators": [], - "loc": { - "start": { - "line": 41, - "column": 44, - "program": "StringBase64.ets" - }, - "end": { - "line": 41, - "column": 53, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "=", "loc": { "start": { "line": 41, @@ -8339,43 +7954,8 @@ } }, "right": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "StringBase64", - "decorators": [], - "loc": { - "start": { - "line": 52, - "column": 55, - "program": "StringBase64.ets" - }, - "end": { - "line": 52, - "column": 67, - "program": "StringBase64.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BASE64PAD", - "decorators": [], - "loc": { - "start": { - "line": 52, - "column": 68, - "program": "StringBase64.ets" - }, - "end": { - "line": 52, - "column": 77, - "program": "StringBase64.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "=", "loc": { "start": { "line": 52, diff --git a/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt b/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt index b375b4963c..e3248a34b3 100644 --- a/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt +++ b/ets2panda/test/parser/ets/as_expression_unary_expression-expected.txt @@ -235,38 +235,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": -1, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "as_expression_unary_expression.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "as_expression_unary_expression.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 24, - "program": "as_expression_unary_expression.ets" - }, - "end": { - "line": 17, - "column": 28, - "program": "as_expression_unary_expression.ets" - } - } - }, + "type": "NumberLiteral", + "value": -1, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/assert-expected.txt b/ets2panda/test/parser/ets/assert-expected.txt index 223e74ab3f..b1044004b9 100644 --- a/ets2panda/test/parser/ets/assert-expected.txt +++ b/ets2panda/test/parser/ets/assert-expected.txt @@ -431,7 +431,7 @@ "loc": { "start": { "line": 20, - "column": 20, + "column": 24, "program": "assert.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/assign-expected.txt b/ets2panda/test/parser/ets/assign-expected.txt index b6142a4897..98ef7bde5d 100644 --- a/ets2panda/test/parser/ets/assign-expected.txt +++ b/ets2panda/test/parser/ets/assign-expected.txt @@ -397,9 +397,8 @@ } }, "right": { - "type": "Identifier", - "name": "b", - "decorators": [], + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/binary_op-expected.txt b/ets2panda/test/parser/ets/binary_op-expected.txt index 6ee5608b7e..66494fa2c3 100644 --- a/ets2panda/test/parser/ets/binary_op-expected.txt +++ b/ets2panda/test/parser/ets/binary_op-expected.txt @@ -806,7 +806,7 @@ "loc": { "start": { "line": 26, - "column": 10, + "column": 16, "program": "binary_op.ets" }, "end": { @@ -1136,7 +1136,7 @@ "loc": { "start": { "line": 31, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -1300,7 +1300,7 @@ "loc": { "start": { "line": 32, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -1464,7 +1464,7 @@ "loc": { "start": { "line": 33, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -1645,7 +1645,7 @@ "loc": { "start": { "line": 34, - "column": 17, + "column": 23, "program": "binary_op.ets" }, "end": { @@ -2119,7 +2119,7 @@ "loc": { "start": { "line": 40, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -3522,7 +3522,7 @@ "loc": { "start": { "line": 59, - "column": 11, + "column": 16, "program": "binary_op.ets" }, "end": { @@ -3882,7 +3882,7 @@ "loc": { "start": { "line": 64, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -4346,7 +4346,7 @@ "loc": { "start": { "line": 70, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -4600,7 +4600,7 @@ "loc": { "start": { "line": 73, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -4734,7 +4734,7 @@ "loc": { "start": { "line": 74, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -4919,7 +4919,7 @@ "loc": { "start": { "line": 75, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -5738,7 +5738,7 @@ "loc": { "start": { "line": 77, - "column": 17, + "column": 23, "program": "binary_op.ets" }, "end": { @@ -6470,7 +6470,7 @@ "loc": { "start": { "line": 26, - "column": 10, + "column": 16, "program": "binary_op.ets" }, "end": { @@ -6776,7 +6776,7 @@ "loc": { "start": { "line": 31, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -6932,7 +6932,7 @@ "loc": { "start": { "line": 32, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -7088,7 +7088,7 @@ "loc": { "start": { "line": 33, - "column": 11, + "column": 17, "program": "binary_op.ets" }, "end": { @@ -7261,7 +7261,7 @@ "loc": { "start": { "line": 34, - "column": 17, + "column": 23, "program": "binary_op.ets" }, "end": { @@ -7703,7 +7703,7 @@ "loc": { "start": { "line": 40, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -9002,7 +9002,7 @@ "loc": { "start": { "line": 59, - "column": 11, + "column": 16, "program": "binary_op.ets" }, "end": { @@ -9338,7 +9338,7 @@ "loc": { "start": { "line": 64, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -9770,7 +9770,7 @@ "loc": { "start": { "line": 70, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -10016,7 +10016,7 @@ "loc": { "start": { "line": 73, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -10142,7 +10142,7 @@ "loc": { "start": { "line": 74, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -10319,7 +10319,7 @@ "loc": { "start": { "line": 75, - "column": 11, + "column": 15, "program": "binary_op.ets" }, "end": { @@ -11122,7 +11122,7 @@ "loc": { "start": { "line": 77, - "column": 17, + "column": 23, "program": "binary_op.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/binary_operations-expected.txt b/ets2panda/test/parser/ets/binary_operations-expected.txt index b720e56330..e456b8b907 100644 --- a/ets2panda/test/parser/ets/binary_operations-expected.txt +++ b/ets2panda/test/parser/ets/binary_operations-expected.txt @@ -44,40 +44,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 17, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 17, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 17, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 17, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 17, @@ -147,104 +115,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 18, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 4, - "loc": { - "start": { - "line": 18, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 18, - "column": 38, - "program": "binary_operations.ets" - }, - "end": { - "line": 18, - "column": 39, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 18, @@ -314,40 +186,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 19, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 19, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 19, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 19, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 19, @@ -417,76 +257,12 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 20, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 20, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 20, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 20, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 20, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 20, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 20, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 20, - "column": 35, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 13, "loc": { "start": { "line": 20, - "column": 26, + "column": 30, "program": "binary_operations.ets" }, "end": { @@ -552,40 +328,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 21, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 21, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 21, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 21, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 21, @@ -655,108 +399,12 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 22, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 22, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 22, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 22, - "column": 38, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 39, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 22, - "column": 39, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": -14, "loc": { "start": { "line": 22, - "column": 26, + "column": 30, "program": "binary_operations.ets" }, "end": { @@ -822,40 +470,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 6.2, - "loc": { - "start": { - "line": 23, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 23, - "column": 32, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3.14, - "loc": { - "start": { - "line": 23, - "column": 35, - "program": "binary_operations.ets" - }, - "end": { - "line": 23, - "column": 39, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 19.468, "loc": { "start": { "line": 23, @@ -864,7 +480,7 @@ }, "end": { "line": 23, - "column": 39, + "column": 41, "program": "binary_operations.ets" } } @@ -900,7 +516,7 @@ }, "end": { "line": 23, - "column": 39, + "column": 41, "program": "binary_operations.ets" } } @@ -925,104 +541,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 6.2, - "loc": { - "start": { - "line": 24, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 33, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 3.7, - "loc": { - "start": { - "line": 24, - "column": 37, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 40, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8.18, - "loc": { - "start": { - "line": 24, - "column": 43, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 47, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 36, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 48, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 24, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 48, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2.2, - "loc": { - "start": { - "line": 24, - "column": 51, - "program": "binary_operations.ets" - }, - "end": { - "line": 24, - "column": 54, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 33.48, "loc": { "start": { "line": 24, @@ -1092,40 +612,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 4.2, - "loc": { - "start": { - "line": 25, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 25, - "column": 31, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2.3, - "loc": { - "start": { - "line": 25, - "column": 34, - "program": "binary_operations.ets" - }, - "end": { - "line": 25, - "column": 37, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1.82609, "loc": { "start": { "line": 25, @@ -1134,7 +622,7 @@ }, "end": { "line": 25, - "column": 37, + "column": 39, "program": "binary_operations.ets" } } @@ -1170,7 +658,7 @@ }, "end": { "line": 25, - "column": 37, + "column": 39, "program": "binary_operations.ets" } } @@ -1195,136 +683,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 4.2, - "loc": { - "start": { - "line": 26, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 32, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "NumberLiteral", - "value": 2.2, - "loc": { - "start": { - "line": 26, - "column": 36, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 39, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 26, - "column": 42, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 45, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 35, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 46, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 46, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 3.3, - "loc": { - "start": { - "line": 26, - "column": 50, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 53, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 6.1, - "loc": { - "start": { - "line": 26, - "column": 56, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 59, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 26, - "column": 49, - "program": "binary_operations.ets" - }, - "end": { - "line": 26, - "column": 60, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2.54098, "loc": { "start": { "line": 26, @@ -1394,40 +754,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "<<", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 27, - "column": 25, - "program": "binary_operations.ets" - }, - "end": { - "line": 27, - "column": 26, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 27, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 28, "loc": { "start": { "line": 27, @@ -1497,40 +825,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": ">>", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 28, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 28, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 28, - "column": 31, - "program": "binary_operations.ets" - }, - "end": { - "line": 28, - "column": 32, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 28, @@ -1600,40 +896,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": ">>>", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 29, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 29, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 29, - "column": 32, - "program": "binary_operations.ets" - }, - "end": { - "line": 29, - "column": 33, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 29, @@ -1703,40 +967,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "&", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 30, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 30, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 30, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 30, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 30, @@ -1790,56 +1022,24 @@ "type": "ClassProperty", "key": { "type": "Identifier", - "name": "bit2", - "decorators": [], - "loc": { - "start": { - "line": 31, - "column": 13, - "program": "binary_operations.ets" - }, - "end": { - "line": 31, - "column": 17, - "program": "binary_operations.ets" - } - } - }, - "value": { - "type": "BinaryExpression", - "operator": "|", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 31, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 31, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 31, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 31, - "column": 31, - "program": "binary_operations.ets" - } + "name": "bit2", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 13, + "program": "binary_operations.ets" + }, + "end": { + "line": 31, + "column": 17, + "program": "binary_operations.ets" } - }, + } + }, + "value": { + "type": "NumberLiteral", + "value": 7, "loc": { "start": { "line": 31, @@ -1909,40 +1109,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "^", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 32, - "column": 26, - "program": "binary_operations.ets" - }, - "end": { - "line": 32, - "column": 27, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 32, - "column": 30, - "program": "binary_operations.ets" - }, - "end": { - "line": 32, - "column": 31, - "program": "binary_operations.ets" - } - } - }, + "type": "NumberLiteral", + "value": 4, "loc": { "start": { "line": 32, @@ -2012,40 +1180,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "<", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 33, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 33, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 33, - "column": 32, - "program": "binary_operations.ets" - }, - "end": { - "line": 33, - "column": 33, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": true, "loc": { "start": { "line": 33, @@ -2115,40 +1251,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "<=", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 34, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 34, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 34, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 34, - "column": 34, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": true, "loc": { "start": { "line": 34, @@ -2218,40 +1322,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": ">=", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 35, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 35, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 35, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 35, - "column": 34, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 35, @@ -2321,40 +1393,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": ">", - "left": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 36, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 36, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 36, - "column": 32, - "program": "binary_operations.ets" - }, - "end": { - "line": 36, - "column": 33, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 36, @@ -2424,40 +1464,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "==", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 37, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 37, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 37, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 37, - "column": 34, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 37, @@ -2527,40 +1535,8 @@ } }, "value": { - "type": "BinaryExpression", - "operator": "!=", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 38, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 38, - "column": 29, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 4, - "loc": { - "start": { - "line": 38, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 38, - "column": 34, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": true, "loc": { "start": { "line": 38, @@ -2630,104 +1606,8 @@ } }, "value": { - "type": "LogicalExpression", - "operator": "&&", - "left": { - "type": "BinaryExpression", - "operator": "<", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 39, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 30, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 39, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 34, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 39, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": ">", - "left": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 39, - "column": 40, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 41, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 39, - "column": 44, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 45, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 39, - "column": 39, - "program": "binary_operations.ets" - }, - "end": { - "line": 39, - "column": 46, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 39, @@ -2797,104 +1677,8 @@ } }, "value": { - "type": "LogicalExpression", - "operator": "||", - "left": { - "type": "BinaryExpression", - "operator": "<", - "left": { - "type": "NumberLiteral", - "value": 7, - "loc": { - "start": { - "line": 40, - "column": 29, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 30, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 3, - "loc": { - "start": { - "line": 40, - "column": 33, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 34, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 40, - "column": 28, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 35, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": ">", - "left": { - "type": "NumberLiteral", - "value": 8, - "loc": { - "start": { - "line": 40, - "column": 40, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 41, - "program": "binary_operations.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 40, - "column": 44, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 45, - "program": "binary_operations.ets" - } - } - }, - "loc": { - "start": { - "line": 40, - "column": 39, - "program": "binary_operations.ets" - }, - "end": { - "line": 40, - "column": 46, - "program": "binary_operations.ets" - } - } - }, + "type": "BooleanLiteral", + "value": true, "loc": { "start": { "line": 40, diff --git a/ets2panda/test/parser/ets/binary_operations.ets b/ets2panda/test/parser/ets/binary_operations.ets index 308cb1ebe8..5c6aeef509 100644 --- a/ets2panda/test/parser/ets/binary_operations.ets +++ b/ets2panda/test/parser/ets/binary_operations.ets @@ -20,9 +20,9 @@ export class binary_operations { private sub2 : int = 8 - 3 + 8; private rem1 : int = 5 % 3; private rem2 : int = 5 % 3 - 2 * 8; - private mult1 : float = 6.2 * 3.14; + private mult1 : float = 6.2f * 3.14f; private mult2 : double = 6.2 * (3.7 + 8.18) / 2.2; - private div1 : float = 4.2 / 2.3; + private div1 : float = 4.2f / 2.3f; private div2 : double = 4.2 / (2.2 - 0.1) + (3.3 / 6.1); private lsh : int = 7 << 2; private rsh1 : int = 7 >> 2; diff --git a/ets2panda/test/parser/ets/boolean_cond-expected.txt b/ets2panda/test/parser/ets/boolean_cond-expected.txt index 5ede97c316..f498e6d0d0 100644 --- a/ets2panda/test/parser/ets/boolean_cond-expected.txt +++ b/ets2panda/test/parser/ets/boolean_cond-expected.txt @@ -248,40 +248,8 @@ { "type": "IfStatement", "test": { - "type": "BinaryExpression", - "operator": ">", - "left": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 20, - "column": 7, - "program": "boolean_cond.ets" - }, - "end": { - "line": 20, - "column": 8, - "program": "boolean_cond.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 20, - "column": 11, - "program": "boolean_cond.ets" - }, - "end": { - "line": 20, - "column": 12, - "program": "boolean_cond.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/cast_expressions-expected.txt b/ets2panda/test/parser/ets/cast_expressions-expected.txt index c7ca64e2b7..6d76a9e8a4 100644 --- a/ets2panda/test/parser/ets/cast_expressions-expected.txt +++ b/ets2panda/test/parser/ets/cast_expressions-expected.txt @@ -504,38 +504,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 18, - "column": 30, - "program": "cast_expressions.ets" - }, - "end": { - "line": 18, - "column": 32, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 36, - "program": "cast_expressions.ets" - }, - "end": { - "line": 18, - "column": 40, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 18, @@ -2596,38 +2566,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 48, - "column": 33, - "program": "cast_expressions.ets" - }, - "end": { - "line": 48, - "column": 35, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 48, - "column": 39, - "program": "cast_expressions.ets" - }, - "end": { - "line": 48, - "column": 44, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 48, @@ -4428,8 +4368,8 @@ } }, "init": { - "type": "NumberLiteral", - "value": 42, + "type": "CharLiteral", + "value": "*", "loc": { "start": { "line": 76, @@ -4591,38 +4531,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 77, - "column": 30, - "program": "cast_expressions.ets" - }, - "end": { - "line": 77, - "column": 32, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 77, - "column": 36, - "program": "cast_expressions.ets" - }, - "end": { - "line": 77, - "column": 40, - "program": "cast_expressions.ets" - } - } - }, + "type": "CharLiteral", + "value": "*", "loc": { "start": { "line": 77, @@ -6586,38 +6496,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 106, - "column": 27, - "program": "cast_expressions.ets" - }, - "end": { - "line": 106, - "column": 29, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 106, - "column": 33, - "program": "cast_expressions.ets" - }, - "end": { - "line": 106, - "column": 36, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 106, @@ -8484,38 +8364,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 134, - "column": 30, - "program": "cast_expressions.ets" - }, - "end": { - "line": 134, - "column": 32, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 134, - "column": 36, - "program": "cast_expressions.ets" - }, - "end": { - "line": 134, - "column": 40, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 134, @@ -10285,38 +10135,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 161, - "column": 33, - "program": "cast_expressions.ets" - }, - "end": { - "line": 161, - "column": 35, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 161, - "column": 39, - "program": "cast_expressions.ets" - }, - "end": { - "line": 161, - "column": 44, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 161, @@ -11989,38 +11809,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 42, - "loc": { - "start": { - "line": 187, - "column": 36, - "program": "cast_expressions.ets" - }, - "end": { - "line": 187, - "column": 38, - "program": "cast_expressions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 187, - "column": 42, - "program": "cast_expressions.ets" - }, - "end": { - "line": 187, - "column": 48, - "program": "cast_expressions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 42, "loc": { "start": { "line": 187, diff --git a/ets2panda/test/parser/ets/class_init-expected.txt b/ets2panda/test/parser/ets/class_init-expected.txt index a3a99d1115..e5d69c29a6 100644 --- a/ets2panda/test/parser/ets/class_init-expected.txt +++ b/ets2panda/test/parser/ets/class_init-expected.txt @@ -166,40 +166,8 @@ } }, "right": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 30, - "loc": { - "start": { - "line": 20, - "column": 11, - "program": "class_init.ets" - }, - "end": { - "line": 20, - "column": 13, - "program": "class_init.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 99, - "loc": { - "start": { - "line": 20, - "column": 16, - "program": "class_init.ets" - }, - "end": { - "line": 20, - "column": 18, - "program": "class_init.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2970, "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt b/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt index 5d2945240a..8783d8a8ca 100644 --- a/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt +++ b/ets2panda/test/parser/ets/conditionalExpressionType-expected.txt @@ -235,8 +235,8 @@ } }, "init": { - "type": "NumberLiteral", - "value": 100, + "type": "CharLiteral", + "value": "d", "loc": { "start": { "line": 17, @@ -301,56 +301,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 18, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 18, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 18, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 68, - "loc": { - "start": { - "line": 18, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 18, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "a", + "decorators": [], "loc": { "start": { "line": 18, @@ -496,56 +449,8 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 21, - "column": 15, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 21, - "column": 20, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 21, - "column": 23, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 21, - "column": 24, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 68, - "loc": { - "start": { - "line": 21, - "column": 27, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 21, - "column": 29, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "NumberLiteral", + "value": 68, "loc": { "start": { "line": 21, @@ -723,56 +628,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 24, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 24, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 24, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 24, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 419, - "loc": { - "start": { - "line": 24, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 24, - "column": 31, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "c", + "decorators": [], "loc": { "start": { "line": 24, @@ -852,8 +710,8 @@ } }, "init": { - "type": "NumberLiteral", - "value": 3, + "type": "CharLiteral", + "value": "\u0003", "loc": { "start": { "line": 26, @@ -918,56 +776,8 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 27, - "column": 18, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 27, - "column": 23, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 26, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 27, - "column": 27, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 665, - "loc": { - "start": { - "line": 27, - "column": 30, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 27, - "column": 33, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "NumberLiteral", + "value": 665, "loc": { "start": { "line": 27, @@ -1145,56 +955,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 30, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 30, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 30, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 30, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 665, - "loc": { - "start": { - "line": 30, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 30, - "column": 31, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "c", + "decorators": [], "loc": { "start": { "line": 30, @@ -1340,56 +1103,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 33, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 33, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 33, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 33, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 665419, - "loc": { - "start": { - "line": 33, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 33, - "column": 34, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "c", + "decorators": [], "loc": { "start": { "line": 33, @@ -1535,56 +1251,8 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 36, - "column": 19, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 36, - "column": 24, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "g", - "decorators": [], - "loc": { - "start": { - "line": 36, - "column": 27, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 36, - "column": 28, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "NumberLiteral", - "value": 30, - "loc": { - "start": { - "line": 36, - "column": 31, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 36, - "column": 33, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "NumberLiteral", + "value": 30, "loc": { "start": { "line": 36, @@ -1965,57 +1633,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 42, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 42, - "column": 21, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 42, - "column": 24, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 42, - "column": 25, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 42, - "column": 28, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 42, - "column": 29, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "a", + "decorators": [], "loc": { "start": { "line": 42, @@ -2274,57 +1894,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 46, - "column": 15, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 46, - "column": 20, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 46, - "column": 23, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 46, - "column": 24, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 46, - "column": 27, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 46, - "column": 28, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "b", + "decorators": [], "loc": { "start": { "line": 46, @@ -2617,7 +2189,7 @@ }, "end": { "line": 51, - "column": 24, + "column": 25, "program": "conditionalExpressionType.ets" } } @@ -2630,7 +2202,7 @@ }, "end": { "line": 51, - "column": 24, + "column": 25, "program": "conditionalExpressionType.ets" } } @@ -2645,7 +2217,7 @@ }, "end": { "line": 51, - "column": 25, + "column": 26, "program": "conditionalExpressionType.ets" } } @@ -3044,8 +2616,8 @@ } }, "init": { - "type": "NumberLiteral", - "value": 2, + "type": "CharLiteral", + "value": "\u0002", "loc": { "start": { "line": 56, @@ -3110,57 +2682,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 58, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 58, - "column": 22, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "a", - "decorators": [], - "loc": { - "start": { - "line": 58, - "column": 25, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 58, - "column": 26, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 58, - "column": 29, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 58, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "b", + "decorators": [], "loc": { "start": { "line": 58, @@ -3225,57 +2749,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 59, - "column": 15, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 59, - "column": 20, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "b", - "decorators": [], - "loc": { - "start": { - "line": 59, - "column": 23, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 59, - "column": 24, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 59, - "column": 27, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 59, - "column": 28, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "c", + "decorators": [], "loc": { "start": { "line": 59, @@ -3340,57 +2816,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 60, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 60, - "column": 22, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "c", - "decorators": [], - "loc": { - "start": { - "line": 60, - "column": 25, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 60, - "column": 26, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "d", - "decorators": [], - "loc": { - "start": { - "line": 60, - "column": 29, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 60, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "d", + "decorators": [], "loc": { "start": { "line": 60, @@ -3455,57 +2883,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 61, - "column": 18, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 61, - "column": 23, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "d", - "decorators": [], - "loc": { - "start": { - "line": 61, - "column": 26, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 61, - "column": 27, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "e", - "decorators": [], - "loc": { - "start": { - "line": 61, - "column": 30, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 61, - "column": 31, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "e", + "decorators": [], "loc": { "start": { "line": 61, @@ -3570,57 +2950,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 62, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 62, - "column": 22, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "e", - "decorators": [], - "loc": { - "start": { - "line": 62, - "column": 25, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 62, - "column": 26, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "f", - "decorators": [], - "loc": { - "start": { - "line": 62, - "column": 29, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 62, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "f", + "decorators": [], "loc": { "start": { "line": 62, @@ -3685,57 +3017,9 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 63, - "column": 17, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 63, - "column": 22, - "program": "conditionalExpressionType.ets" - } - } - }, - "consequent": { - "type": "Identifier", - "name": "f", - "decorators": [], - "loc": { - "start": { - "line": 63, - "column": 25, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 63, - "column": 26, - "program": "conditionalExpressionType.ets" - } - } - }, - "alternate": { - "type": "Identifier", - "name": "g", - "decorators": [], - "loc": { - "start": { - "line": 63, - "column": 29, - "program": "conditionalExpressionType.ets" - }, - "end": { - "line": 63, - "column": 30, - "program": "conditionalExpressionType.ets" - } - } - }, + "type": "Identifier", + "name": "g", + "decorators": [], "loc": { "start": { "line": 63, diff --git a/ets2panda/test/parser/ets/conditionalExpressionType.ets b/ets2panda/test/parser/ets/conditionalExpressionType.ets index 1a17d452f6..a3094001cd 100644 --- a/ets2panda/test/parser/ets/conditionalExpressionType.ets +++ b/ets2panda/test/parser/ets/conditionalExpressionType.ets @@ -48,7 +48,7 @@ function unboxingCases(): void{ function dominantNumericCases(): void{ let a : double = 2.0; - let b : float = 2.0; + let b : float = 2.0f; let c : long = 2; let d : int = 2; let e : Short = 2; diff --git a/ets2panda/test/parser/ets/conversions-expected.txt b/ets2panda/test/parser/ets/conversions-expected.txt index de9e873fde..aa4456c66b 100644 --- a/ets2panda/test/parser/ets/conversions-expected.txt +++ b/ets2panda/test/parser/ets/conversions-expected.txt @@ -235,38 +235,8 @@ } }, "init": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 17, - "column": 19, - "program": "conversions.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "conversions.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 17, - "column": 24, - "program": "conversions.ets" - }, - "end": { - "line": 17, - "column": 28, - "program": "conversions.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/declare_enum-expected.txt b/ets2panda/test/parser/ets/declare_enum-expected.txt index ace3a9cf37..0e5f9ad815 100644 --- a/ets2panda/test/parser/ets/declare_enum-expected.txt +++ b/ets2panda/test/parser/ets/declare_enum-expected.txt @@ -177,7 +177,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/default_parameter5-expected.txt b/ets2panda/test/parser/ets/default_parameter5-expected.txt index 9ab9f2a7d4..e2e6805249 100644 --- a/ets2panda/test/parser/ets/default_parameter5-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter5-expected.txt @@ -861,7 +861,7 @@ "loc": { "start": { "line": 23, - "column": 12, + "column": 17, "program": "default_parameter5.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/default_parameter8-expected.txt b/ets2panda/test/parser/ets/default_parameter8-expected.txt index ec5ead42f2..3a65cce5fb 100644 --- a/ets2panda/test/parser/ets/default_parameter8-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter8-expected.txt @@ -709,38 +709,8 @@ } }, "alternate": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 99, - "loc": { - "start": { - "line": 21, - "column": 30, - "program": "default_parameter8.ets" - }, - "end": { - "line": 21, - "column": 32, - "program": "default_parameter8.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 21, - "column": 24, - "program": "default_parameter8.ets" - }, - "end": { - "line": 21, - "column": 27, - "program": "default_parameter8.ets" - } - } - }, + "type": "NumberLiteral", + "value": 99, "loc": { "start": { "line": 1, diff --git a/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt b/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt index 190b9c3fe6..ca48d97c20 100644 --- a/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt @@ -558,70 +558,8 @@ } }, "alternate": { - "type": "TSAsExpression", - "expression": { - "type": "StringLiteral", - "value": "default", - "loc": { - "start": { - "line": 16, - "column": 38, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 47, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 29, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 35, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 29, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 37, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 29, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 37, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, + "type": "StringLiteral", + "value": "default", "loc": { "start": { "line": 1, @@ -814,70 +752,8 @@ } }, "alternate": { - "type": "TSAsExpression", - "expression": { - "type": "StringLiteral", - "value": "another", - "loc": { - "start": { - "line": 16, - "column": 61, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 70, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 52, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 58, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 52, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 60, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 52, - "program": "default_parameter_implicitly_typed_return_void.ets" - }, - "end": { - "line": 16, - "column": 60, - "program": "default_parameter_implicitly_typed_return_void.ets" - } - } - }, + "type": "StringLiteral", + "value": "another", "loc": { "start": { "line": 1, diff --git a/ets2panda/test/parser/ets/field_decl-expected.txt b/ets2panda/test/parser/ets/field_decl-expected.txt index 0ac292d2ba..689727a8d8 100644 --- a/ets2panda/test/parser/ets/field_decl-expected.txt +++ b/ets2panda/test/parser/ets/field_decl-expected.txt @@ -416,7 +416,7 @@ }, "end": { "line": 23, - "column": 38, + "column": 39, "program": "field_decl.ets" } } @@ -452,7 +452,7 @@ }, "end": { "line": 23, - "column": 38, + "column": 39, "program": "field_decl.ets" } } diff --git a/ets2panda/test/parser/ets/field_decl.ets b/ets2panda/test/parser/ets/field_decl.ets index 68d3688c7d..2a2d52b1a4 100644 --- a/ets2panda/test/parser/ets/field_decl.ets +++ b/ets2panda/test/parser/ets/field_decl.ets @@ -20,7 +20,7 @@ export class field_decl { public d : boolean = true; f : short ; static g : long ; - static readonly pi : float = 3.14; + static readonly pi : float = 3.14f; public static readonly e : double = 2.71828; private readonly h : byte = 2; } diff --git a/ets2panda/test/parser/ets/float_pont_format_2-expected.txt b/ets2panda/test/parser/ets/float_pont_format_2-expected.txt index 850d7b2cc2..bec8dfd030 100644 --- a/ets2panda/test/parser/ets/float_pont_format_2-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_2-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_2.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_2.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_2.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_2.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_3-expected.txt b/ets2panda/test/parser/ets/float_pont_format_3-expected.txt index 21d98fea12..7ed81174d5 100644 --- a/ets2panda/test/parser/ets/float_pont_format_3-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_3-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 1.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_3.ets" - }, - "end": { - "line": 17, - "column": 16, - "program": "float_pont_format_3.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 19, - "program": "float_pont_format_3.ets" - }, - "end": { - "line": 17, - "column": 21, - "program": "float_pont_format_3.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_4-expected.txt b/ets2panda/test/parser/ets/float_pont_format_4-expected.txt index db9f5816e9..d6d8338179 100644 --- a/ets2panda/test/parser/ets/float_pont_format_4-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_4-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_4.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_4.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 1.5, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_4.ets" - }, - "end": { - "line": 17, - "column": 21, - "program": "float_pont_format_4.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_5-expected.txt b/ets2panda/test/parser/ets/float_pont_format_5-expected.txt index 5624b9cbb9..4913b2533c 100644 --- a/ets2panda/test/parser/ets/float_pont_format_5-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_5-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 1.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_5.ets" - }, - "end": { - "line": 17, - "column": 16, - "program": "float_pont_format_5.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 19, - "program": "float_pont_format_5.ets" - }, - "end": { - "line": 17, - "column": 21, - "program": "float_pont_format_5.ets" - } - } - }, + "type": "NumberLiteral", + "value": 3, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_6-expected.txt b/ets2panda/test/parser/ets/float_pont_format_6-expected.txt index 3a786d9c44..0fafd5d120 100644 --- a/ets2panda/test/parser/ets/float_pont_format_6-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_6-expected.txt @@ -205,40 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_6.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_6.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_6.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_6.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_pont_format_7-expected.txt b/ets2panda/test/parser/ets/float_pont_format_7-expected.txt index a913834768..99931a57f0 100644 --- a/ets2panda/test/parser/ets/float_pont_format_7-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_7-expected.txt @@ -205,172 +205,12 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.7, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_7.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.4, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 25, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 29, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 31, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 17, - "column": 34, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 36, - "program": "float_pont_format_7.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 28, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "float_pont_format_7.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "float_pont_format_7.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 40, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_7.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_7.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_7.ets" - } - } - }, + "type": "NumberLiteral", + "value": 1.2, "loc": { "start": { "line": 17, - "column": 13, + "column": 18, "program": "float_pont_format_7.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/float_pont_format_8-expected.txt b/ets2panda/test/parser/ets/float_pont_format_8-expected.txt index f492de68b9..034dfbfa3c 100644 --- a/ets2panda/test/parser/ets/float_pont_format_8-expected.txt +++ b/ets2panda/test/parser/ets/float_pont_format_8-expected.txt @@ -205,552 +205,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 15, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.7, - "loc": { - "start": { - "line": 17, - "column": 18, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.4, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 25, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 29, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 31, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 17, - "column": 34, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 36, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 28, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 40, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 42, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "BinaryExpression", - "operator": "-", - "left": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 47, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 49, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.7, - "loc": { - "start": { - "line": 17, - "column": 52, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 54, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 47, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 54, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.4, - "loc": { - "start": { - "line": 17, - "column": 57, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 59, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 63, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 65, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 17, - "column": 68, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 70, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 62, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 71, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 57, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 71, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 74, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 76, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 57, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 76, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 46, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 77, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.5, - "loc": { - "start": { - "line": 17, - "column": 80, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 82, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 46, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 82, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.7, - "loc": { - "start": { - "line": 17, - "column": 85, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 87, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 46, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 87, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "%", - "left": { - "type": "BinaryExpression", - "operator": "*", - "left": { - "type": "NumberLiteral", - "value": 0.4, - "loc": { - "start": { - "line": 17, - "column": 90, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 92, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 96, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 98, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.1, - "loc": { - "start": { - "line": 17, - "column": 101, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 103, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 95, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 104, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 90, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 104, - "program": "float_pont_format_8.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0.2, - "loc": { - "start": { - "line": 17, - "column": 107, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 109, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 90, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 109, - "program": "float_pont_format_8.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 45, - "program": "float_pont_format_8.ets" - }, - "end": { - "line": 17, - "column": 110, - "program": "float_pont_format_8.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2.5, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/float_separator_1-expected.txt b/ets2panda/test/parser/ets/float_separator_1-expected.txt index 6457c93362..f90de87c9c 100644 --- a/ets2panda/test/parser/ets/float_separator_1-expected.txt +++ b/ets2panda/test/parser/ets/float_separator_1-expected.txt @@ -230,7 +230,7 @@ }, "end": { "line": 17, - "column": 38, + "column": 39, "program": "float_separator_1.ets" } } @@ -243,7 +243,7 @@ }, "end": { "line": 17, - "column": 38, + "column": 39, "program": "float_separator_1.ets" } } @@ -258,7 +258,7 @@ }, "end": { "line": 17, - "column": 38, + "column": 39, "program": "float_separator_1.ets" } } diff --git a/ets2panda/test/parser/ets/float_separator_1.ets b/ets2panda/test/parser/ets/float_separator_1.ets index 419d60864d..568ef176d8 100644 --- a/ets2panda/test/parser/ets/float_separator_1.ets +++ b/ets2panda/test/parser/ets/float_separator_1.ets @@ -14,5 +14,5 @@ */ function main() { - let a: float = -0.0e2_147_483_647 + let a: float = -0.0e2_147_483_647f } diff --git a/ets2panda/test/parser/ets/for_with_break-expected.txt b/ets2panda/test/parser/ets/for_with_break-expected.txt index 25c3039b12..257f20e53e 100644 --- a/ets2panda/test/parser/ets/for_with_break-expected.txt +++ b/ets2panda/test/parser/ets/for_with_break-expected.txt @@ -505,7 +505,7 @@ "loc": { "start": { "line": 19, - "column": 13, + "column": 17, "program": "for_with_break.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/forofUnboxing-expected.txt b/ets2panda/test/parser/ets/forofUnboxing-expected.txt index 10cc306b5c..7efc172b3f 100644 --- a/ets2panda/test/parser/ets/forofUnboxing-expected.txt +++ b/ets2panda/test/parser/ets/forofUnboxing-expected.txt @@ -450,38 +450,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 10, - "loc": { - "start": { - "line": 18, - "column": 33, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 35, - "program": "forofUnboxing.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 39, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 43, - "program": "forofUnboxing.ets" - } - } - }, + "type": "NumberLiteral", + "value": 10, "loc": { "start": { "line": 18, @@ -560,38 +530,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 12, - "loc": { - "start": { - "line": 18, - "column": 55, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 57, - "program": "forofUnboxing.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 61, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 65, - "program": "forofUnboxing.ets" - } - } - }, + "type": "NumberLiteral", + "value": 12, "loc": { "start": { "line": 18, @@ -670,38 +610,8 @@ }, "arguments": [ { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 33, - "loc": { - "start": { - "line": 18, - "column": 77, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 79, - "program": "forofUnboxing.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 18, - "column": 83, - "program": "forofUnboxing.ets" - }, - "end": { - "line": 18, - "column": 87, - "program": "forofUnboxing.ets" - } - } - }, + "type": "NumberLiteral", + "value": 33, "loc": { "start": { "line": 18, diff --git a/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt index 4714961b87..dd55942add 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type8-expected.txt @@ -1286,7 +1286,7 @@ "loc": { "start": { "line": 39, - "column": 15, + "column": 24, "program": "function_implicit_return_type8.ets" }, "end": { @@ -1451,7 +1451,7 @@ "loc": { "start": { "line": 40, - "column": 15, + "column": 24, "program": "function_implicit_return_type8.ets" }, "end": { @@ -1616,7 +1616,7 @@ "loc": { "start": { "line": 41, - "column": 15, + "column": 24, "program": "function_implicit_return_type8.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt b/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt index b9502a4e99..3355f5dd6d 100644 --- a/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt +++ b/ets2panda/test/parser/ets/function_implicit_return_type9-expected.txt @@ -1673,7 +1673,7 @@ "loc": { "start": { "line": 43, - "column": 15, + "column": 24, "program": "function_implicit_return_type9.ets" }, "end": { @@ -1838,7 +1838,7 @@ "loc": { "start": { "line": 44, - "column": 15, + "column": 24, "program": "function_implicit_return_type9.ets" }, "end": { @@ -2003,7 +2003,7 @@ "loc": { "start": { "line": 45, - "column": 15, + "column": 24, "program": "function_implicit_return_type9.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt index 0f0b798931..c73c634d4e 100644 --- a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2-expected.txt @@ -696,7 +696,7 @@ }, "end": { "line": 16, - "column": 32, + "column": 33, "program": "imported_module_2.ets" } } @@ -732,7 +732,7 @@ }, "end": { "line": 16, - "column": 32, + "column": 33, "program": "imported_module_2.ets" } } diff --git a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets index b5508f11e4..cfbfbd87ed 100644 --- a/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets +++ b/ets2panda/test/parser/ets/import_tests/import_name_conflicts/imported_module_2.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -export const flt: float = 2.345; +export const flt: float = 2.345f; export let c: int = 3; diff --git a/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt index b200321200..f72675996e 100755 --- a/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/package_module_1-expected.txt @@ -698,7 +698,7 @@ }, "end": { "line": 18, - "column": 33, + "column": 34, "program": "package_module_2.ets" } } @@ -734,7 +734,7 @@ }, "end": { "line": 18, - "column": 33, + "column": 34, "program": "package_module_2.ets" } } diff --git a/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt b/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt index b1d61276d9..c746d9151e 100755 --- a/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt +++ b/ets2panda/test/parser/ets/import_tests/packages/package_module_2-expected.txt @@ -224,7 +224,7 @@ }, "end": { "line": 18, - "column": 33, + "column": 34, "program": "package_module_2.ets" } } @@ -260,7 +260,7 @@ }, "end": { "line": 18, - "column": 33, + "column": 34, "program": "package_module_2.ets" } } @@ -295,7 +295,7 @@ }, "end": { "line": 18, - "column": 34, + "column": 35, "program": "package_module_1.ets" } } @@ -331,7 +331,7 @@ }, "end": { "line": 18, - "column": 34, + "column": 35, "program": "package_module_1.ets" } } diff --git a/ets2panda/test/parser/ets/import_tests/packages/package_module_2.ets b/ets2panda/test/parser/ets/import_tests/packages/package_module_2.ets index d7cfbc6715..4b828a1d6b 100644 --- a/ets2panda/test/parser/ets/import_tests/packages/package_module_2.ets +++ b/ets2panda/test/parser/ets/import_tests/packages/package_module_2.ets @@ -15,4 +15,4 @@ package import_tests.packages; -export const flt: float = 1.2345; +export const flt: float = 1.2345f; diff --git a/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt b/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt index 4c37f7a531..5773b160e0 100644 --- a/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledDoWhileStatement-expected.txt @@ -530,7 +530,7 @@ "loc": { "start": { "line": 22, - "column": 9, + "column": 13, "program": "labeledDoWhileStatement.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/labeledForStatement-expected.txt b/ets2panda/test/parser/ets/labeledForStatement-expected.txt index bb8876b63c..440198edf0 100644 --- a/ets2panda/test/parser/ets/labeledForStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledForStatement-expected.txt @@ -1111,7 +1111,7 @@ "loc": { "start": { "line": 29, - "column": 11, + "column": 15, "program": "labeledForStatement.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt b/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt index a5074ba198..cefec5d022 100644 --- a/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt +++ b/ets2panda/test/parser/ets/labeledWhileStatement-expected.txt @@ -647,7 +647,7 @@ "loc": { "start": { "line": 23, - "column": 9, + "column": 13, "program": "labeledWhileStatement.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt index 59c102cdb8..3e4cc5e503 100644 --- a/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt +++ b/ets2panda/test/parser/ets/lambda-type-inference-overloaded-expected.txt @@ -1643,6 +1643,5 @@ } } } -TypeError: Reference to foo is ambiguous [lambda-type-inference-overloaded.ets:28:5] TypeError: The type of parameter 'x' cannot be inferred [lambda-type-inference-overloaded.ets:31:10] TypeError: The type of parameter 'y' cannot be inferred [lambda-type-inference-overloaded.ets:31:13] diff --git a/ets2panda/test/parser/ets/null_valid-expected.txt b/ets2panda/test/parser/ets/null_valid-expected.txt index f4d0b80cdb..673f3a347a 100644 --- a/ets2panda/test/parser/ets/null_valid-expected.txt +++ b/ets2panda/test/parser/ets/null_valid-expected.txt @@ -205,9 +205,8 @@ } }, "right": { - "type": "Identifier", - "name": "n", - "decorators": [], + "type": "NullLiteral", + "value": null, "loc": { "start": { "line": 17, diff --git a/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt b/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt index 06f443f4b1..04752bd0e5 100644 --- a/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt +++ b/ets2panda/test/parser/ets/parentheses_expression_value-expected.txt @@ -794,7 +794,7 @@ "loc": { "start": { "line": 22, - "column": 7, + "column": 12, "program": "parentheses_expression_value.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/rest_parameter_02-expected.txt b/ets2panda/test/parser/ets/rest_parameter_02-expected.txt index 6d7657dd10..a1d39957a7 100644 --- a/ets2panda/test/parser/ets/rest_parameter_02-expected.txt +++ b/ets2panda/test/parser/ets/rest_parameter_02-expected.txt @@ -864,38 +864,8 @@ } }, "alternate": { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 20, - "column": 40, - "program": "rest_parameter_02.ets" - }, - "end": { - "line": 20, - "column": 41, - "program": "rest_parameter_02.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 20, - "column": 34, - "program": "rest_parameter_02.ets" - }, - "end": { - "line": 20, - "column": 37, - "program": "rest_parameter_02.ets" - } - } - }, + "type": "NumberLiteral", + "value": 0, "loc": { "start": { "line": 1, diff --git a/ets2panda/test/parser/ets/rethrow-func-1-expected.txt b/ets2panda/test/parser/ets/rethrow-func-1-expected.txt index 76388e85f7..74a8f4c9f1 100644 --- a/ets2panda/test/parser/ets/rethrow-func-1-expected.txt +++ b/ets2panda/test/parser/ets/rethrow-func-1-expected.txt @@ -817,40 +817,8 @@ } }, "init": { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 1, - "loc": { - "start": { - "line": 26, - "column": 17, - "program": "rethrow-func-1.ets" - }, - "end": { - "line": 26, - "column": 18, - "program": "rethrow-func-1.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 26, - "column": 21, - "program": "rethrow-func-1.ets" - }, - "end": { - "line": 26, - "column": 22, - "program": "rethrow-func-1.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2147483647, "loc": { "start": { "line": 26, @@ -1307,3 +1275,4 @@ } } } +SyntaxError: Division by zero are not allowed. [rethrow-func-1.ets:26:17] diff --git a/ets2panda/test/parser/ets/string_template_1-expected.txt b/ets2panda/test/parser/ets/string_template_1-expected.txt index 2de1927709..40bc249bce 100644 --- a/ets2panda/test/parser/ets/string_template_1-expected.txt +++ b/ets2panda/test/parser/ets/string_template_1-expected.txt @@ -428,7 +428,7 @@ "loc": { "start": { "line": 20, - "column": 11, + "column": 20, "program": "string_template_1.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/string_template_2-expected.txt b/ets2panda/test/parser/ets/string_template_2-expected.txt index 2574c1b4a2..df3eabfe91 100644 --- a/ets2panda/test/parser/ets/string_template_2-expected.txt +++ b/ets2panda/test/parser/ets/string_template_2-expected.txt @@ -205,97 +205,8 @@ } }, "init": { - "type": "TemplateLiteral", - "expressions": [ - { - "type": "BinaryExpression", - "operator": "/", - "left": { - "type": "NumberLiteral", - "value": 14, - "loc": { - "start": { - "line": 17, - "column": 47, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 49, - "program": "string_template_2.ets" - } - } - }, - "right": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 17, - "column": 50, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 51, - "program": "string_template_2.ets" - } - } - }, - "loc": { - "start": { - "line": 17, - "column": 47, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 51, - "program": "string_template_2.ets" - } - } - } - ], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "(escaped expression) \${14/2} = ", - "cooked": "(escaped expression) ${14/2} = " - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 45, - "program": "string_template_2.ets" - } - } - }, - { - "type": "TemplateElement", - "value": { - "raw": "", - "cooked": "" - }, - "loc": { - "start": { - "line": 17, - "column": 52, - "program": "string_template_2.ets" - }, - "end": { - "line": 17, - "column": 52, - "program": "string_template_2.ets" - } - } - } - ], + "type": "StringLiteral", + "value": "(escaped expression) ${14/2} = 7", "loc": { "start": { "line": 17, @@ -394,9 +305,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "(escaped expression) ${14/2} = 7", "loc": { "start": { "line": 18, @@ -527,9 +437,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "(escaped expression) ${14/2} = 7", "loc": { "start": { "line": 20, @@ -544,9 +453,8 @@ } }, { - "type": "Identifier", - "name": "expected", - "decorators": [], + "type": "StringLiteral", + "value": "(escaped expression) ${14/2} = 7", "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/string_template_3-expected.txt b/ets2panda/test/parser/ets/string_template_3-expected.txt index b0c8377dd3..ea684bd5fe 100644 --- a/ets2panda/test/parser/ets/string_template_3-expected.txt +++ b/ets2panda/test/parser/ets/string_template_3-expected.txt @@ -205,29 +205,8 @@ } }, "init": { - "type": "TemplateLiteral", - "expressions": [], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "(slash at curly braces) $\{true || false\}", - "cooked": "(slash at curly braces) ${true || false}" - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "string_template_3.ets" - }, - "end": { - "line": 17, - "column": 55, - "program": "string_template_3.ets" - } - } - } - ], + "type": "StringLiteral", + "value": "(slash at curly braces) ${true || false}", "loc": { "start": { "line": 17, @@ -326,9 +305,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "(slash at curly braces) ${true || false}", "loc": { "start": { "line": 18, @@ -393,97 +371,8 @@ } }, "init": { - "type": "TemplateLiteral", - "expressions": [ - { - "type": "LogicalExpression", - "operator": "||", - "left": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 19, - "column": 46, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 50, - "program": "string_template_3.ets" - } - } - }, - "right": { - "type": "BooleanLiteral", - "value": false, - "loc": { - "start": { - "line": 19, - "column": 54, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 59, - "program": "string_template_3.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 46, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 59, - "program": "string_template_3.ets" - } - } - } - ], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "(slash at curly braces) ", - "cooked": "(slash at curly braces) " - }, - "loc": { - "start": { - "line": 19, - "column": 20, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 44, - "program": "string_template_3.ets" - } - } - }, - { - "type": "TemplateElement", - "value": { - "raw": "", - "cooked": "" - }, - "loc": { - "start": { - "line": 19, - "column": 60, - "program": "string_template_3.ets" - }, - "end": { - "line": 19, - "column": 60, - "program": "string_template_3.ets" - } - } - } - ], + "type": "StringLiteral", + "value": "(slash at curly braces) true", "loc": { "start": { "line": 19, @@ -548,9 +437,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "(slash at curly braces) ${true || false}", "loc": { "start": { "line": 20, @@ -565,9 +453,8 @@ } }, { - "type": "Identifier", - "name": "expected", - "decorators": [], + "type": "StringLiteral", + "value": "(slash at curly braces) true", "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/string_template_4-expected.txt b/ets2panda/test/parser/ets/string_template_4-expected.txt index 17b8cf3405..da47a2a4c0 100644 --- a/ets2panda/test/parser/ets/string_template_4-expected.txt +++ b/ets2panda/test/parser/ets/string_template_4-expected.txt @@ -205,86 +205,8 @@ } }, "init": { - "type": "TemplateLiteral", - "expressions": [ - { - "type": "TemplateLiteral", - "expressions": [], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "backtick = \`", - "cooked": "backtick = `" - }, - "loc": { - "start": { - "line": 17, - "column": 23, - "program": "string_template_4.ets" - }, - "end": { - "line": 17, - "column": 36, - "program": "string_template_4.ets" - } - } - } - ], - "loc": { - "start": { - "line": 17, - "column": 22, - "program": "string_template_4.ets" - }, - "end": { - "line": 17, - "column": 37, - "program": "string_template_4.ets" - } - } - } - ], - "quasis": [ - { - "type": "TemplateElement", - "value": { - "raw": "nested ", - "cooked": "nested " - }, - "loc": { - "start": { - "line": 17, - "column": 13, - "program": "string_template_4.ets" - }, - "end": { - "line": 17, - "column": 20, - "program": "string_template_4.ets" - } - } - }, - { - "type": "TemplateElement", - "value": { - "raw": "", - "cooked": "" - }, - "loc": { - "start": { - "line": 17, - "column": 38, - "program": "string_template_4.ets" - }, - "end": { - "line": 17, - "column": 38, - "program": "string_template_4.ets" - } - } - } - ], + "type": "StringLiteral", + "value": "nested backtick = `", "loc": { "start": { "line": 17, @@ -383,9 +305,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "nested backtick = `", "loc": { "start": { "line": 18, @@ -516,9 +437,8 @@ }, "arguments": [ { - "type": "Identifier", - "name": "v", - "decorators": [], + "type": "StringLiteral", + "value": "nested backtick = `", "loc": { "start": { "line": 20, @@ -533,9 +453,8 @@ } }, { - "type": "Identifier", - "name": "expected", - "decorators": [], + "type": "StringLiteral", + "value": "nested backtick = `", "loc": { "start": { "line": 20, diff --git a/ets2panda/test/parser/ets/switch2-expected.txt b/ets2panda/test/parser/ets/switch2-expected.txt index f2edf57641..4e12dd2d58 100644 --- a/ets2panda/test/parser/ets/switch2-expected.txt +++ b/ets2panda/test/parser/ets/switch2-expected.txt @@ -829,3 +829,6 @@ } } } +TypeError: Switch case type 'int' is not comparable to discriminant type 'byte' [switch2.ets:21:8] +TypeError: Switch case type 'int' is not comparable to discriminant type 'byte' [switch2.ets:22:8] +TypeError: Switch case type 'int' is not comparable to discriminant type 'byte' [switch2.ets:25:8] diff --git a/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt b/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt index dd1cbe89ce..d1aa6c5581 100644 --- a/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt +++ b/ets2panda/test/parser/ets/switch_char_compare_num-expected.txt @@ -476,3 +476,4 @@ } } } +TypeError: Switch case type 'int' is not comparable to discriminant type 'char' [switch_char_compare_num.ets:21:14] diff --git a/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt b/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt index 5d62c072a3..e8d302aebc 100644 --- a/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt +++ b/ets2panda/test/parser/ets/switch_enum_string_case-expected.txt @@ -315,7 +315,7 @@ } }, "kind": "constructor", - "accessibility": "public", + "accessibility": "private", "static": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member-expected.txt index c9dceaf4f6..ab089826db 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member-expected.txt @@ -693,43 +693,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Fgr", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 14, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 27, - "column": 17, - "program": "switch_readonly_member.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 18, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 27, - "column": 20, - "program": "switch_readonly_member.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "{", "loc": { "start": { "line": 27, @@ -777,43 +742,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Sqr", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 14, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 29, - "column": 17, - "program": "switch_readonly_member.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 18, - "program": "switch_readonly_member.ets" - }, - "end": { - "line": 29, - "column": 20, - "program": "switch_readonly_member.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "[", "loc": { "start": { "line": 29, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt index f8f43cea1a..fd21a4ff30 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt @@ -693,43 +693,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Fgr", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 14, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 27, - "column": 17, - "program": "switch_readonly_member_compare_char.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 27, - "column": 18, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 27, - "column": 20, - "program": "switch_readonly_member_compare_char.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "{", "loc": { "start": { "line": 27, @@ -777,43 +742,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Sqr", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 14, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 29, - "column": 17, - "program": "switch_readonly_member_compare_char.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 18, - "program": "switch_readonly_member_compare_char.ets" - }, - "end": { - "line": 29, - "column": 20, - "program": "switch_readonly_member_compare_char.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "[", "loc": { "start": { "line": 29, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt index e6f846ba4c..d9d12a2ab7 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt @@ -742,43 +742,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Fgr", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 14, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 29, - "column": 17, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 18, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 29, - "column": 20, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "{", "loc": { "start": { "line": 29, @@ -826,43 +791,8 @@ { "type": "SwitchCase", "test": { - "type": "MemberExpression", - "object": { - "type": "Identifier", - "name": "Sqr", - "decorators": [], - "loc": { - "start": { - "line": 31, - "column": 14, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 31, - "column": 17, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - }, - "property": { - "type": "Identifier", - "name": "BR", - "decorators": [], - "loc": { - "start": { - "line": 31, - "column": 18, - "program": "switch_readonly_member_compare_char_2.ets" - }, - "end": { - "line": 31, - "column": 20, - "program": "switch_readonly_member_compare_char_2.ets" - } - } - }, - "computed": false, - "optional": false, + "type": "CharLiteral", + "value": "[", "loc": { "start": { "line": 31, diff --git a/ets2panda/test/parser/ets/test_type_alias6-expected.txt b/ets2panda/test/parser/ets/test_type_alias6-expected.txt index 3107be32be..3714ac94d3 100644 --- a/ets2panda/test/parser/ets/test_type_alias6-expected.txt +++ b/ets2panda/test/parser/ets/test_type_alias6-expected.txt @@ -447,4 +447,4 @@ } TypeError: Variable 'x' has already been declared. [test_type_alias6.ets:17:5] TypeError: Type name 'x' used in the wrong context [test_type_alias6.ets:17:5] -TypeError: Type 'double' cannot be assigned to type 'int' [test_type_alias6.ets:17:9] +TypeError: Type 'Double' cannot be assigned to type 'Int' [test_type_alias6.ets:17:9] diff --git a/ets2panda/test/parser/ets/this_cmp_object-expected.txt b/ets2panda/test/parser/ets/this_cmp_object-expected.txt index 68323c16cd..d770e9b0ce 100644 --- a/ets2panda/test/parser/ets/this_cmp_object-expected.txt +++ b/ets2panda/test/parser/ets/this_cmp_object-expected.txt @@ -161,53 +161,7 @@ } }, "init": { - "type": "ConditionalExpression", - "test": { - "type": "BooleanLiteral", - "value": true, - "loc": { - "start": { - "line": 18, - "column": 26, - "program": "this_cmp_object.ets" - }, - "end": { - "line": 18, - "column": 30, - "program": "this_cmp_object.ets" - } - } - }, - "consequent": { - "type": "ThisExpression", - "loc": { - "start": { - "line": 18, - "column": 33, - "program": "this_cmp_object.ets" - }, - "end": { - "line": 18, - "column": 37, - "program": "this_cmp_object.ets" - } - } - }, - "alternate": { - "type": "ThisExpression", - "loc": { - "start": { - "line": 18, - "column": 40, - "program": "this_cmp_object.ets" - }, - "end": { - "line": 18, - "column": 44, - "program": "this_cmp_object.ets" - } - } - }, + "type": "ThisExpression", "loc": { "start": { "line": 18, @@ -353,7 +307,7 @@ "loc": { "start": { "line": 19, - "column": 12, + "column": 20, "program": "this_cmp_object.ets" }, "end": { diff --git a/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt index f72997ce91..6934a43364 100644 --- a/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt +++ b/ets2panda/test/parser/ets/tupleIndexWithNumbers-expected.txt @@ -574,9 +574,8 @@ } }, "property": { - "type": "Identifier", - "name": "index1", - "decorators": [], + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 21, @@ -672,9 +671,8 @@ } }, "property": { - "type": "Identifier", - "name": "index2", - "decorators": [], + "type": "NumberLiteral", + "value": 1, "loc": { "start": { "line": 22, diff --git a/ets2panda/test/parser/ets/tuple_type_1-expected.txt b/ets2panda/test/parser/ets/tuple_type_1-expected.txt index 753dcbb963..5cfa191987 100644 --- a/ets2panda/test/parser/ets/tuple_type_1-expected.txt +++ b/ets2panda/test/parser/ets/tuple_type_1-expected.txt @@ -560,38 +560,8 @@ } }, { - "type": "TSAsExpression", - "expression": { - "type": "NumberLiteral", - "value": 2, - "loc": { - "start": { - "line": 23, - "column": 31, - "program": "tuple_type_1.ets" - }, - "end": { - "line": 23, - "column": 32, - "program": "tuple_type_1.ets" - } - } - }, - "typeAnnotation": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 23, - "column": 36, - "program": "tuple_type_1.ets" - }, - "end": { - "line": 23, - "column": 42, - "program": "tuple_type_1.ets" - } - } - }, + "type": "NumberLiteral", + "value": 2, "loc": { "start": { "line": 23, diff --git a/ets2panda/test/parser/ets/unary_op-expected.txt b/ets2panda/test/parser/ets/unary_op-expected.txt index 10516d0b64..6671ec78a8 100644 --- a/ets2panda/test/parser/ets/unary_op-expected.txt +++ b/ets2panda/test/parser/ets/unary_op-expected.txt @@ -433,25 +433,8 @@ } }, "right": { - "type": "UnaryExpression", - "operator": "+", - "prefix": true, - "argument": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 19, - "column": 10, - "program": "unary_op.ets" - }, - "end": { - "line": 19, - "column": 11, - "program": "unary_op.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 19, @@ -824,26 +807,8 @@ } }, "right": { - "type": "UnaryExpression", - "operator": "!", - "prefix": true, - "argument": { - "type": "Identifier", - "name": "i", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "unary_op.ets" - }, - "end": { - "line": 25, - "column": 11, - "program": "unary_op.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 25, @@ -1162,25 +1127,8 @@ } }, "value": { - "type": "UnaryExpression", - "operator": "+", - "prefix": true, - "argument": { - "type": "NumberLiteral", - "value": 5, - "loc": { - "start": { - "line": 19, - "column": 10, - "program": "unary_op.ets" - }, - "end": { - "line": 19, - "column": 11, - "program": "unary_op.ets" - } - } - }, + "type": "NumberLiteral", + "value": 5, "loc": { "start": { "line": 19, @@ -1569,26 +1517,8 @@ } }, "value": { - "type": "UnaryExpression", - "operator": "!", - "prefix": true, - "argument": { - "type": "Identifier", - "name": "i", - "decorators": [], - "loc": { - "start": { - "line": 25, - "column": 10, - "program": "unary_op.ets" - }, - "end": { - "line": 25, - "column": 11, - "program": "unary_op.ets" - } - } - }, + "type": "BooleanLiteral", + "value": false, "loc": { "start": { "line": 25, diff --git a/ets2panda/test/parser/ets/var_declare-expected.txt b/ets2panda/test/parser/ets/var_declare-expected.txt index e6c6ab3282..7b2fb7d830 100644 --- a/ets2panda/test/parser/ets/var_declare-expected.txt +++ b/ets2panda/test/parser/ets/var_declare-expected.txt @@ -560,7 +560,7 @@ }, "end": { "line": 23, - "column": 32, + "column": 33, "program": "var_declare.ets" } } @@ -573,7 +573,7 @@ }, "end": { "line": 23, - "column": 32, + "column": 33, "program": "var_declare.ets" } } @@ -588,7 +588,7 @@ }, "end": { "line": 23, - "column": 33, + "column": 34, "program": "var_declare.ets" } } diff --git a/ets2panda/test/parser/ets/var_declare.ets b/ets2panda/test/parser/ets/var_declare.ets index 224c7e55e4..56429d9472 100644 --- a/ets2panda/test/parser/ets/var_declare.ets +++ b/ets2panda/test/parser/ets/var_declare.ets @@ -20,6 +20,6 @@ class VarDeclareTest { b *= 10; let c : int , d : int = 5; const e : double = 2.781828; - const Pi : float = 3.14; + const Pi : float = 3.14f; } } diff --git a/ets2panda/test/runtime/ets/AliasPrimitive.ets b/ets2panda/test/runtime/ets/AliasPrimitive.ets index 8f1d2e43c6..92c5c3601f 100644 --- a/ets2panda/test/runtime/ets/AliasPrimitive.ets +++ b/ets2panda/test/runtime/ets/AliasPrimitive.ets @@ -16,23 +16,18 @@ type AliasPrimitive = T; type AliasAlias = AliasPrimitive; -function fn(p: double) -{ - assertEQ(p, 42) -} - function fn(p: Double) { - assertTrue(false) + assertEQ(p, 42) } function main() { - let v1 : double = new Int(42); // unboxing -> widening - fn(v1); + let v1 : double = new Int(42); // widening + fn(v1); - let v2 : AliasPrimitive = new Int(42); // unboxing -> widening - fn(v2); + let v2 : AliasPrimitive = new Int(42); // widening + fn(v2); - let v3 : AliasAlias = new Int(42); // unboxing -> widening - fn(v3); + let v3 : AliasAlias = new Int(42); // widening + fn(v3); } diff --git a/ets2panda/test/runtime/ets/ArrayLiteral.ets b/ets2panda/test/runtime/ets/ArrayLiteral.ets index a541cb9b16..138113de77 100644 --- a/ets2panda/test/runtime/ets/ArrayLiteral.ets +++ b/ets2panda/test/runtime/ets/ArrayLiteral.ets @@ -18,7 +18,7 @@ function main(): void { let b: short = 20000; let c: int = 2000000; let d: long = 200000000000; - let e: float = 2.2; + let e: float = 2.2f; let f: double = 2.2222222222; let g: double[] = [a, b, c, d, e, f]; assertEQ(g[0], 2) @@ -32,7 +32,7 @@ function main(): void { const i: short = 2; const j: int = 2; const k: long = 2; - const l: float = 2.0; + const l: float = 2.0f; const m: double = 2.0; const n: byte[] = [h, i, j, k, l, m]; assertEQ(n[0], 2) diff --git a/ets2panda/test/runtime/ets/CastPrimitive.ets b/ets2panda/test/runtime/ets/CastPrimitive.ets index 40b174bdfe..07263656da 100644 --- a/ets2panda/test/runtime/ets/CastPrimitive.ets +++ b/ets2panda/test/runtime/ets/CastPrimitive.ets @@ -30,7 +30,7 @@ function main(): void { assertEQ(a as char, c'\u0000') assertEQ(a as byte, 0) - let b : float = 70000.9921875; + let b : float = 70000.9921875f; assertEQ(b as double, 70000.9921875) assertEQ(b as long, 70000 ) // rounded, 70000 == 0x11170 assertEQ(b as int, 70000) diff --git a/ets2panda/test/runtime/ets/ConditionalExpression_01.ets b/ets2panda/test/runtime/ets/ConditionalExpression_01.ets index 9bf3f0fd14..29f8e4dde0 100644 --- a/ets2panda/test/runtime/ets/ConditionalExpression_01.ets +++ b/ets2panda/test/runtime/ets/ConditionalExpression_01.ets @@ -27,14 +27,14 @@ function main() { assertEQ(z2, 4.0) let x3 = (): int | undefined => { return 5; }(); - let y3: int = !x3 ? 3.1 : x3; - let z3: int = x3 ? x3 : 4.1; + let y3: int = !x3 ? 3.1 as int : x3; + let z3: int = x3 ? x3 : 4.1 as int; assertEQ(y3, 5) assertEQ(z3, 5) let x4 = (): int | undefined => { return undefined; }(); - let y4: int = x4 == undefined ? 3.1 : x4; - let z4: int = x4 != undefined ? x4 : 4.1; + let y4: int = x4 == undefined ? 3.1 as int : x4; + let z4: int = x4 != undefined ? x4 : 4.1 as int; assertEQ(y4, 3) assertEQ(z4, 4) } diff --git a/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets b/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets index 1b1698448d..df06bcf254 100644 --- a/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets +++ b/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets @@ -24,10 +24,6 @@ class A extends Numeric { this.value = value; } - public constructor(value: Int) { - this.value = value.intValue(); - } - public override byteValue(): byte { return this.value as byte; } diff --git a/ets2panda/test/runtime/ets/RegisterSpiller.ets b/ets2panda/test/runtime/ets/RegisterSpiller.ets index d83252e75f..3e1f984b85 100644 --- a/ets2panda/test/runtime/ets/RegisterSpiller.ets +++ b/ets2panda/test/runtime/ets/RegisterSpiller.ets @@ -28,7 +28,7 @@ function main(): void { let n2: int = 41; let n3: long = 42; - let n4: float = 43.43; + let n4: float = 43.43f; let n5: double = 44.44; let n6: double = random(); let n7: double = random() + 42; diff --git a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_1.ets b/ets2panda/test/runtime/ets/boxed_primitives_overloading.ets similarity index 60% rename from ets2panda/test/runtime/ets/most_specific_method_with_rest_param_1.ets rename to ets2panda/test/runtime/ets/boxed_primitives_overloading.ets index a12bbff686..7e71029928 100644 --- a/ets2panda/test/runtime/ets/most_specific_method_with_rest_param_1.ets +++ b/ets2panda/test/runtime/ets/boxed_primitives_overloading.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,17 +13,17 @@ * limitations under the License. */ -class C { - public met(...p: FixedArray): string { - return "nR" - } - public met(...p: FixedArray): string { - return "NR" - } +class A { + func(a: Double): String { return "of Double" } + func(a: Float): String { return "of Float" } + func(a: Int): String { return "of Int" } } -function main() { - let c: C = new C() - assertEQ(c.met(0.0), "nR") - assertEQ(c.met(new Number()), "NR") +function main(): int{ + let c1: A = new A(); + let helpbyte: Byte = new Byte(1 as byte); + if (c1.func(helpbyte) != "of Int") { + return 1; + } + return 0; } diff --git a/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets b/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets index 3f0f183b1f..0c0e95fb75 100644 --- a/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets +++ b/ets2panda/test/runtime/ets/boxingUnboxingCalls.ets @@ -17,10 +17,6 @@ function intParam(a: int): int { return 0; } -function intParam(a: Int): int { - return 1; -} - function objParam(a: Object): int { return 2; } @@ -36,14 +32,10 @@ function retInt(a: Int): int { function main(): void { let a: int = 1; let b: Int = 2; - let c: int = intParam(a); - assertEQ(c, 0) - let d: int = intParam(b); - assertEQ(d, 1) - let e: Int = intParam(a); + let c: Int = intParam(a); assertEQ(c, 0) let f: Int = intParam(b); - assertEQ(d, 1) + assertEQ(f, 0) let g: int = objParam(a); assertEQ(g, 2) let h: int = objParam(b); diff --git a/ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts b/ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts new file mode 100644 index 0000000000..5e498766bb --- /dev/null +++ b/ets2panda/test/runtime/ets/cast_boxed_primitives_invoke_context_and_unions.sts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A {} + +function foo(a: Float): Float { + return a; +} + +function main(): int { + let c: A | Double = new Double(10.0 as double); + let b: Int = new Int(9 as int); + c = b + if (c != 9) { + return 1; + } + let k: Int = new Int(10 as int); + let v: Float = foo(k) + if (v.isNaN()) { + return 1; + } + return 0; +} diff --git a/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets b/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets index 5b40ffe6e0..e316567081 100644 --- a/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets +++ b/ets2panda/test/runtime/ets/conditionalExpressionLUB.ets @@ -45,6 +45,10 @@ function foo(p: F): int { return 6; } +function getTrue(): boolean { + return true +} + // #15276 foo(Object|null) and foo(Object) overloads function foo7(p: Object | null): int { return 7; @@ -59,30 +63,30 @@ function main(): void { function sameTypeLUB(): void { let a : A = new A(); let b : A = new A(); - let c = true ? a : b; + let c = getTrue() ? a : b; assertEQ(foo(c), 2) } function objectLUB(): void { let a : A = new A(); let b : Int = 2; - let c = true ? a : b; + let c = getTrue() ? a : b; assertEQ(foo(c), 1) let arr : Int[] | null = null; - let d = true ? a : arr; + let d = getTrue() ? a : arr; assertEQ(foo7(d), 7) } function forkSubtypeLUB(): void { let a : F = new F(); let b : D = new D(); - let c = true ? a : b; + let c = getTrue() ? a : b; assertEQ(foo(c), 2) let d : A = new A(); - let e = true ? a : b; + let e = getTrue() ? a : b; assertEQ(foo(e), 2) let f : B = new B(); - let g = true ? a : f; + let g = getTrue() ? a : f; assertEQ(foo(g), 3) } diff --git a/ets2panda/test/runtime/ets/division-by-zero.ets b/ets2panda/test/runtime/ets/division-by-zero.ets index 3d774e0f85..2f06cf1157 100644 --- a/ets2panda/test/runtime/ets/division-by-zero.ets +++ b/ets2panda/test/runtime/ets/division-by-zero.ets @@ -16,34 +16,6 @@ function main() : void { let caught_counter = 0; - try { - let result : int = 1 / 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 1) - - try { - let result : long = 1 / 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 2) - - try { - let result : int = 1 % 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 3) - - try { - let result : long = 1 % 0; - } catch (error: ArithmeticError) { - caught_counter++; - } - assertEQ(caught_counter, 4) - let INT_ONE : int = 1; let INT_ZERO : int = 0; let LONG_ONE : long = 1; @@ -54,28 +26,28 @@ function main() : void { } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 5) + assertEQ(caught_counter, 1) try { let result : long = LONG_ONE / LONG_ZERO; } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 6) + assertEQ(caught_counter, 2) try { let result : int = INT_ONE % INT_ZERO; } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 7) + assertEQ(caught_counter, 3) try { let result : long = LONG_ONE % LONG_ZERO; } catch (error: ArithmeticError) { caught_counter++; } - assertEQ(caught_counter, 8) + assertEQ(caught_counter, 4) let DOUBLE_ONE : double = 1.0; let DOUBLE_ZERO : double = 0.0; diff --git a/ets2panda/test/runtime/ets/local-class-capture-boxing.ets b/ets2panda/test/runtime/ets/local-class-capture-boxing.ets index 0ddecafe02..17712173f8 100644 --- a/ets2panda/test/runtime/ets/local-class-capture-boxing.ets +++ b/ets2panda/test/runtime/ets/local-class-capture-boxing.ets @@ -56,7 +56,7 @@ class GlobalClass let l_short : short = 3; let l_int : int = 4; let l_long : long = 5; - let l_float : float = 6.0; + let l_float : float = 6.0f; let l_double : double = 7.0; let l_boolean : boolean = false; let l_char : char = c'x'; diff --git a/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets b/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets index b22d5bb64c..d06cbc640e 100644 --- a/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets +++ b/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets @@ -56,7 +56,7 @@ class GlobalClass let l_short : short = 3; let l_int : int = 4; let l_long : long = 5; - let l_float : float = 6.0; + let l_float : float = 6.0f; let l_double : double = 7.0; let l_boolean : boolean = false; let l_char : char = c'x'; diff --git a/ets2panda/test/runtime/ets/skippedTest.ets b/ets2panda/test/runtime/ets/skippedTest.ets index 436327c450..2411180ddb 100644 --- a/ets2panda/test/runtime/ets/skippedTest.ets +++ b/ets2panda/test/runtime/ets/skippedTest.ets @@ -20,7 +20,7 @@ function main(): void { let c: String = "abc"; let n2: int = 41; let n3: long = 42; - let n4: float = 43.43; + let n4: float = 43.43f; let n5: double = 44.44; console.print(str); console.println(); diff --git a/ets2panda/test/runtime/ets/tuple_types_runtime.ets b/ets2panda/test/runtime/ets/tuple_types_runtime.ets index ea92f4de2f..f787e31f4d 100644 --- a/ets2panda/test/runtime/ets/tuple_types_runtime.ets +++ b/ets2panda/test/runtime/ets/tuple_types_runtime.ets @@ -77,7 +77,7 @@ function main(): void { let tup_10: [number, int, string, boolean, Object] = [1, 2, "I", false, new Object()]; let var_float: float = tup_10[1]; - let var_float_2: float = 2.0; + let var_float_2: float = 2.0f; assertEQ(var_float, var_float_2); let tup_11: [int, number, string, boolean, Object] = [6, 7, "J", true, 789]; diff --git a/ets2panda/test/runtime/ets/visible_signatures.ets b/ets2panda/test/runtime/ets/visible_signatures.ets index a4201f3d8d..0acd2259f5 100644 --- a/ets2panda/test/runtime/ets/visible_signatures.ets +++ b/ets2panda/test/runtime/ets/visible_signatures.ets @@ -14,39 +14,37 @@ */ class A { - foo(a: Double | undefined): Int { + foo(a: Long): Int { return 1; } - private foo(a: double): Int { + private foo(a: Int): Int { return 0; } - foo2(a: Int | undefined): Int { + foo2(a: Int): Int { return 1; } - private foo2(a: int): Int { + private foo2(a: Long): Int { return 0; } - foo3(a: Number | undefined): Int { + foo3(a: Long): Int { return 1; } - private foo3(a: number): Int { + private foo3(a: Int): Int { return 0; } - - foo4(a: Number | undefined): Int { + foo4(a: Int): Int { return 1; } - protected foo4(a: number): Int { + protected foo4(a: Long): Int { return 0; } - } function main(): void { - assertEQ(new A().foo(3.0), 1) + assertEQ(new A().foo(3), 1) assertEQ(new A().foo2(3), 1) - assertEQ(new A().foo3(3.0), 1) - assertEQ(new A().foo4(3.0), 1) + assertEQ(new A().foo3(3), 1) + assertEQ(new A().foo4(3), 1) } diff --git a/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt b/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt index bb991b21cc..0c7275c719 100644 --- a/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt +++ b/ets2panda/test/test-lists/astchecker/astchecker-ets-ignored.txt @@ -108,3 +108,100 @@ ast/compiler/ets/lambda_infer_type/lambda_param_type_cannot_be_determined.ets # Issue: #24605 incorrect column ast/parser/ets/named_types_2.ets + +#24986 +ast/compiler/ets/extension_function_tests/extension_function_called_by_class.ets +ast/compiler/ets/extension_function_tests/extension_function_duplicated_with_private_field.ets +ast/compiler/ets/extension_function_tests/extension_function_primitive.ets +ast/compiler/ets/ambiguous_signature02.ets +ast/compiler/ets/import_tests/import_distant_package/package_with_errors/import_in_package_with_error.ets +ast/compiler/ets/unionCommonMember_neg.ets +ast/parser/ets/FixedArray/MultipleParserErrors.ets +ast/parser/ets/FixedArray/for_of_02.ets +ast/parser/ets/FixedArray/invalidTypes.ets +ast/parser/ets/FixedArray/unexpected_token_31.ets +ast/parser/ets/FixedArray/unexpected_token_36.ets +ast/parser/ets/FixedArray/unexpected_token_42.ets +ast/parser/ets/FixedArray/unexpected_token_47.ets +ast/parser/ets/InvalidExpressions1.ets +ast/parser/ets/MultipleParserErrors.ets +ast/parser/ets/SmartCast_1.ets +ast/parser/ets/SmartCast_2.ets +ast/parser/ets/array_new_failed.ets +ast/parser/ets/constFloatInSwitch.ets +ast/parser/ets/enum28.ets +ast/parser/ets/enum29.ets +ast/parser/ets/enum30.ets +ast/parser/ets/enum31.ets +ast/parser/ets/enum7.ets +ast/parser/ets/for_of_04.ets +ast/parser/ets/function_implicit_return_type7.ets +ast/parser/ets/import_tests/import_name_conflicts/main_2.ets +ast/parser/ets/import_tests/import_name_conflicts/main_3.ets +ast/parser/ets/import_tests/import_name_conflicts/main_4.ets +ast/parser/ets/import_tests/import_name_conflicts/main_5.ets +ast/parser/ets/import_tests/import_name_conflicts/main_6.ets +ast/parser/ets/import_tests/import_name_conflicts/main_7.ets +ast/parser/ets/import_tests/import_name_conflicts/main_8.ets +ast/parser/ets/import_tests/import_type_error_in_class.ets +ast/parser/ets/import_tests/import_type_error_top_level.ets +ast/parser/ets/index_not_support_such_type.ets +ast/parser/ets/instanceof_with_not_object_type.ets +ast/parser/ets/interface_private_function_1.ets +ast/parser/ets/invalidEnums.ets +ast/parser/ets/keyof_annotation.ets +ast/parser/ets/keyof_array_tuple.ets +ast/parser/ets/keyof_parameter.ets +ast/parser/ets/lambda_infer_type_neg_1.ets +ast/parser/ets/lambda_omit_parentheses_parameter_neg_3.ets +ast/parser/ets/multi_typeerror_function_implicit_return_value.ets +ast/parser/ets/n_arrayHoldingNullValue.ets +ast/parser/ets/new_object_1.ets +ast/parser/ets/new_object_2.ets +ast/parser/ets/nonIntegralIndex.ets +ast/parser/ets/non_proper_index_method.ets +ast/parser/ets/overrideFuncWithGetter_n.ets +ast/parser/ets/override_method.ets +ast/parser/ets/partialPrimitiveConversion_n.ets +ast/parser/ets/partial_not_reference_type.ets +ast/parser/ets/predefined_non_primitive_types.ets +ast/parser/ets/primitive_type_method_1.ets +ast/parser/ets/primitive_type_method_2.ets +ast/parser/ets/privateSuperConstructorCall.ets +ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test1.ets +ast/parser/ets/readonly-parameter-test/Readonly-with-ArrayType-test4.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test3.ets +ast/parser/ets/readonly-parameter-test/readonly-parameter-test4.ets +ast/parser/ets/recordIndexing.ets +ast/parser/ets/recordKeyTypeCheck01.ets +ast/parser/ets/record_object_value.ets +ast/parser/ets/return_null_and_type_not_match.ets +ast/parser/ets/return_type_non_match.ets +ast/parser/ets/returntype_override_primitive.ets +ast/parser/ets/single_statement_1.ets +ast/parser/ets/single_statement_2.ets +ast/parser/ets/switch_const_int_compare_char_duplicate.ets +ast/parser/ets/switch_num_compare_char_duplicate.ets +ast/parser/ets/switch_readonly_member_number_duplicate.ets +ast/parser/ets/trailing_comma_2.ets +ast/parser/ets/type_from_utility_type.ets +ast/parser/ets/type_references.ets +ast/parser/ets/types_decls.ets +ast/parser/ets/unexpected_token_29.ets +ast/parser/ets/unexpected_token_31.ets +ast/parser/ets/unexpected_token_35.ets +ast/parser/ets/unexpected_token_36.ets +ast/parser/ets/unexpected_token_41.ets +ast/parser/ets/unexpected_token_42.ets +ast/parser/ets/unexpected_token_47.ets +ast/parser/ets/unexpected_token_53.ets +ast/parser/ets/unexpected_token_55.ets +ast/parser/ets/unexpected_token_61.ets +ast/parser/ets/visible_signatures_1.ets +ast/parser/ets/wrong_context_class_1.ets +ast/parser/ets/wrong_context_class_2.ets +ast/parser/ets/wrong_context_function_1.ets +ast/parser/ets/wrong_context_function_2.ets +ast/parser/ets/FixedArray/ets_never_type_without_affect_other.ets +ast/parser/ets/ets_never_type_without_affect_other.ets +ast/parser/ets/non_constant_expression.ets diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index ed76e9c73b..2c572e87b0 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -93,5 +93,31 @@ GenericBridges_01.ets GenericBridges_02.ets override_for_partial_01.ets +# Overloads involving primitives +Override-4.ets +# 22415 +lambda_type_with_rest_param.ets +lambda_with_rest_param.ets +lambda_with_restparameter.ets +lambda_with_restparameter_object.ets +lambda_with_restparameter_predefinedtypes.ets + +# Arrays of primitives used interchangeably with arrays of reference (in generics and forOf) +ForOfUnion.ets +SpreadExpressions.ets +GenericArray_1.ets +GenericArray_2.ets +SpreadExpressions_ResizableArray.ets +array-object.ets + #HEAD FILE NO NEED TO RUN import_self_head_tests/B/test.d.ets + +#24986 +RecordKeyTypeCheck.ets +constant_char.ets +enum-initialize-with-enum1.ets +enum-initialize-with-enum2.ets +CastPrimitive.ets +nullishTypeCodesamples.ets +instanceof.ets diff --git a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt index 3f8d5be2c2..9a38c3a7f2 100644 --- a/ets2panda/test/test-lists/parser/parser-ets-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-ets-ignored.txt @@ -22,3 +22,21 @@ parser/ts/test-tuple-type.ts parser/ts/test-type-literal.ts parser/ts/test_generic.ts compiler/ts/functionCall.ts + +#24986 +compiler/ets/dynamicLambdaJSValue.ets +parser/ets/switch2.ets +parser/ets/switch_char_compare_num.ets +ark_tests/parser/js/expressions/binary/test-binary-expression.js +ark_tests/parser/js/expressions/binary/test-logical-expression.js +ark_tests/parser/js/expressions/binary/test-nullish-coalescing.js +ark_tests/parser/js/expressions/conditional/test-conditional-expression.js +ark_tests/parser/js/expressions/test-grouping-level.js +ark_tests/parser/js/functions/declarations/test-function-return.js +parser/js/test-binary-expression.js +parser/js/test-conditional-expression.js +parser/js/test-grouping-level.js +parser/js/test-logical-expression.js +parser/js/test-nullish-coalescing.js +compiler/ets/dynamic_instanceof_error.ets +parser/ets/tuple_type_1.ets diff --git a/ets2panda/test/test-lists/parser/parser-js-ignored.txt b/ets2panda/test/test-lists/parser/parser-js-ignored.txt index e69de29bb2..ebb05bf9f7 100644 --- a/ets2panda/test/test-lists/parser/parser-js-ignored.txt +++ b/ets2panda/test/test-lists/parser/parser-js-ignored.txt @@ -0,0 +1,17 @@ +#24986 +compiler/ets/dynamicLambdaJSValue.ets +parser/ets/switch2.ets +parser/ets/switch_char_compare_num.ets +ark_tests/parser/js/expressions/binary/test-binary-expression.js +ark_tests/parser/js/expressions/binary/test-logical-expression.js +ark_tests/parser/js/expressions/binary/test-nullish-coalescing.js +ark_tests/parser/js/expressions/conditional/test-conditional-expression.js +ark_tests/parser/js/expressions/test-grouping-level.js +ark_tests/parser/js/functions/declarations/test-function-return.js +parser/js/test-binary-expression.js +parser/js/test-conditional-expression.js +parser/js/test-grouping-level.js +parser/js/test-logical-expression.js +parser/js/test-nullish-coalescing.js +compiler/ets/dynamic_instanceof_error.ets +parser/ets/tuple_type_1.ets diff --git a/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp b/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp index 523d4aaba1..a1998a7aac 100644 --- a/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp +++ b/ets2panda/test/unit/annotations/mutiple_annotations_for_function.cpp @@ -91,36 +91,35 @@ public: void CheckLiteralArrayTable(pandasm::Program *program) { std::vector>> expectedLiteralArrayTable = { - {"ETSGLOBAL$Anno2$param$0", std::vector {VALUE_1, VALUE_2, VALUE_3, VALUE_4}}, - {"ETSGLOBAL$Anno3$param$1", std::vector {VALUE_1}}, - {"ETSGLOBAL$Anno3$param$2", std::vector {VALUE_2}}, + {"ETSGLOBAL$Anno2$param$0", std::vector {1U, 2U, 3U, 4U}}, + {"ETSGLOBAL$Anno3$param$1", std::vector {1U}}, + {"ETSGLOBAL$Anno3$param$2", std::vector {2U}}, {"ETSGLOBAL$Anno3$param$3", std::vector {std::string("ETSGLOBAL$Anno3$param$1"), std::string("ETSGLOBAL$Anno3$param$2")}}, - {"ETSGLOBAL$Anno3$param$4", std::vector {VALUE_2}}, - {"ETSGLOBAL$Anno3$param$5", std::vector {VALUE_3}}, + {"ETSGLOBAL$Anno3$param$4", std::vector {2U}}, + {"ETSGLOBAL$Anno3$param$5", std::vector {3U}}, {"ETSGLOBAL$Anno3$param$6", std::vector {std::string("ETSGLOBAL$Anno3$param$4"), std::string("ETSGLOBAL$Anno3$param$5")}}, - {"ETSGLOBAL$Anno3$param$7", std::vector {VALUE_3}}, - {"ETSGLOBAL$Anno3$param$8", std::vector {VALUE_4}}, + {"ETSGLOBAL$Anno3$param$7", std::vector {3U}}, + {"ETSGLOBAL$Anno3$param$8", std::vector {4U}}, {"ETSGLOBAL$Anno3$param$9", std::vector {std::string("ETSGLOBAL$Anno3$param$7"), std::string("ETSGLOBAL$Anno3$param$8")}}, {"ETSGLOBAL$Anno3$param$10", std::vector {std::string("ETSGLOBAL$Anno3$param$3"), std::string("ETSGLOBAL$Anno3$param$6"), std::string("ETSGLOBAL$Anno3$param$9")}}, - {"ETSGLOBAL.foo:void;$Anno2$value$11", - std::vector {VALUE_4, VALUE_5, VALUE_6, VALUE_7}}, - {"ETSGLOBAL.foo:void;$Anno3$param$12", std::vector {VALUE_1}}, - {"ETSGLOBAL.foo:void;$Anno3$param$13", std::vector {VALUE_2}}, + {"ETSGLOBAL.foo:void;$Anno2$value$11", std::vector {4U, 5U, 6U, 7U}}, + {"ETSGLOBAL.foo:void;$Anno3$param$12", std::vector {1U}}, + {"ETSGLOBAL.foo:void;$Anno3$param$13", std::vector {2U}}, {"ETSGLOBAL.foo:void;$Anno3$param$14", std::vector {std::string("ETSGLOBAL.foo:void;$Anno3$param$12"), std::string("ETSGLOBAL.foo:void;$Anno3$param$13")}}, - {"ETSGLOBAL.foo:void;$Anno3$param$15", std::vector {VALUE_2}}, - {"ETSGLOBAL.foo:void;$Anno3$param$16", std::vector {VALUE_3}}, + {"ETSGLOBAL.foo:void;$Anno3$param$15", std::vector {2U}}, + {"ETSGLOBAL.foo:void;$Anno3$param$16", std::vector {3U}}, {"ETSGLOBAL.foo:void;$Anno3$param$17", std::vector {std::string("ETSGLOBAL.foo:void;$Anno3$param$15"), std::string("ETSGLOBAL.foo:void;$Anno3$param$16")}}, - {"ETSGLOBAL.foo:void;$Anno3$param$18", std::vector {VALUE_3}}, - {"ETSGLOBAL.foo:void;$Anno3$param$19", std::vector {VALUE_4}}, + {"ETSGLOBAL.foo:void;$Anno3$param$18", std::vector {3U}}, + {"ETSGLOBAL.foo:void;$Anno3$param$19", std::vector {4U}}, {"ETSGLOBAL.foo:void;$Anno3$param$20", std::vector {std::string("ETSGLOBAL.foo:void;$Anno3$param$18"), std::string("ETSGLOBAL.foo:void;$Anno3$param$19")}}, diff --git a/ets2panda/test/unit/lsp/get_diagnostics.cpp b/ets2panda/test/unit/lsp/get_diagnostics.cpp index bfb46178f1..8308130c35 100644 --- a/ets2panda/test/unit/lsp/get_diagnostics.cpp +++ b/ets2panda/test/unit/lsp/get_diagnostics.cpp @@ -62,7 +62,7 @@ add("1", 2);)"); ASSERT_EQ(result.diagnostic[thirdIndex].range_.end.character_, expectedFirstEndCharacter); ASSERT_EQ(result.diagnostic[thirdIndex].severity_, DiagnosticSeverity::Error); ASSERT_EQ(std::get(result.diagnostic[thirdIndex].code_), 1); - ASSERT_EQ(result.diagnostic[thirdIndex].message_, R"(Type '"hello"' cannot be assigned to type 'double')"); + ASSERT_EQ(result.diagnostic[thirdIndex].message_, R"(Type '"hello"' cannot be assigned to type 'Double')"); ASSERT_EQ(result.diagnostic[thirdIndex].codeDescription_.href_, "test code description"); auto const expectedSecondStartLine = 5; auto const expectedSecondStartCharacter = 5; @@ -74,7 +74,7 @@ add("1", 2);)"); ASSERT_EQ(result.diagnostic[0].range_.end.character_, expectedSecondEndCharacter); ASSERT_EQ(result.diagnostic[0].severity_, DiagnosticSeverity::Error); ASSERT_EQ(std::get(result.diagnostic[0].code_), 1); - ASSERT_EQ(result.diagnostic[0].message_, R"(Type '"1"' is not compatible with type 'double' at index 1)"); + ASSERT_EQ(result.diagnostic[0].message_, R"(Type '"1"' is not compatible with type 'Double' at index 1)"); ASSERT_EQ(result.diagnostic[0].codeDescription_.href_, "test code description"); } diff --git a/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp b/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp index d4dba0a490..8d50e2ec7a 100644 --- a/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp +++ b/ets2panda/test/unit/lsp/get_type_of_symbol_at_location_test.cpp @@ -24,15 +24,17 @@ using ark::es2panda::lsp::Initializer; +static auto g_fileSource = + "let a: number;\nlet b: byte;\nlet c: short;\nlet d: int;\nlet e: long;\nlet f: " + "float;\nlet g: double;\nlet h: char;\nlet i: boolean;"; + +// CC-OFFNXT(huge_method) test function TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation1) { using ark::es2panda::ir::AstNode; using ark::es2panda::public_lib::Context; Initializer initializer = Initializer(); - es2panda_Context *ctx = - initializer.CreateContext("types.ets", ES2PANDA_STATE_CHECKED, - "let a: number;\nlet b: byte;\nlet c: short;\nlet d: int;\nlet e: long;\nlet f: " - "float;\nlet g: double;\nlet h: char;\nlet i: boolean;"); + es2panda_Context *ctx = initializer.CreateContext("types.ets", ES2PANDA_STATE_CHECKED, g_fileSource); ASSERT_EQ(ContextState(ctx), ES2PANDA_STATE_CHECKED); auto checker = reinterpret_cast(ctx)->checker->AsETSChecker(); @@ -40,47 +42,49 @@ TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation1) auto targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "a"; }); auto type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsDoubleType()); + std::cout << type->ToString() << std::endl; + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalDoubleBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "b"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsByteType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalByteBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "c"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsShortType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalShortBuiltinType())); + ; targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "d"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsIntType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalIntBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "e"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsLongType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalLongBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "f"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsFloatType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalFloatBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "g"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsDoubleType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalDoubleBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "h"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsCharType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalCharBuiltinType())); targetNode = astNode->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "i"; }); type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); - ASSERT_TRUE(type->IsETSBooleanType()); + ASSERT_TRUE(checker->Relation()->IsIdenticalTo(type, checker->GlobalETSBooleanBuiltinType())); initializer.DestroyContext(ctx); } @@ -142,4 +146,4 @@ TEST_F(LSPAPITests, GetTypeOfSymbolAtLocation2) type = ark::es2panda::lsp::GetTypeOfSymbolAtLocation(checker, targetNode); ASSERT_TRUE(type->IsETSUnionType()); initializer.DestroyContext(ctx); -} \ No newline at end of file +} diff --git a/ets2panda/test/unit/lsp/inlay_hints_test.cpp b/ets2panda/test/unit/lsp/inlay_hints_test.cpp index c9b480e473..8302541de2 100644 --- a/ets2panda/test/unit/lsp/inlay_hints_test.cpp +++ b/ets2panda/test/unit/lsp/inlay_hints_test.cpp @@ -214,7 +214,7 @@ TEST_F(LSPInlayHintsTests, VisitFunctionDeclarationLikeForReturnTypeTest1) }; )"}; - const std::string doubleString = "double"; + const std::string doubleString = "Double"; const size_t addIndex = 89; const size_t multiplyIndex = 186; const size_t i0 = 0; diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_check.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_check.cpp index ca0a1a3dad..4ad3bd24fe 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_check.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_check.cpp @@ -25,7 +25,7 @@ static es2panda_Impl *impl = nullptr; -static auto source = std::string("function main() { 1 + 2 }"); +static auto source = std::string("function main(): void { let v = 1; v + 2 }"); static es2panda_AstNode *binExpr = nullptr; static es2panda_Context *ctx = nullptr; @@ -53,7 +53,7 @@ static bool TestAstNodeCheck(es2panda_Context *context, es2panda_AstNode *root) auto *mainType = impl->AstNodeCheck(context, binExpr); std::cout << impl->TypeToStringConst(context, mainType) << std::endl; - return impl->TypeIsIntType(mainType); + return impl->TypeIsETSObjectType(mainType); // boxed Int } int main(int argc, char **argv) diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_transform_children_recursively.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_transform_children_recursively.cpp index 90bc552fa3..dd16a6fdc4 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_transform_children_recursively.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_ast_node_transform_children_recursively.cpp @@ -30,6 +30,7 @@ es2panda_AstNode *Transform(es2panda_AstNode *ast) { if (g_impl->IsIdentifier(ast) && strcmp(g_impl->IdentifierName(g_ctx, ast), "main") == 0) { auto *id = g_impl->CreateIdentifier1(g_ctx, const_cast("foo")); + g_impl->AstNodeSetParent(g_ctx, id, g_impl->AstNodeParent(g_ctx, ast)); g_isFound = true; return id; } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_as_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_as_expression.cpp index 38505a37c3..cbbd90c2a4 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_as_expression.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_as_expression.cpp @@ -125,6 +125,8 @@ void CreateAsExpression() auto typeAnnotation = impl->CreateETSPrimitiveType(context, primitiveType); auto *asExpr = impl->CreateTSAsExpression(context, numberLiteral, typeAnnotation, true); impl->VariableDeclaratorSetInit(context, variableDeclarator, asExpr); + impl->AstNodeSetParent(context, numberLiteral, asExpr); + impl->AstNodeSetParent(context, typeAnnotation, asExpr); impl->AstNodeSetParent(context, asExpr, variableDeclarator); impl->AstNodeSetParent(context, variableDeclarator, letStatement); } @@ -168,4 +170,4 @@ int main(int argc, char **argv) return 0; } -// NOLINTEND \ No newline at end of file +// NOLINTEND diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_parameter_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_parameter_expression.cpp index a7aa23aa08..53f55b343b 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_parameter_expression.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_ets_parameter_expression.cpp @@ -34,7 +34,9 @@ es2panda_AstNode *Transform(es2panda_AstNode *ast) auto *id = g_impl->CreateIdentifier2(g_ctx, const_cast("yyy"), g_impl->CreateETSPrimitiveType(g_ctx, PRIMITIVE_TYPE_INT)); auto param = g_impl->CreateETSParameterExpression(g_ctx, id, false); + g_impl->AstNodeSetParent(g_ctx, g_impl->IdentifierTypeAnnotationConst(g_ctx, id), id); g_impl->AstNodeSetParent(g_ctx, id, param); + g_impl->AstNodeSetParent(g_ctx, param, g_impl->AstNodeParent(g_ctx, ast)); g_isFound = true; return param; } diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_member_expression.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_member_expression.cpp index ba03cef15b..10774a84d5 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_member_expression.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_member_expression.cpp @@ -94,8 +94,8 @@ static es2panda_AstNode *CreateMemberExpression() { es2panda_AstNode *instanceName = CreateIdentifierFromString(context, "a"); es2panda_AstNode *memberName = CreateIdentifierFromString(context, "age"); - es2panda_AstNode *memberExpr = - impl->CreateMemberExpression(context, instanceName, memberName, MEMBER_EXPRESSION_KIND_NONE, false, false); + es2panda_AstNode *memberExpr = impl->CreateMemberExpression(context, instanceName, memberName, + MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false); impl->AstNodeSetParent(context, instanceName, memberExpr); impl->AstNodeSetParent(context, memberName, memberExpr); return memberExpr; @@ -123,8 +123,8 @@ static void CheckUpdateMemberExpression(es2panda_AstNode *programNode) { es2panda_AstNode *instanceName = CreateIdentifierFromString(context, "a"); es2panda_AstNode *memberName = CreateIdentifierFromString(context, "address"); - es2panda_AstNode *newMemberExpr = impl->UpdateMemberExpression(context, memberExpression, instanceName, memberName, - MEMBER_EXPRESSION_KIND_NONE, false, false); + es2panda_AstNode *newMemberExpr = impl->UpdateMemberExpression( + context, memberExpression, instanceName, memberName, MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false); impl->AstNodeSetParent(context, instanceName, newMemberExpr); impl->AstNodeSetParent(context, memberName, newMemberExpr); es2panda_AstNode *newMemberStat = impl->CreateExpressionStatement(context, newMemberExpr); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method.cpp index e60ad40c6a..5a0619ead0 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_this_into_method.cpp @@ -81,8 +81,8 @@ static es2panda_AstNode *CreateMemberExpression() { es2panda_AstNode *thisExpr = CreateThisExpression(); es2panda_AstNode *memberName = CreateIdentifierFromString(context, "x"); - es2panda_AstNode *memberExpr = - impl->CreateMemberExpression(context, thisExpr, memberName, MEMBER_EXPRESSION_KIND_NONE, false, false); + es2panda_AstNode *memberExpr = impl->CreateMemberExpression(context, thisExpr, memberName, + MEMBER_EXPRESSION_KIND_PROPERTY_ACCESS, false, false); impl->AstNodeSetParent(context, thisExpr, memberExpr); impl->AstNodeSetParent(context, memberName, memberExpr); return memberExpr; diff --git a/ets2panda/test/unit/rest_parameter_flag_test.cpp b/ets2panda/test/unit/rest_parameter_flag_test.cpp index 6a86bc3195..026166d78b 100644 --- a/ets2panda/test/unit/rest_parameter_flag_test.cpp +++ b/ets2panda/test/unit/rest_parameter_flag_test.cpp @@ -328,7 +328,9 @@ TEST_F(RestParameterTest, external_function_with_rest_parameter_0) TEST_F(RestParameterTest, external_function_with_rest_parameter_1) { - SetCurrentProgram(""); + SetCurrentProgram(R"( + let v = Math.max(0.0, 1.0, 2.0) // Ensure the func is actually called and reference processed by unboxLowering. + )"); CheckRestParameterFlag("escompat.Math.max:escompat.Array;f64;", true); } diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 86acf72939..5951a48707 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -915,9 +915,9 @@ semantic: id: 227 message: "Array element at index {} with type '{}' is not compatible with the target array element type '{}'" -- name: INIT_NOT_ASSIGNABLE +- name: TYPEARG_TYPEPARAM_SUBTYPING id: 228 - message: "Type {} is not assignable to constraint type {}" + message: "Type argument '{}' should be a subtype of '{}'-constraint" - name: OVERLOADED_FUNCTION_REFERENCE id: 229 @@ -1111,8 +1111,24 @@ semantic: id: 279 message: "Tuple types with arity >16 are not yet implemented" -- name: UNION_METHOD_SIGNATURE +- name: CONSTANT_FLOATING_POINT_COVERSION + id: 279 + message: "Floating-point value cannot be converted" + +- name: CONSTANT_VALUE_OUT_OF_RANGE id: 280 + message: "Value is out of range" + +- name: WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION + id: 281 + message: "Wrong type of operands for binary expression" + +- name: WRONG_OPERAND_TYPE_FOR_UNARY_EXPRESSION + id: 282 + message: "Wrong operand type for unary expression" + +- name: UNION_METHOD_SIGNATURE + id: 283 message: "Union constituent types should have only one common method signature." - name: NOT_ALLOWED_THIS_IN_UNION_TYPE diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index f8a36487ec..f9ad711efb 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -1102,7 +1102,7 @@ syntax: - name: DIVISION_BY_ZERO id: 273 - message: "Division by zero are not allowed in Enum or Annotation." + message: "Division by zero are not allowed." - name: UNSUPPORTED_OPERATOR_FOR_STRING id: 274 diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index e7204d2d33..9a1d19e418 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -16,8 +16,11 @@ #include "helpers.h" #include +#include "checker/ETSchecker.h" + #include "parser/program/program.h" #include "varbinder/privateBinding.h" +#include "varbinder/ETSBinder.h" #include "lexer/token/letters.h" #include "ir/base/classDefinition.h" @@ -706,6 +709,57 @@ std::vector const &Helpers::StdLib() return stdlib; } +varbinder::Scope *Helpers::NearestScope(const ir::AstNode *ast) +{ + while (ast != nullptr && !ast->IsScopeBearer()) { + ast = ast->Parent(); + } + + return ast == nullptr ? nullptr : ast->Scope(); +} + +checker::ETSObjectType const *Helpers::ContainingClass(const ir::AstNode *ast) +{ + while (ast != nullptr && !ast->IsClassDefinition()) { + ast = ast->Parent(); + } + + return ast == nullptr ? nullptr : ast->AsClassDefinition()->TsType()->AsETSObjectType(); +} + +bool CheckTypeRelation(checker::ETSChecker *checker, checker::Type *super, checker::Type *sub) +{ + return checker->Relation()->IsSupertypeOf(super, sub); +} + +void Helpers::CheckLoweredNode(varbinder::ETSBinder *varBinder, checker::ETSChecker *checker, ir::AstNode *node) +{ + auto *scope = util::Helpers::NearestScope(node); + varBinder->ResolveReferencesForScopeWithContext(node, scope); + + auto *containingClass = ContainingClass(node); + checker::CheckerStatus newStatus = + (containingClass == nullptr) ? checker::CheckerStatus::NO_OPTS : checker::CheckerStatus::IN_CLASS; + if ((checker->Context().Status() & checker::CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK) != 0) { + newStatus |= checker::CheckerStatus::IN_EXTENSION_ACCESSOR_CHECK; + } + auto checkerCtx = checker::SavedCheckerContext(checker, newStatus, containingClass); + auto scopeCtx = checker::ScopeContext(checker, scope); + + node->Check(checker); +} + +bool Helpers::IsNumericGlobalBuiltIn(checker::Type *type, checker::ETSChecker *checker) +{ + return CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalIntegerBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalShortBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalByteBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalCharBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalLongBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType()) || + CheckTypeRelation(checker, type, checker->GetGlobalTypesHolder()->GlobalFloatBuiltinType()); +} + bool Helpers::IsStdLib(const parser::Program *program) { // NOTE(rsipka): early check: if program is not in a package then it is not part of the stdlib either diff --git a/ets2panda/util/helpers.h b/ets2panda/util/helpers.h index 3ac2779161..b6cd9fe75e 100644 --- a/ets2panda/util/helpers.h +++ b/ets2panda/util/helpers.h @@ -30,6 +30,7 @@ class Program; namespace ark::es2panda::varbinder { class Variable; +class ETSBinder; } // namespace ark::es2panda::varbinder namespace ark::es2panda::checker { @@ -160,6 +161,14 @@ public: std::uint32_t index); static bool IsAsyncMethod(ir::AstNode const *node); + static varbinder::Scope *NearestScope(const ir::AstNode *ast); + static checker::ETSObjectType const *ContainingClass(const ir::AstNode *ast); + // Note: run varbinder and checker on the new node generated in lowering phases (without + // ClearTypesVariablesAndScopes) + static void CheckLoweredNode(varbinder::ETSBinder *varBinder, checker::ETSChecker *checker, ir::AstNode *node); + + static bool IsNumericGlobalBuiltIn(checker::Type *type, checker::ETSChecker *checker); + template static ArenaVector ConvertVector(const ArenaVector &src) { diff --git a/ets2panda/varbinder/scope.cpp b/ets2panda/varbinder/scope.cpp index f430c8cd48..e6a3835eb4 100644 --- a/ets2panda/varbinder/scope.cpp +++ b/ets2panda/varbinder/scope.cpp @@ -236,7 +236,10 @@ Variable *Scope::AddLocalTypeAliasVariable(ArenaAllocator *allocator, Decl *newD Variable *Scope::AddLocalClassVariable(ArenaAllocator *allocator, Decl *newDecl) { auto isNamespaceTransformed = newDecl->Node()->AsClassDefinition()->IsNamespaceTransformed(); - VariableFlags flag = isNamespaceTransformed ? VariableFlags::NAMESPACE : VariableFlags::CLASS; + auto isEnumTransformed = newDecl->Node()->AsClassDefinition()->IsEnumTransformed(); + VariableFlags flag = isNamespaceTransformed ? VariableFlags::NAMESPACE + : isEnumTransformed ? VariableFlags::ENUM_LITERAL + : VariableFlags::CLASS; auto *var = bindings_.insert({newDecl->Name(), allocator->New(newDecl, flag)}).first->second; newDecl->Node()->AsClassDefinition()->Ident()->SetVariable(var); return var; diff --git a/ets2panda/varbinder/variable.cpp b/ets2panda/varbinder/variable.cpp index 6768c7b88a..f58fab3472 100644 --- a/ets2panda/varbinder/variable.cpp +++ b/ets2panda/varbinder/variable.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -33,6 +33,8 @@ LocalVariable::LocalVariable(VariableFlags flags) : Variable(flags) {} const util::StringView &Variable::Name() const { + // Synthetic var has no decl_ + ES2PANDA_ASSERT(decl_ != nullptr); return decl_->Name(); } -- Gitee From b559eb952f16f95e7588719281d3eddfd97cbdec Mon Sep 17 00:00:00 2001 From: Shimenkov Mikhail Date: Tue, 22 Apr 2025 15:01:43 +0800 Subject: [PATCH 02/12] Fixes to rebase no-primitives Signed-off-by: Shimenkov Mikhail Change-Id: I31c8b5de3377f5f477b2f52c827ee43b9e69715c --- ets2panda/checker/ets/arithmetic.cpp | 8 ++-- ets2panda/checker/ets/function.cpp | 13 ++++--- ets2panda/checker/types/ets/etsEnumType.h | 4 +- .../types/ets/etsResizableArrayType.cpp | 9 ++++- .../checker/types/ets/etsResizableArrayType.h | 5 ++- ets2panda/checker/types/globalTypesHolder.h | 2 +- ets2panda/compiler/core/ETSemitter.cpp | 2 - .../lowering/ets/arrayLiteralLowering.cpp | 17 ++++++-- .../ets/constantExpressionLowering.cpp | 13 ++----- .../lowering/ets/restArgsLowering.cpp | 17 ++++++-- .../compiler/lowering/ets/spreadLowering.cpp | 2 +- .../compiler/lowering/ets/unboxLowering.cpp | 37 +++++++++++++----- ets2panda/compiler/lowering/util.cpp | 17 -------- ets2panda/parser/ETSparserExpressions.cpp | 1 - .../ets-runtime/ets-runtime-ignored.txt | 39 +++++++++++-------- 15 files changed, 109 insertions(+), 77 deletions(-) diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 5b4759a23d..e488b24ddf 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -121,6 +121,10 @@ static Type *TryConvertToPrimitiveType(ETSChecker *checker, Type *type) return nullptr; } + if (type->IsETSIntEnumType()) { + return checker->GlobalIntType(); + } + if (type->IsETSStringEnumType()) { return checker->GlobalETSStringLiteralType(); } @@ -372,10 +376,6 @@ checker::Type *ETSChecker::CheckBinaryBitwiseOperatorForIntEnums(const checker:: checker::Type *ETSChecker::CheckBinaryOperatorPlusForEnums(const checker::Type *const leftType, const checker::Type *const rightType) { - if (!leftType->IsETSEnumType() || !rightType->IsETSEnumType()) { - return nullptr; - } - if (auto numericType = CheckBinaryOperatorForIntEnums(leftType, rightType); numericType != nullptr) { return numericType; } diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 8d6d6b8eac..b9925d61d0 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -822,16 +822,13 @@ static void InitMostSpecificType(TypeRelation *relation, const ArenaVector call func(a where a is Byte) -> mostSpecificType will be last ETSObjectType (Int) - // ex: func(double); func(int) -> call func(a where a is byte) -> mostSpecificType will be just the first one in the - // list (double) and the second one contradicts spec!!! - // // Attempt to choose the widest type of available ones SavedTypeRelationFlagsContext ctx {relation, TypeRelationFlag::WIDENING | TypeRelationFlag::ONLY_CHECK_WIDENING}; auto checker = relation->GetChecker()->AsETSChecker(); for (auto *sig : signatures) { Type *sigType = GetParatmeterTypeOrRestAtIdx(checker, sig, idx); + relation->Result(false); + if (sigType->IsETSObjectType()) { if (sigType->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::INTERFACE)) { continue; @@ -849,6 +846,12 @@ static void InitMostSpecificType(TypeRelation *relation, const ArenaVectorIsETSFunctionType() && relation->IsSupertypeOf(sigType, mostSpecificType)) { + mostSpecificType = sigType; + prevSig = sig; + continue; + } + relation->Result(false); WideningConverter(checker, relation, sigType, mostSpecificType); if (relation->IsTrue()) { mostSpecificType = sigType; diff --git a/ets2panda/checker/types/ets/etsEnumType.h b/ets2panda/checker/types/ets/etsEnumType.h index ad1fc07d26..414a2e6102 100644 --- a/ets2panda/checker/types/ets/etsEnumType.h +++ b/ets2panda/checker/types/ets/etsEnumType.h @@ -84,7 +84,7 @@ public: if (mobj->TsType() == this) { // No need to search properties since enum-literals are the only enum-type properties // NOTE(dkofanov): For some reason, 'enumLowering' changes 'CLASS' to 'ENUM_LITERAL', instead of 'ENUM'. - ES2PANDA_ASSERT(mobj->Variable()->HasFlag(varbinder::VariableFlags::ENUM_LITERAL)); + // ES2PANDA_ASSERT(mobj->Variable()->HasFlag(varbinder::VariableFlags::ENUM_LITERAL)); ES2PANDA_ASSERT(GetDeclNode()->AsClassDefinition()->IsEnumTransformed()); return true; } @@ -162,4 +162,4 @@ public: } // namespace ark::es2panda::checker -#endif \ No newline at end of file +#endif diff --git a/ets2panda/checker/types/ets/etsResizableArrayType.cpp b/ets2panda/checker/types/ets/etsResizableArrayType.cpp index 25fcd72aba..2d4da551f1 100644 --- a/ets2panda/checker/types/ets/etsResizableArrayType.cpp +++ b/ets2panda/checker/types/ets/etsResizableArrayType.cpp @@ -24,4 +24,11 @@ ETSResizableArrayType *ETSResizableArrayType::Substitute(TypeRelation *relation, return copiedType; } -} // namespace ark::es2panda::checker \ No newline at end of file +void ETSResizableArrayType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const +{ + if (element_ != nullptr) { + ss << element_->ToString() << "[]"; + } +} + +} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsResizableArrayType.h b/ets2panda/checker/types/ets/etsResizableArrayType.h index 43babf404a..4f685b51cf 100644 --- a/ets2panda/checker/types/ets/etsResizableArrayType.h +++ b/ets2panda/checker/types/ets/etsResizableArrayType.h @@ -76,10 +76,13 @@ public: ETSResizableArrayType *Substitute(TypeRelation *relation, const Substitution *substitution) override; + + void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; + private: Type *element_; }; } // namespace ark::es2panda::checker -#endif \ No newline at end of file +#endif diff --git a/ets2panda/checker/types/globalTypesHolder.h b/ets2panda/checker/types/globalTypesHolder.h index 5f68b3fbb3..96569e2b9f 100644 --- a/ets2panda/checker/types/globalTypesHolder.h +++ b/ets2panda/checker/types/globalTypesHolder.h @@ -98,7 +98,6 @@ enum class GlobalTypeId : std::size_t { ETS_FUNCTION_BUILTIN, ETS_REGEXP_BUILTIN, ETS_ARRAY_BUILTIN, - ETS_ARRAY, ETS_INTEROP_JSRUNTIME_BUILTIN, ETS_INTEROP_JSVALUE_BUILTIN, ETS_BOX_BUILTIN, @@ -112,6 +111,7 @@ enum class GlobalTypeId : std::size_t { ETS_DOUBLE_BOX_BUILTIN, ETS_BIG_INT_BUILTIN, ETS_BIG_INT, + ETS_ARRAY, ETS_FUNCTION0_CLASS, ETS_FUNCTION1_CLASS, diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index e15be4dfc7..81da21404f 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -789,8 +789,6 @@ pandasm::AnnotationElement ETSEmitter::GenCustomAnnotationElement(const ir::Clas { const auto *init = prop->Value(); const auto *type = init->TsType(); - auto typeKind = checker::ETSChecker::TypeKind(type); - auto propName = prop->Id()->Name().Mutf8(); if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { return ProcessArrayType(prop, baseName, init); } diff --git a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp index a9aa187de8..55b253c522 100644 --- a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp @@ -88,15 +88,26 @@ ir::AstNode *ArrayLiteralLowering::TryTransformLiteralArrayToRefArray(ir::ArrayE std::vector newStmts; std::stringstream ss; auto *genSymIdent = Gensym(Allocator()); + auto *genSymIdent2 = Gensym(Allocator()); auto *type = checker_->AllocNode(arrayType, Allocator()); + // ss << "let @@I1 : FixedArray<@@T2> = @@E3;"; + // ss << "Array.from<@@T4>(@@I5);"; ss << "let @@I1 : FixedArray<@@T2> = @@E3;"; - ss << "Array.from<@@T4>(@@I5);"; + ss << "let @@I4 : Array<@@T5> = new Array<@@T6>(@@I7.length);"; + ss << "for (let i = 0; i < @@I8.length; ++i) { @@I9[i] = @@I10[i]}"; + ss << "@@I11;"; newStmts.emplace_back(genSymIdent); newStmts.emplace_back(type); - literalArray->SetTsType(nullptr); newStmts.emplace_back(literalArray); + literalArray->SetTsType(nullptr); + newStmts.emplace_back(genSymIdent2); + newStmts.emplace_back(type->Clone(Allocator(), nullptr)); newStmts.emplace_back(type->Clone(Allocator(), nullptr)); newStmts.emplace_back(genSymIdent->Clone(Allocator(), nullptr)); + newStmts.emplace_back(genSymIdent->Clone(Allocator(), nullptr)); + newStmts.emplace_back(genSymIdent2->Clone(Allocator(), nullptr)); + newStmts.emplace_back(genSymIdent->Clone(Allocator(), nullptr)); + newStmts.emplace_back(genSymIdent2->Clone(Allocator(), nullptr)); auto *parent = literalArray->Parent(); auto *loweringResult = parser_->CreateFormattedExpression(ss.str(), newStmts); @@ -255,4 +266,4 @@ ArenaAllocator *ArrayLiteralLowering::Allocator() return checker_->Allocator(); } -} // namespace ark::es2panda::compiler \ No newline at end of file +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index d5ff5281c3..3d00d014f3 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -1405,11 +1405,6 @@ ir::AstNode *ConstantExpressionLowering::MaybeUnfoldMemberExpression(ir::MemberE ir::AstNode *ConstantExpressionLowering::MaybeUnfold(ir::AstNode *node) { ir::NodeTransformer handleMaybeUnfold = [this](ir::AstNode *const n) { - if (auto const *const parent = n->Parent(); - parent->IsMemberExpression() && parent->AsMemberExpression()->Property() == n && - parent->AsMemberExpression()->Kind() != ir::MemberExpressionKind::ELEMENT_ACCESS) { - return n; - } if (n->IsIdentifier()) { return MaybeUnfoldIdentifier(n->AsIdentifier()); @@ -1490,10 +1485,10 @@ void ConstantExpressionLowering::IsInitByConstant(ir::AstNode *node) } if (!IsPotentialConstant(initTobeChecked->Type())) { - LogError(diagnostic::INVALID_INIT_IN_PACKAGE, {}, initTobeChecked->Start()); + LogError(context_, diagnostic::INVALID_INIT_IN_PACKAGE, {}, initTobeChecked->Start()); return; } - assignExpr->SetRight(FoldConstant(UnfoldConstIdentifiers(initTobeChecked))->AsExpression()); + assignExpr->SetRight(Fold(MaybeUnfold(initTobeChecked))->AsExpression()); } if (node->IsClassProperty()) { @@ -1508,10 +1503,10 @@ void ConstantExpressionLowering::IsInitByConstant(ir::AstNode *node) } if (!IsPotentialConstant(initTobeChecked->Type())) { - LogError(diagnostic::INVALID_INIT_IN_PACKAGE, {}, initTobeChecked->Start()); + LogError(context_, diagnostic::INVALID_INIT_IN_PACKAGE, {}, initTobeChecked->Start()); return; } - classProp->SetValue(FoldConstant(UnfoldConstIdentifiers(initTobeChecked))->AsExpression()); + classProp->SetValue(Fold(MaybeUnfold(initTobeChecked))->AsExpression()); } } diff --git a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp index 8726f60f08..cf74d5d53a 100644 --- a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp +++ b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp @@ -108,12 +108,21 @@ static ir::Expression *CreateRestArgsArray(public_lib::Context *context, ArenaVe std::stringstream ss; auto *genSymIdent = Gensym(allocator); + auto *genSymIdent2 = Gensym(allocator); + // Was: + // ss << "let @@I1 : FixedArray<@@T2> = @@E3;"; + // ss << "Array.from<@@T4>(@@I5);"; + // Now: + // NOTE: refactor me! ss << "let @@I1 : FixedArray<@@T2> = @@E3;"; - ss << "Array.from<@@T4>(@@I5);"; + ss << "let @@I4 : Array<@@T5> = new Array<@@T6>(@@I7.length);"; + ss << "for (let i = 0; i < @@I8.length; ++i) { @@I9[i] = @@I10[i]}"; + ss << "@@I11;"; auto *arrayExpr = checker->AllocNode(std::move(copiedArguments), allocator); auto *loweringResult = - parser->CreateFormattedExpression(ss.str(), genSymIdent, type, arrayExpr, type->Clone(allocator, nullptr), - genSymIdent->Clone(allocator, nullptr)); + parser->CreateFormattedExpression(ss.str(), genSymIdent, type->Clone(allocator, nullptr), arrayExpr, genSymIdent2, + type, type->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), + genSymIdent2->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), genSymIdent2->Clone(allocator, nullptr)); return loweringResult; } @@ -221,4 +230,4 @@ bool RestArgsLowering::PerformForModule(public_lib::Context *ctx, parser::Progra Name()); return true; } -} // namespace ark::es2panda::compiler \ No newline at end of file +} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/spreadLowering.cpp b/ets2panda/compiler/lowering/ets/spreadLowering.cpp index 4ab017a7ab..7eb4d5283a 100644 --- a/ets2panda/compiler/lowering/ets/spreadLowering.cpp +++ b/ets2panda/compiler/lowering/ets/spreadLowering.cpp @@ -109,7 +109,7 @@ static ir::Identifier *CreateNewArrayDeclareStatement(public_lib::Context *ctx, } ir::Statement *newArrayDeclareSt = - parser->CreateFormattedStatement(newArrayDeclareStr, newArrayId->Clone(allocator, nullptr), arrayElementType, + parser->CreateFormattedStatement(newArrayDeclareStr.str(), newArrayId->Clone(allocator, nullptr), arrayElementType, arrayElementType, newArrayLengthId->Clone(allocator, nullptr)); statements.emplace_back(newArrayDeclareSt); diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index c2598d1a28..783ecfa6f8 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -52,12 +52,24 @@ static bool IsRecursivelyUnboxed(checker::Type *t) return t->IsETSPrimitiveType() || IsRecursivelyUnboxedReference(t); } +static checker::Type *GetArrayElementType(checker::Type *arrType) +{ + if (arrType->IsETSResizableArrayType()) { + return arrType->AsETSResizableArrayType()->ElementType(); + } + + if (arrType->IsETSArrayType()) { + return arrType->AsETSArrayType()->ElementType(); + } + return nullptr; +} + static bool IsRecursivelyUnboxedReference(checker::Type *t) { return (t->IsETSTupleType() && std::any_of(t->AsETSTupleType()->GetTupleTypesList().begin(), t->AsETSTupleType()->GetTupleTypesList().end(), IsRecursivelyUnboxedReference)) || - (t->IsETSArrayType() && IsRecursivelyUnboxed(t->AsETSArrayType()->ElementType())) || + (t->IsETSArrayType() && IsRecursivelyUnboxed(GetArrayElementType(t))) || (t->IsETSUnionType() && std::any_of(t->AsETSUnionType()->ConstituentTypes().begin(), t->AsETSUnionType()->ConstituentTypes().end(), IsRecursivelyUnboxedReference)) || @@ -83,7 +95,7 @@ static bool IsUnboxingApplicableReference(checker::Type *t) return (t->IsETSTupleType() && std::any_of(t->AsETSTupleType()->GetTupleTypesList().begin(), t->AsETSTupleType()->GetTupleTypesList().end(), IsUnboxingApplicableReference)) || - (t->IsETSArrayType() && IsUnboxingApplicable(t->AsETSArrayType()->ElementType())) || + (t->IsETSArrayType() && IsUnboxingApplicable(GetArrayElementType(t))) || (t->IsETSUnionType() && std::any_of(t->AsETSUnionType()->ConstituentTypes().begin(), t->AsETSUnionType()->ConstituentTypes().end(), IsUnboxingApplicableReference)) || @@ -146,6 +158,12 @@ static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, che return (newE == srcArr->ElementType()) ? t : uctx->checker->CreateETSArrayType(newE); } + if (t->IsETSResizableArrayType()) { + auto *srcArr = t->AsETSResizableArrayType(); + auto *newE = MaybeRecursivelyUnboxType(uctx, srcArr->ElementType()); + return (newE == srcArr->ElementType()) ? t : uctx->checker->CreateETSResizableArrayType(newE); + } + if (t->IsETSUnionType()) { auto *srcUnion = t->AsETSUnionType(); ArenaVector newTps {allocator->Adapter()}; @@ -606,7 +624,7 @@ static void HandleForOfStatement(UnboxContext *uctx, ir::ForOfStatement *forOf) checker::Type *elemTp = nullptr; if (tp->IsETSArrayType()) { - elemTp = tp->AsETSArrayType()->ElementType(); + elemTp = GetArrayElementType(tp); } else if (tp->IsETSStringType()) { elemTp = uctx->checker->GlobalCharType(); } else { @@ -741,7 +759,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { auto *restVar = call->Signature()->RestVar(); if (restVar != nullptr && !arg->IsSpreadElement()) { // NOTE(gogabr) should we try to unbox spread elements? - auto *restElemType = restVar->TsType()->AsETSArrayType()->ElementType(); + auto *restElemType = GetArrayElementType(restVar->TsType()); call->Arguments()[i] = AdjustType(uctx_, arg, restElemType); } } else { @@ -816,7 +834,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { auto *restVar = call->GetSignature()->RestVar(); if (restVar != nullptr && !arg->IsSpreadElement()) { // NOTE(gogabr) should we try to unbox spread elements? - auto *restElemType = restVar->TsType()->AsETSArrayType()->ElementType(); + auto *restElemType = GetArrayElementType(restVar->TsType()); call->GetArguments()[i] = AdjustType(uctx_, arg, restElemType); } } else { @@ -848,7 +866,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { if (aexpr->TsType()->IsETSTupleType()) { expectedType = aexpr->TsType()->AsETSTupleType()->GetTypeAtIndex(i); } else if (aexpr->TsType()->IsETSArrayType()) { - expectedType = aexpr->TsType()->AsETSArrayType()->ElementType(); + expectedType = GetArrayElementType(aexpr->TsType()); } else { ES2PANDA_UNREACHABLE(); } @@ -1071,8 +1089,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { ES2PANDA_ASSERT(index >= 0 && (size_t)index < tupType->GetTupleSize()); mexpr->SetTsType(tupType->GetTupleTypesList()[index]); } else if (mexpr->Object()->TsType()->IsETSArrayType()) { - auto *objTp = mexpr->Object()->TsType()->AsETSArrayType(); - mexpr->SetTsType(objTp->ElementType()); + mexpr->SetTsType(GetArrayElementType(mexpr->Object()->TsType())); } /* mexpr->Object() may also have never type; nothing needs to be done in that case */ } else { @@ -1125,7 +1142,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { { auto unboxedType = MaybeRecursivelyUnboxType(uctx_, nexpr->TsType()); nexpr->SetTsType(unboxedType); - nexpr->TypeReference()->SetTsType(unboxedType->AsETSArrayType()->ElementType()); + nexpr->TypeReference()->SetTsType(GetArrayElementType(unboxedType)); nexpr->SetDimension( AdjustType(uctx_, nexpr->Dimension(), uctx_->checker->MaybeUnboxType(nexpr->Dimension()->TsType()))); @@ -1139,7 +1156,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { auto toUnbox = unboxedType; for (auto &dim : nexpr->Dimensions()) { dim = AdjustType(uctx_, dim, uctx_->checker->MaybeUnboxType(dim->TsType())); - toUnbox = toUnbox->AsETSArrayType()->ElementType(); + toUnbox = GetArrayElementType(toUnbox); } nexpr->TypeReference()->SetTsType(toUnbox); diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index 5d030192cb..013f4b7e6e 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -100,23 +100,6 @@ void ClearTypesVariablesAndScopes(ir::AstNode *node) noexcept doNode(node); } -ir::AstNode *RefineSourceRanges(ir::AstNode *node) -{ - auto const isDummyLoc = [](lexer::SourceRange const &range) { - return (range.start.index == 0 && range.start.line == 0) || (range.start.index > range.end.index); - }; - - auto const refine = [isDummyLoc](ir::AstNode *n) { - if (isDummyLoc(n->Range())) { - n->SetRange(n->Parent()->Range()); - }; - }; - - refine(node); - node->IterateRecursively(refine); - return node; -} - ArenaSet FindCaptured(ArenaAllocator *allocator, ir::AstNode *scopeBearer) noexcept { auto result = ArenaSet {allocator->Adapter()}; diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 750c7d34b6..091f63ce30 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -149,7 +149,6 @@ ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFla char32_t beginningChar = Lexer()->Lookahead(); auto start = Lexer()->GetToken().Start(); - auto const inParenthesis = Lexer()->Lookahead() == lexer::LEX_CHAR_LEFT_PAREN; Lexer()->NextToken(tokenFlags); ir::Expression *argument = ResolveArgumentUnaryExpr(flags); diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index 2c572e87b0..7d0bcb90f6 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -48,7 +48,6 @@ nullableType.ets #Issue 17949 #SyntaxError: Cannot find type 'C'. -lambdaWithLocalClassAccess.ets #Issue 21065 implementsClassPropertyUnionType1.ets @@ -61,23 +60,15 @@ optional_field.ets #Issue 22384 Object-type-in-binary-logical-expression.ets trailing-lambda.ets -unboxingBooleanConversion.ets BitwiseOperationsOnFloat.ets RecursiveTypeAlias11.ets boxingConversions3.ets -char-type.ets conversionFloatIntLong.ets conversionFromInfinity.ets -enum_const_variable.ets -local_enum03.ets non-const-capture.ets inallyCatchExecutedNormally.ets -finallyTryExecutedNormally.ets -finallyCatchExecutedNormally.ets -enumConstExpression.ets #Issue 48215 -implementsClassPropertyFunctionType_ObjectLiteralExpr.ets lambda_with_receiver/lambda_with_receiver_generics_return_this_rotate.ets lambda_with_receiver/lambda_with_receiver_return_this3.ets lambda_with_receiver/lambda_with_receiver_generics_return_this.ets @@ -85,9 +76,6 @@ lambda_with_receiver/lambda_with_receiver_trailing_in_class_method_return_this_r lambda_with_receiver/lambda_with_receiver_trailing_in_function_return_this_rotate.ets #Issue 23074 -# instance method used as value -FunctionType.ets -function_type_inference1.ets # generic bridges GenericBridges_01.ets GenericBridges_02.ets @@ -103,11 +91,7 @@ lambda_with_restparameter_object.ets lambda_with_restparameter_predefinedtypes.ets # Arrays of primitives used interchangeably with arrays of reference (in generics and forOf) -ForOfUnion.ets -SpreadExpressions.ets GenericArray_1.ets -GenericArray_2.ets -SpreadExpressions_ResizableArray.ets array-object.ets #HEAD FILE NO NEED TO RUN @@ -121,3 +105,26 @@ enum-initialize-with-enum2.ets CastPrimitive.ets nullishTypeCodesamples.ets instanceof.ets + +# Rebase no-primitives pathch onto master with merger Array refactoring +AnnotationConstExpression.ets +annotation_tests/AnnotationForClass.ets +annotation_tests/AnnotationForLambdaExpression.ets +annotation_tests/AnnotationNoNeedToSetProperties03.ets +annotation_tests/AnnotationsFieldType03.ets +annotation_tests/AnnotationsFieldType04.ets +annotation_tests/EmitAnnotationToBytecode.ets +annotation_tests/annotationUsageSingleFileds05.ets +namespace_tests/namespace_with_annotations.ets +lambda_with_rest_param_resizablearray.ets +type_from_primitive_type.ets +lambda_with_rest_param_fixedarray.ets +lambda_with_restparameter_object_fixedarray.ets +lambda_with_restparameter_predefinedtypes_fixedarray.ets +annotation_tests/AnnotationForTypesInAnnotation.ets +annotation_tests/annotationUsageSingleFileds06.ets +annotation_tests/annotationUsageSingleFileds07.ets +enum-relational-operators.ets +local-enum-relational-operators.ets +rest_object_literal.ets +union_generic_class.ets -- Gitee From 2232c83565e5db0c7d762187ea71eb17e4cf34cb Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Tue, 22 Apr 2025 14:41:45 +0300 Subject: [PATCH 03/12] Fix normalization of resizable array types Signed-off-by: Georgy Bronnikov --- ets2panda/compiler/lowering/ets/unboxLowering.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 783ecfa6f8..c02f872e2b 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -160,7 +160,7 @@ static checker::Type *MaybeRecursivelyUnboxReferenceType(UnboxContext *uctx, che if (t->IsETSResizableArrayType()) { auto *srcArr = t->AsETSResizableArrayType(); - auto *newE = MaybeRecursivelyUnboxType(uctx, srcArr->ElementType()); + auto *newE = MaybeRecursivelyUnboxReferenceType(uctx, srcArr->ElementType()); return (newE == srcArr->ElementType()) ? t : uctx->checker->CreateETSResizableArrayType(newE); } -- Gitee From a109b3ea930e5c6bcdcc9b0a6b3b52be06ec90d1 Mon Sep 17 00:00:00 2001 From: aakmaev Date: Tue, 22 Apr 2025 15:11:57 +0300 Subject: [PATCH 04/12] Fix clang format and remove workaround Signed-off-by: Akmaev Aleksey --- ets2panda/checker/types/ets/etsResizableArrayType.h | 1 - ets2panda/checker/types/signature.cpp | 4 +--- .../lowering/ets/constantExpressionLowering.cpp | 1 - ets2panda/compiler/lowering/ets/restArgsLowering.cpp | 9 +++++---- ets2panda/compiler/lowering/ets/spreadLowering.cpp | 6 +++--- .../ets/topLevelStmts/globalClassHandler.cpp | 9 +++------ .../lowering/ets/topLevelStmts/globalClassHandler.h | 12 +++++++----- 7 files changed, 19 insertions(+), 23 deletions(-) diff --git a/ets2panda/checker/types/ets/etsResizableArrayType.h b/ets2panda/checker/types/ets/etsResizableArrayType.h index 4f685b51cf..8b041760eb 100644 --- a/ets2panda/checker/types/ets/etsResizableArrayType.h +++ b/ets2panda/checker/types/ets/etsResizableArrayType.h @@ -76,7 +76,6 @@ public: ETSResizableArrayType *Substitute(TypeRelation *relation, const Substitution *substitution) override; - void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override; private: diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index 0983219efb..34b2d8a74e 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -217,9 +217,7 @@ static bool MethodSignaturesAreCompatible(TypeRelation *relation, bool checkIden } auto const areCompatible = [relation, checkIdentical](Type *superT, Type *subT) { - return checkIdentical - ? superT->IsETSTypeParameter() || subT->IsETSTypeParameter() || relation->IsIdenticalTo(superT, subT) - : relation->IsSupertypeOf(superT, subT); + return checkIdentical ? relation->IsIdenticalTo(superT, subT) : relation->IsSupertypeOf(superT, subT); }; if (!relation->NoReturnTypeCheck() && !areCompatible(super->ReturnType(), sub->ReturnType())) { return false; diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index 3d00d014f3..ab0e05cae9 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -1405,7 +1405,6 @@ ir::AstNode *ConstantExpressionLowering::MaybeUnfoldMemberExpression(ir::MemberE ir::AstNode *ConstantExpressionLowering::MaybeUnfold(ir::AstNode *node) { ir::NodeTransformer handleMaybeUnfold = [this](ir::AstNode *const n) { - if (n->IsIdentifier()) { return MaybeUnfoldIdentifier(n->AsIdentifier()); } diff --git a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp index cf74d5d53a..b8b421ea10 100644 --- a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp +++ b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp @@ -119,10 +119,11 @@ static ir::Expression *CreateRestArgsArray(public_lib::Context *context, ArenaVe ss << "for (let i = 0; i < @@I8.length; ++i) { @@I9[i] = @@I10[i]}"; ss << "@@I11;"; auto *arrayExpr = checker->AllocNode(std::move(copiedArguments), allocator); - auto *loweringResult = - parser->CreateFormattedExpression(ss.str(), genSymIdent, type->Clone(allocator, nullptr), arrayExpr, genSymIdent2, - type, type->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), - genSymIdent2->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), genSymIdent2->Clone(allocator, nullptr)); + auto *loweringResult = parser->CreateFormattedExpression( + ss.str(), genSymIdent, type->Clone(allocator, nullptr), arrayExpr, genSymIdent2, type, + type->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), + genSymIdent2->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), + genSymIdent2->Clone(allocator, nullptr)); return loweringResult; } diff --git a/ets2panda/compiler/lowering/ets/spreadLowering.cpp b/ets2panda/compiler/lowering/ets/spreadLowering.cpp index 7eb4d5283a..31bd8b08a9 100644 --- a/ets2panda/compiler/lowering/ets/spreadLowering.cpp +++ b/ets2panda/compiler/lowering/ets/spreadLowering.cpp @@ -108,9 +108,9 @@ static ir::Identifier *CreateNewArrayDeclareStatement(public_lib::Context *ctx, newArrayDeclareStr << "let @@I1: FixedArray<@@T2> = new (@@T3)[@@I4];" << std::endl; } - ir::Statement *newArrayDeclareSt = - parser->CreateFormattedStatement(newArrayDeclareStr.str(), newArrayId->Clone(allocator, nullptr), arrayElementType, - arrayElementType, newArrayLengthId->Clone(allocator, nullptr)); + ir::Statement *newArrayDeclareSt = parser->CreateFormattedStatement( + newArrayDeclareStr.str(), newArrayId->Clone(allocator, nullptr), arrayElementType, arrayElementType, + newArrayLengthId->Clone(allocator, nullptr)); statements.emplace_back(newArrayDeclareSt); return newArrayId; diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp index 9d21718251..4135e26bac 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp @@ -141,8 +141,7 @@ void GlobalClassHandler::SetupGlobalMethods(ArenaVector &&initS return; } - ir::MethodDefinition *initMethod = - CreateGlobalMethod(compiler::Signatures::INIT_METHOD, std::move(initStatements)); + ir::MethodDefinition *initMethod = CreateGlobalMethod(compiler::Signatures::INIT_METHOD, std::move(initStatements)); InsertInGlobal(globalClass, initMethod); if (!initMethod->Function()->Body()->AsBlockStatement()->Statements().empty()) { AddInitCallToStaticBlock(globalClass, initMethod); @@ -223,8 +222,7 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns) const ModuleDependencies md {allocator_->Adapter()}; auto immediateInitStatements = FormInitMethodStatements(&md, std::move(immediateInitializers)); auto initializerBlockStatements = FormInitMethodStatements(&md, std::move(initializerBlock)); - SetupGlobalMethods(std::move(immediateInitStatements), globalClass, - ns->IsDeclare()); + SetupGlobalMethods(std::move(immediateInitStatements), globalClass, ns->IsDeclare()); // remove namespaceDecl from orginal node auto end = std::remove_if(body.begin(), body.end(), [&namespaces](ir::AstNode *node) { @@ -318,8 +316,7 @@ void GlobalClassHandler::SetupGlobalClass(const ArenaVector & CollectProgramGlobalClasses(namespaces); TransformBrokenNamespace(); - auto initializerBlockStmts = - FormInitStaticBlockMethodStatements(moduleDependencies, std::move(initializerBlock)); + auto initializerBlockStmts = FormInitStaticBlockMethodStatements(moduleDependencies, std::move(initializerBlock)); CollectExportedClasses(globalClass, globalProgram_->Ast()->Statements()); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h index 8dac90e886..1d65297dec 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.h @@ -32,7 +32,10 @@ public: ArenaVector statements; }; explicit GlobalClassHandler(parser::ETSParser *parser, ArenaAllocator *allocator, parser::Program *program) - : parser_(parser), allocator_(allocator), globalProgram_(program), packageInitializerBlockCount_(allocator->Adapter()) {}; + : parser_(parser), + allocator_(allocator), + globalProgram_(program), + packageInitializerBlockCount_(allocator->Adapter()) {}; static void MergeNamespace(ArenaVector &namespaces, parser::Program *program); @@ -64,8 +67,8 @@ private: template void CollectExportedClasses(ir::ClassDefinition *classDef, const ArenaVector &statements); void CollectNamespaceExportedClasses(ir::ClassDefinition *classDef); - void SetupGlobalMethods(ArenaVector &&initStatements, - ir::ClassDefinition *globalClass, bool isDeclare); + void SetupGlobalMethods(ArenaVector &&initStatements, ir::ClassDefinition *globalClass, + bool isDeclare); void SetupInitializerBlock(ArenaVector> &&initializerBlock, ir::ClassDefinition *globalClass); ArenaVector TransformNamespaces(ArenaVector &namespaces); @@ -78,8 +81,7 @@ private: ArenaVector &&initializerBlocks); ArenaVector> FormInitStaticBlockMethodStatements( - const ModuleDependencies *moduleDependencies, - ArenaVector &&initStatements); + const ModuleDependencies *moduleDependencies, ArenaVector &&initStatements); void TransformBrokenNamespace(); ArenaVector FormInitMethodStatements(const ModuleDependencies *moduleDependencies, -- Gitee From 8d0d2edecebe9c59950d6b10113092b36bfce682 Mon Sep 17 00:00:00 2001 From: Tatiana Titova Date: Wed, 9 Apr 2025 15:36:28 +0300 Subject: [PATCH 05/12] Change koala version Signed-off-by: Tatiana Titova --- ets2panda/scripts/arkui.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties index cbe2883b04..567afb5a99 100644 --- a/ets2panda/scripts/arkui.properties +++ b/ets2panda/scripts/arkui.properties @@ -1,3 +1,3 @@ ARKUI_DEV_REPO=https://gitee.com/rri_opensource/koala_projects.git -ARKUI_DEV_BRANCH=panda_rev_7-1-type-error +ARKUI_DEV_BRANCH=panda_rev_7-remove-primitives ARKUI_DEST=koala-sig -- Gitee From 017ea88a841b9939bbb597663297d4654b181331 Mon Sep 17 00:00:00 2001 From: Anna Antipina Date: Tue, 22 Apr 2025 19:53:55 +0300 Subject: [PATCH 06/12] Fix GlobalClass lowering Change-Id: I5db0b3466162b314367240370889a305739a1cdf Signed-off-by: Anna Antipina --- .../ets/topLevelStmts/globalClassHandler.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp index 4135e26bac..9b79dc94c9 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp @@ -221,8 +221,9 @@ ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns) AddStaticBlockToClass(globalClass); const ModuleDependencies md {allocator_->Adapter()}; auto immediateInitStatements = FormInitMethodStatements(&md, std::move(immediateInitializers)); - auto initializerBlockStatements = FormInitMethodStatements(&md, std::move(initializerBlock)); + auto initializerBlockStatements = FormInitStaticBlockMethodStatements(&md, std::move(initializerBlock)); SetupGlobalMethods(std::move(immediateInitStatements), globalClass, ns->IsDeclare()); + SetupInitializerBlock(std::move(initializerBlockStatements), globalClass); // remove namespaceDecl from orginal node auto end = std::remove_if(body.begin(), body.end(), [&namespaces](ir::AstNode *node) { @@ -559,23 +560,12 @@ static bool HasMethod(ir::ClassDefinition const *cls, const std::string_view nam void GlobalClassHandler::SetupGlobalMethods(ArenaVector &&initStatements) { ir::ClassDefinition *const globalClass = globalProgram_->GlobalClass(); - - auto const insertInGlobal = [globalClass](ir::AstNode *node) { - // NOTE(vpukhov): inserted to begin for some reason - globalClass->Body().insert(globalClass->Body().begin(), node); - node->SetParent(globalClass); - }; - - if (!globalProgram_->IsDeclarationModule()) { - ir::MethodDefinition *initMethod = - CreateGlobalMethod(compiler::Signatures::INIT_METHOD, std::move(initStatements)); - insertInGlobal(initMethod); - } + SetupGlobalMethods(std::move(initStatements), globalClass, globalProgram_->IsDeclarationModule()); if (globalProgram_->IsSeparateModule() && !HasMethod(globalClass, compiler::Signatures::MAIN)) { ir::MethodDefinition *mainMethod = CreateGlobalMethod(compiler::Signatures::MAIN, ArenaVector(allocator_->Adapter())); - insertInGlobal(mainMethod); + InsertInGlobal(globalClass, mainMethod); } } -- Gitee From ea21a0fbae6a60423b00edf3c036f5a754955838 Mon Sep 17 00:00:00 2001 From: Daniel Kofanov Date: Wed, 23 Apr 2025 01:23:06 +0800 Subject: [PATCH 07/12] Lower T[] into FixedArray[] in annotations Also 1. Pass callback in 'TransformChildrenRecursively' by ref rather than by-value 2. Handle chars in UnboxLowering for annotations 3. Replace some ETSChecker methods with static functions --- ets2panda/checker/ETSAnalyzer.cpp | 17 ++++++++- ets2panda/checker/ETSchecker.h | 3 -- ets2panda/checker/ets/typeCheckingHelpers.cpp | 38 +++++++++++-------- ets2panda/checker/ets/validateHelpers.cpp | 21 ---------- .../lowering/ets/resizableArrayLowering.cpp | 23 ++++++++--- .../compiler/lowering/ets/unboxLowering.cpp | 31 ++++++++------- ets2panda/ir/astNode.cpp | 35 ++++++++++++++--- ets2panda/ir/astNode.h | 11 +++++- 8 files changed, 111 insertions(+), 68 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 331c9b6048..dcf6d5b49b 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2415,6 +2415,21 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationDeclaration *st) const return ReturnTypeForStatement(st); } +static void ProcessRequiredFields(ArenaUnorderedMap &fieldMap, + ir::AnnotationUsage *st, ETSChecker *checker) +{ + for (const auto &entry : fieldMap) { + if (entry.second->Value() == nullptr) { + checker->LogError(diagnostic::ANNOT_FIELD_NO_VAL, {entry.first}, st->Start()); + continue; + } + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + auto *clone = entry.second->Clone(checker->Allocator(), st); + st->AddProperty(clone); + clone->Check(checker); + } +} + checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const { if (st->Expr()->TsType() != nullptr) { @@ -2450,7 +2465,7 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const checker->CheckMultiplePropertiesAnnotation(st, st->GetBaseName()->Name(), fieldMap); } - checker->ProcessRequiredFields(fieldMap, st, checker); + ProcessRequiredFields(fieldMap, st, checker); return ReturnTypeForStatement(st); } diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index bc4e8b0a22..2e0c049eab 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -572,9 +572,6 @@ public: bool IsNullLikeOrVoidExpression(const ir::Expression *expr) const; bool IsConstantExpression(ir::Expression *expr, Type *type); void ValidateUnaryOperatorOperand(varbinder::Variable *variable); - bool ValidateAnnotationPropertyType(checker::Type *tsType); - void ProcessRequiredFields(ArenaUnorderedMap &fieldMap, - ir::AnnotationUsage *st, ETSChecker *checker) const; void CheckFunctionSignatureAnnotations(const ArenaVector ¶ms, ir::TSTypeParameterDeclaration *typeParams, ir::TypeNode *returnTypeAnnotation); diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 92cbd276d8..9ce7252c38 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -1109,10 +1109,31 @@ static auto IsValidAnnotationPropInitializer(ir::Expression *init) return false; } +static bool ValidateAnnotationPropertyType(checker::Type *type, ETSChecker *checker) +{ + if (type == nullptr || type->IsTypeError()) { + ES2PANDA_ASSERT(checker->IsAnyError()); + return false; + } + + if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { + return ValidateAnnotationPropertyType(checker->GetElementTypeOfArray(type), checker); + } + auto relation = checker->Relation(); + return type->IsETSEnumType() || type->IsETSStringType() || + (type->IsETSObjectType() && (relation->IsSupertypeOf(checker->GlobalETSBooleanBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalByteBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalShortBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalIntBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalLongBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalFloatBuiltinType(), type) || + relation->IsSupertypeOf(checker->GlobalDoubleBuiltinType(), type))); +} + void ETSChecker::CheckAnnotationPropertyType(ir::ClassProperty *property) { // typeAnnotation check - if (!ValidateAnnotationPropertyType(property->TsType())) { + if (!ValidateAnnotationPropertyType(property->TsType(), this)) { LogError(diagnostic::ANNOT_FIELD_INVALID_TYPE, {}, property->Start()); } @@ -1138,21 +1159,6 @@ void ETSChecker::CheckSinglePropertyAnnotation(ir::AnnotationUsage *st, ir::Anno CheckAnnotationPropertyType(param); } -void ETSChecker::ProcessRequiredFields(ArenaUnorderedMap &fieldMap, - ir::AnnotationUsage *st, ETSChecker *checker) const -{ - for (const auto &entry : fieldMap) { - if (entry.second->Value() == nullptr) { - checker->LogError(diagnostic::ANNOT_FIELD_NO_VAL, {entry.first}, st->Start()); - continue; - } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *clone = entry.second->Clone(checker->Allocator(), st); - st->AddProperty(clone); - clone->Check(checker); - } -} - void ETSChecker::CheckMultiplePropertiesAnnotation(ir::AnnotationUsage *st, util::StringView const &baseName, ArenaUnorderedMap &fieldMap) { diff --git a/ets2panda/checker/ets/validateHelpers.cpp b/ets2panda/checker/ets/validateHelpers.cpp index a99d8ef1e6..2530894b03 100644 --- a/ets2panda/checker/ets/validateHelpers.cpp +++ b/ets2panda/checker/ets/validateHelpers.cpp @@ -180,27 +180,6 @@ void ETSChecker::ValidateResolvedIdentifier(ir::Identifier *const ident) } } -bool ETSChecker::ValidateAnnotationPropertyType(checker::Type *type) -{ - if (type == nullptr || type->IsTypeError()) { - ES2PANDA_ASSERT(IsAnyError()); - return false; - } - - if (type->IsETSArrayType() || type->IsETSResizableArrayType()) { - return ValidateAnnotationPropertyType(MaybeUnboxType(GetElementTypeOfArray(type))); - } - - return type->IsETSEnumType() || type->IsETSStringType() || - (type->IsETSObjectType() && (Relation()->IsSupertypeOf(GlobalETSBooleanBuiltinType(), type) || - Relation()->IsSupertypeOf(GlobalByteBuiltinType(), type) || - Relation()->IsSupertypeOf(GlobalShortBuiltinType(), type) || - Relation()->IsSupertypeOf(GlobalIntBuiltinType(), type) || - Relation()->IsSupertypeOf(GlobalLongBuiltinType(), type) || - Relation()->IsSupertypeOf(GlobalFloatBuiltinType(), type) || - Relation()->IsSupertypeOf(GlobalDoubleBuiltinType(), type))); -} - void ETSChecker::ValidateUnaryOperatorOperand(varbinder::Variable *variable) { if (IsVariableGetterSetter(variable)) { diff --git a/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp b/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp index 12d58293e3..d2fc30b97c 100644 --- a/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp +++ b/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp @@ -22,11 +22,11 @@ namespace ark::es2panda::compiler { using AstNodePtr = ir::AstNode *; -static ir::AstNode *ConvertToResizableArrayType(ir::TSArrayType *node, public_lib::Context *ctx) +static ir::AstNode *ConvertToResizableArrayType(ir::TSArrayType *node, public_lib::Context *ctx, bool insideAnnotdecl) { auto *parser = ctx->parser->AsETSParser(); - ir::TypeNode *typeAnnotation = - parser->CreateFormattedTypeAnnotation("Array<" + node->ElementType()->DumpEtsSrc() + ">"); + ir::TypeNode *typeAnnotation = parser->CreateFormattedTypeAnnotation((insideAnnotdecl ? "FixedArray<" : "Array<") + + node->ElementType()->DumpEtsSrc() + ">"); typeAnnotation->SetAnnotations(std::move(node->Annotations())); typeAnnotation->SetParent(node->Parent()); typeAnnotation->SetRange(node->Range()); @@ -37,13 +37,24 @@ static ir::AstNode *ConvertToResizableArrayType(ir::TSArrayType *node, public_li bool ResizableArrayConvert::PerformForModule(public_lib::Context *ctx, parser::Program *program) { - program->Ast()->TransformChildrenRecursivelyPreorder( - [ctx](ir::AstNode *node) -> AstNodePtr { + bool insideAnnotdecl = false; + program->Ast()->TransformChildrenRecursively( + [&insideAnnotdecl, ctx](ir::AstNode *node) -> AstNodePtr { + if (node->IsAnnotationDeclaration()) { + ES2PANDA_ASSERT(!insideAnnotdecl); + insideAnnotdecl = true; + } if (node->IsTSArrayType()) { - return ConvertToResizableArrayType(node->AsTSArrayType(), ctx); + return ConvertToResizableArrayType(node->AsTSArrayType(), ctx, insideAnnotdecl); } return node; }, + [&insideAnnotdecl](ir::AstNode *node) { + if (node->IsAnnotationDeclaration()) { + ES2PANDA_ASSERT(insideAnnotdecl); + insideAnnotdecl = false; + } + }, Name()); return true; diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index c02f872e2b..e82b01fd5e 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -478,29 +478,29 @@ static ir::Expression *InsertPrimitiveConversionIfNeeded(UnboxContext *uctx, ir: } // CC-OFFNXT(huge_cyclomatic_complexity,G.FUN.01-CPP) solid logic -static ir::Expression *PerformLiteralConversion(UnboxContext *uctx, lexer::Number const *n, checker::Type *expectedType) +static ir::Expression *PerformLiteralConversion(UnboxContext *uctx, lexer::Number const &n, checker::Type *expectedType) { auto *allocator = uctx->checker->Allocator(); bool isInt = false; int64_t longValue = 0; double doubleValue = 0.0; - if (n->IsByte()) { - longValue = n->GetByte(); + if (n.IsByte()) { + longValue = n.GetByte(); isInt = true; - } else if (n->IsShort()) { - longValue = n->GetShort(); + } else if (n.IsShort()) { + longValue = n.GetShort(); isInt = true; - } else if (n->IsInt()) { - longValue = n->GetInt(); + } else if (n.IsInt()) { + longValue = n.GetInt(); isInt = true; - } else if (n->IsLong()) { - longValue = n->GetLong(); + } else if (n.IsLong()) { + longValue = n.GetLong(); isInt = true; - } else if (n->IsFloat()) { - doubleValue = n->GetFloat(); + } else if (n.IsFloat()) { + doubleValue = n.GetFloat(); isInt = false; - } else if (n->IsDouble()) { - doubleValue = n->GetDouble(); + } else if (n.IsDouble()) { + doubleValue = n.GetDouble(); isInt = false; } else { ES2PANDA_UNREACHABLE(); @@ -544,7 +544,10 @@ static ir::Expression *InsertConversionBetweenPrimitivesIfNeeded(UnboxContext *u if (expr->IsNumberLiteral() && expectedType->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC)) { /* Some contexts (namely, annotations) expect literals, so provide them if possible */ - res = PerformLiteralConversion(uctx, &expr->AsNumberLiteral()->Number(), expectedType); + res = PerformLiteralConversion(uctx, expr->AsNumberLiteral()->Number(), expectedType); + res->SetRange(range); + } else if (expr->IsCharLiteral() && expectedType->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC)) { + res = PerformLiteralConversion(uctx, lexer::Number{expr->AsCharLiteral()->Char()}, expectedType); res->SetRange(range); } else { auto *allocator = checker->Allocator(); diff --git a/ets2panda/ir/astNode.cpp b/ets2panda/ir/astNode.cpp index 14806412bd..e06c80311a 100644 --- a/ets2panda/ir/astNode.cpp +++ b/ets2panda/ir/astNode.cpp @@ -127,10 +127,35 @@ void AstNode::TransformChildrenRecursively(const NodeTransformer &cb, std::strin TransformChildrenRecursivelyPostorder(cb, transformationName); } +void AstNode::TransformChildrenRecursively(const NodeTransformer &pre, const NodeTraverser &post, + std::string_view transformationName) +{ + TransformChildren( + [&pre, &post, transformationName](AstNode *child) { + auto *childReplacement = pre(child); + childReplacement->TransformChildrenRecursively(pre, post, transformationName); + post(childReplacement); + return childReplacement; + }, + transformationName); +} + +void AstNode::TransformChildrenRecursively(const NodeTraverser &pre, const NodeTransformer &post, + std::string_view transformationName) +{ + TransformChildren( + [&pre, &post, transformationName](AstNode *child) { + pre(child); + child->TransformChildrenRecursively(pre, post, transformationName); + return post(child); + }, + transformationName); +} + void AstNode::TransformChildrenRecursivelyPreorder(const NodeTransformer &cb, std::string_view transformationName) { TransformChildren( - [=](AstNode *child) { + [&cb, transformationName](AstNode *child) { auto *res = cb(child); res->TransformChildrenRecursivelyPreorder(cb, transformationName); return res; @@ -141,7 +166,7 @@ void AstNode::TransformChildrenRecursivelyPreorder(const NodeTransformer &cb, st void AstNode::TransformChildrenRecursivelyPostorder(const NodeTransformer &cb, std::string_view transformationName) { TransformChildren( - [=](AstNode *child) { + [&cb, transformationName](AstNode *child) { child->TransformChildrenRecursivelyPostorder(cb, transformationName); return cb(child); }, @@ -155,7 +180,7 @@ void AstNode::IterateRecursively(const NodeTraverser &cb) const void AstNode::IterateRecursivelyPreorder(const NodeTraverser &cb) const { - Iterate([=](AstNode *child) { + Iterate([&cb](AstNode *child) { cb(child); child->IterateRecursivelyPreorder(cb); }); @@ -163,7 +188,7 @@ void AstNode::IterateRecursivelyPreorder(const NodeTraverser &cb) const void AstNode::IterateRecursivelyPostorder(const NodeTraverser &cb) const { - Iterate([=](AstNode *child) { + Iterate([&cb](AstNode *child) { child->IterateRecursivelyPostorder(cb); cb(child); }); @@ -180,7 +205,7 @@ void AnyChildHelper(bool *found, const NodePredicate &cb, AstNode *ast) return; } - ast->Iterate([=](AstNode *child) { AnyChildHelper(found, cb, child); }); + ast->Iterate([&cb, found](AstNode *child) { AnyChildHelper(found, cb, child); }); } bool AstNode::IsAnyChild(const NodePredicate &cb) const diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index 1ea28d2117..2d1903dc4c 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -529,8 +529,15 @@ public: virtual void Iterate(const NodeTraverser &cb) const = 0; void TransformChildrenRecursively(const NodeTransformer &cb, std::string_view transformationName); - void TransformChildrenRecursivelyPreorder(const NodeTransformer &cb, std::string_view transformationName); - void TransformChildrenRecursivelyPostorder(const NodeTransformer &cb, std::string_view transformationName); + void TransformChildrenRecursively(const NodeTransformer &pre, const NodeTraverser &post, + std::string_view transformationName); + void TransformChildrenRecursively(const NodeTraverser &pre, const NodeTransformer &post, + std::string_view transformationName); + // Keep these for perf reasons: + void TransformChildrenRecursivelyPreorder(const NodeTransformer &preorderTransformer, + std::string_view transformationName); + void TransformChildrenRecursivelyPostorder(const NodeTransformer &postorderTransformer, + std::string_view transformationName); void IterateRecursively(const NodeTraverser &cb) const; void IterateRecursivelyPreorder(const NodeTraverser &cb) const; -- Gitee From 4bf1622116663880023e15178d277fc30f90ee33 Mon Sep 17 00:00:00 2001 From: Shimenkov Mikhail Date: Mon, 21 Apr 2025 16:42:38 +0800 Subject: [PATCH 08/12] Remove conversion char <-> string Signed-off-by: Shimenkov Mikhail Change-Id: Id57f9a50654242d467d8a4343770b61499b8d7ec --- ets2panda/BUILD.gn | 1 - ets2panda/CMakeLists.txt | 1 - ets2panda/checker/types/ets/charType.cpp | 10 --- ets2panda/checker/types/ets/etsObjectType.cpp | 12 ---- ets2panda/checker/types/ets/etsStringType.cpp | 23 +----- ets2panda/checker/types/ets/etsStringType.h | 2 - ets2panda/checker/types/typeRelation.h | 5 -- ets2panda/compiler/core/ETSGen.cpp | 16 +---- .../ets/constStringToCharLowering.cpp | 72 ------------------- .../lowering/ets/constStringToCharLowering.h | 31 -------- .../ets/constantExpressionLowering.cpp | 54 +------------- .../compiler/lowering/ets/unboxLowering.cpp | 4 -- ets2panda/compiler/lowering/phase.cpp | 3 - .../ets/ImplicitCharToStringConversion.ets | 21 ------ ets2panda/test/runtime/ets/boxing_1.ets | 16 ++--- .../test/runtime/ets/charToStringCast.ets | 4 +- .../test/runtime/ets/primitive_to_boxed.ets | 8 +-- .../ets-runtime/ets-runtime-ignored.txt | 1 + ets2panda/util/ustring.cpp | 8 --- ets2panda/util/ustring.h | 2 - 20 files changed, 18 insertions(+), 276 deletions(-) delete mode 100644 ets2panda/compiler/lowering/ets/constStringToCharLowering.cpp delete mode 100644 ets2panda/compiler/lowering/ets/constStringToCharLowering.h delete mode 100644 ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 22a8026b70..0a418ecf30 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -209,7 +209,6 @@ libes2panda_sources = [ "compiler/lowering/ets/boxingForLocals.cpp", "compiler/lowering/ets/capturedVariables.cpp", "compiler/lowering/ets/cfgBuilderPhase.cpp", - "compiler/lowering/ets/constStringToCharLowering.cpp", "compiler/lowering/ets/constantExpressionLowering.cpp", "compiler/lowering/ets/declareOverloadLowering.cpp", "compiler/lowering/ets/defaultParametersInConstructorLowering.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index b75743efaa..08ba487893 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -274,7 +274,6 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/ambientLowering.cpp compiler/lowering/ets/asyncMethodLowering.cpp compiler/lowering/ets/bigintLowering.cpp - compiler/lowering/ets/constStringToCharLowering.cpp compiler/lowering/ets/recordLowering.cpp compiler/lowering/ets/resizableArrayLowering.cpp compiler/lowering/ets/restArgsLowering.cpp diff --git a/ets2panda/checker/types/ets/charType.cpp b/ets2panda/checker/types/ets/charType.cpp index 0446571769..73a36a0570 100644 --- a/ets2panda/checker/types/ets/charType.cpp +++ b/ets2panda/checker/types/ets/charType.cpp @@ -37,11 +37,6 @@ void CharType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *s bool CharType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) { if (relation->InAssignmentContext()) { - if (target->IsETSStringType()) { - conversion::Boxing(relation, this); - relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); - return relation->Result(true); - } relation->GetChecker()->AsETSChecker()->CheckUnboxedTypeWidenable(relation, target, this); if (!relation->IsTrue()) { return false; @@ -72,11 +67,6 @@ void CharType::Cast(TypeRelation *const relation, Type *const target) return; } - if (target->IsETSStringType()) { - conversion::String(relation, this); - return; - } - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { if (target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)) { conversion::Boxing(relation, this); diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 243851bea7..6e4fcf43d1 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -483,12 +483,6 @@ bool ETSObjectType::CheckIdenticalFlags(ETSObjectType *other) const bool ETSObjectType::AssignmentSource(TypeRelation *const relation, [[maybe_unused]] Type *const target) { - if (target->IsETSStringType() && IsETSCharType()) { - if (relation->GetNode() != nullptr) { - relation->GetNode()->AddAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); - } - return relation->Result(true); - } // NOTE: do not modify, to be implied by the relation return relation->IsSupertypeOf(target, this); } @@ -693,12 +687,6 @@ void ETSObjectType::Cast(TypeRelation *const relation, Type *const target) } if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - if (target->IsETSStringType() && IsETSCharType()) { - // Cast Char to String - auto unboxed = relation->GetChecker()->AsETSChecker()->MaybeUnboxType(this); - conversion::String(relation, unboxed); - return; - } conversion::WideningReference(relation, this, target->AsETSObjectType()); if (relation->IsTrue()) { return; diff --git a/ets2panda/checker/types/ets/etsStringType.cpp b/ets2panda/checker/types/ets/etsStringType.cpp index 648af3cc01..ef98c512f8 100644 --- a/ets2panda/checker/types/ets/etsStringType.cpp +++ b/ets2panda/checker/types/ets/etsStringType.cpp @@ -40,17 +40,7 @@ void ETSStringType::Identical(TypeRelation *relation, Type *other) bool ETSStringType::AssignmentSource(TypeRelation *relation, Type *target) { - auto node = relation->GetNode(); - if ((relation->InAssignmentContext() || relation->ApplyStringToChar()) && IsConvertibleTo(target)) { - node->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOX_TO_CHAR); - if (target->IsETSObjectType()) { - node->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR); - } - relation->Result(true); - } else { - relation->Result(target->IsETSStringType() && AreStringTypesAssignable(this, target)); - } - + relation->Result(target->IsETSStringType() && AreStringTypesAssignable(this, target)); return relation->IsTrue(); } @@ -84,15 +74,4 @@ void ETSStringType::IsSubtypeOf(TypeRelation *relation, Type *source) auto *const checker = relation->GetChecker()->AsETSChecker(); relation->IsSupertypeOf(source, checker->GlobalBuiltinETSStringType()); } - -bool ETSStringType::IsConvertibleTo(Type const *to) const -{ - const bool targetIsChar = - to->IsCharType() || - // ETSObjectType is used in arrow function expression call. - (to->IsETSObjectType() && to->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_CHAR)); - - return targetIsChar && IsConstantType() && value_.IsConvertibleToChar(); -} - } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsStringType.h b/ets2panda/checker/types/ets/etsStringType.h index bad56b1e2d..2aa87a138a 100644 --- a/ets2panda/checker/types/ets/etsStringType.h +++ b/ets2panda/checker/types/ets/etsStringType.h @@ -76,8 +76,6 @@ public: return value_; } - bool IsConvertibleTo(Type const *to) const; - private: util::StringView value_ {}; }; diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index f71f472980..1387cac1e1 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -157,11 +157,6 @@ public: return (flags_ & TypeRelationFlag::UNBOXING) != 0; } - bool ApplyStringToChar() const - { - return (flags_ & TypeRelationFlag::STRING_TO_CHAR) != 0; - } - bool NoReturnTypeCheck() const { return (flags_ & TypeRelationFlag::NO_RETURN_TYPE_CHECK) != 0; diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index fb19731ee5..57a00db32b 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -1149,12 +1149,6 @@ void ETSGen::ApplyConversion(const ir::AstNode *node, const checker::Type *targe const bool hasUnboxingflags = (node->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U; if (hasBoxingflags && !hasUnboxingflags) { ApplyBoxingConversion(node); - - if (node->HasAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING)) { - CastToString(node); - node->RemoveAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); - } - return; } @@ -1807,15 +1801,7 @@ void ETSGen::CastToString(const ir::AstNode *const node) if (sourceType->IsETSStringType()) { return; } - if (sourceType->IsETSCharType()) { - Ra().Emit(node, Signatures::BUILTIN_OBJECT_TO_STRING, dummyReg_, 0); - return; - } - if (sourceType->IsETSPrimitiveType()) { - EmitBoxingConversion(node); - } else { - ES2PANDA_ASSERT(sourceType->IsETSReferenceType()); - } + ES2PANDA_ASSERT(sourceType->IsETSReferenceType()); // caller must ensure parameter is not null Ra().Emit(node, Signatures::BUILTIN_OBJECT_TO_STRING, dummyReg_, 0); SetAccumulatorType(Checker()->GetGlobalTypesHolder()->GlobalETSStringBuiltinType()); diff --git a/ets2panda/compiler/lowering/ets/constStringToCharLowering.cpp b/ets2panda/compiler/lowering/ets/constStringToCharLowering.cpp deleted file mode 100644 index 73a1658357..0000000000 --- a/ets2panda/compiler/lowering/ets/constStringToCharLowering.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "constStringToCharLowering.h" - -#include "checker/ETSchecker.h" - -namespace ark::es2panda::compiler { - -std::string_view ConstStringToCharLowering::Name() const -{ - return "ConstStringToCharLowering"; -} - -ir::AstNode *TryConvertToCharLiteral(checker::ETSChecker *checker, ir::AstNode *ast) -{ - if (!ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOX_TO_CHAR) || !ast->IsExpression() || - ast->AsExpression()->TsType() == nullptr || !ast->AsExpression()->TsType()->IsETSStringType()) { - return nullptr; - } - - auto type = ast->AsExpression()->TsType()->AsETSStringType(); - if (!type->IsConstantType() || !type->GetValue().IsConvertibleToChar()) { - return nullptr; - } - - auto parent = ast->Parent(); - util::StringView::Iterator it(type->GetValue()); - auto value = static_cast(it.PeekCp()); - - auto newValue = checker->Allocator()->New(value); - newValue->SetParent(parent); - newValue->SetRange(ast->Range()); - if (ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR)) { - newValue->AddBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR); - } - - newValue->Check(checker); - return newValue; -} - -bool ConstStringToCharLowering::PerformForModule(public_lib::Context *const ctx, parser::Program *const program) -{ - auto *const checker = ctx->checker->AsETSChecker(); - - program->Ast()->TransformChildrenRecursively( - // CC-OFFNXT(G.FMT.14-CPP) project code style - [checker](ir::AstNode *ast) -> ir::AstNode * { - if (auto newValue = TryConvertToCharLiteral(checker, ast); newValue != nullptr) { - return newValue; - } - - return ast; - }, - Name()); - - return true; -} - -} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/constStringToCharLowering.h b/ets2panda/compiler/lowering/ets/constStringToCharLowering.h deleted file mode 100644 index e1ac39e53c..0000000000 --- a/ets2panda/compiler/lowering/ets/constStringToCharLowering.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ES2PANDA_COMPILER_LOWERING_CONST_STRING_TO_CHAR_LOWERING_H -#define ES2PANDA_COMPILER_LOWERING_CONST_STRING_TO_CHAR_LOWERING_H - -#include "compiler/lowering/phase.h" - -namespace ark::es2panda::compiler { - -class ConstStringToCharLowering : public PhaseForBodies { -public: - std::string_view Name() const override; - bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; -}; - -} // namespace ark::es2panda::compiler - -#endif // ES2PANDA_COMPILER_LOWERING_CONST_STRING_TO_CHAR_LOWERING_H diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index ab0e05cae9..df830e8780 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -170,18 +170,6 @@ static To CastValTo(const ir::Literal *lit) return static_cast(GetVal(lit)); } - if (lit->IsStringLiteral() && lit->AsStringLiteral()->Str().IsConvertibleToChar() && std::is_same_v) { - auto getChar = [](const ir::Literal *strLit) { - if (strLit->IsCharLiteral()) { - return strLit->AsCharLiteral()->Char(); - } - ES2PANDA_ASSERT(strLit->IsStringLiteral()); - util::StringView::Iterator it(strLit->AsStringLiteral()->Str()); - return static_cast(it.PeekCp()); - }; - return getChar(lit); - } - ES2PANDA_ASSERT(lit->IsNumberLiteral() || lit->IsCharLiteral()); auto rank = GetTypeRank(lit); @@ -234,12 +222,6 @@ static bool IsStringTypeReference(ir::ETSTypeReference *type) return name == "string" || name == "String"; } -static ir::AstNode *CommonCastStringToChar(const ir::Literal *lit, ArenaAllocator *allocator) -{ - auto parent = const_cast(lit)->Parent(); - return CreateCharLiteral(CastValTo(lit), parent, lit->Range(), allocator); -} - template static ir::AstNode *CommonCastNumberLiteralTo(const ir::Literal *num, ArenaAllocator *allocator) { @@ -346,14 +328,10 @@ static ir::AstNode *CastNumberOrCharLiteralFrom(const ir::Literal *lit, ir::Prim static ir::AstNode *CorrectNumberOrCharLiteral(const ir::Literal *lit, ir::PrimitiveType type, public_lib::Context *context) { - if (!lit->IsStringLiteral() && TypeRankToPrimitiveType(GetTypeRank(lit)) == type) { + if (TypeRankToPrimitiveType(GetTypeRank(lit)) == type) { return const_cast(lit); } - if (lit->IsStringLiteral() && lit->AsStringLiteral()->Str().IsConvertibleToChar()) { - return CommonCastStringToChar(lit, context->allocator); - } - switch (GetTypeRank(lit)) { case TypeRank::CHAR: return CastNumberOrCharLiteralFrom(lit, type, context); @@ -419,15 +397,6 @@ static ir::PrimitiveType GetRightTypeOfNumberOrCharLiteral(const ir::Literal *li static ir::AstNode *TryToCorrectNumberOrCharLiteral(ir::AstNode *node, public_lib::Context *context) { - if (node->IsStringLiteral()) { - auto lit = node->AsExpression()->AsLiteral(); - auto annotationType = GetTypeAnnotationFromVarDecl(lit); - if (annotationType != nullptr && annotationType->IsETSPrimitiveType() && - node->AsStringLiteral()->Str().IsConvertibleToChar()) { - return CorrectNumberOrCharLiteral(lit, ir::PrimitiveType::CHAR, context); - } - } - if (node->IsNumberLiteral() || node->IsCharLiteral()) { auto lit = node->AsExpression()->AsLiteral(); return CorrectNumberOrCharLiteral(lit, GetRightTypeOfNumberOrCharLiteral(lit), context); @@ -552,20 +521,6 @@ static ir::AstNode *HandleNumericalRelationalExpression(const ir::BinaryExpressi return CreateBooleanLiteral(res, const_cast(expr)->Parent(), expr->Range(), allocator); } -static bool HandleCharStringRelation(const ir::Literal *left, const ir::Literal *right, lexer::TokenType opType) -{ - auto getChar = [](const ir::Literal *lit) { - if (lit->IsCharLiteral()) { - return lit->AsCharLiteral()->Char(); - } - ES2PANDA_ASSERT(lit->IsStringLiteral()); - util::StringView::Iterator it(lit->AsStringLiteral()->Str()); - return static_cast(it.PeekCp()); - }; - - return PerformRelationOperation(getChar(left), getChar(right), opType); -} - static ir::AstNode *HandleNullUndefinedRelation(const ir::BinaryExpression *expr, public_lib::Context *context) { auto left = expr->Left()->AsLiteral(); @@ -636,13 +591,6 @@ static ir::AstNode *HandleRelationalExpression(const ir::BinaryExpression *expr, return HandleNullUndefinedRelation(expr, context); } - if ((left->IsCharLiteral() && right->IsStringLiteral() && right->AsStringLiteral()->Str().IsConvertibleToChar()) || - (right->IsCharLiteral() && left->IsStringLiteral() && left->AsStringLiteral()->Str().IsConvertibleToChar())) { - auto res = HandleCharStringRelation(left, right, opType); - return CreateBooleanLiteral(res, const_cast(expr)->Parent(), expr->Range(), - context->allocator); - } - LogError(context, diagnostic::WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION, {}, expr->Start()); return CreateErrorIdentifier(expr, context->allocator); } diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index e82b01fd5e..4876544d46 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -470,10 +470,6 @@ static ir::Expression *InsertPrimitiveConversionIfNeeded(UnboxContext *uctx, ir: res->TypeAnnotation()->SetRange(range); res->SetRange(range); - if (toConvert->IsETSStringType() && actualType->IsCharType()) { - res->AddAstNodeFlags(ir::AstNodeFlags::CONVERT_TO_STRING); - } - return res; } diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index b1f01312ad..b9f9b26529 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -23,7 +23,6 @@ #include "compiler/lowering/ets/boxedTypeLowering.h" #include "compiler/lowering/ets/boxingForLocals.h" #include "compiler/lowering/ets/capturedVariables.h" -#include "compiler/lowering/ets/constStringToCharLowering.h" #include "compiler/lowering/ets/constantExpressionLowering.h" #include "compiler/lowering/ets/declareOverloadLowering.h" #include "compiler/lowering/ets/cfgBuilderPhase.h" @@ -82,7 +81,6 @@ static ArrayLiteralLowering g_arrayLiteralLowering {}; static BigIntLowering g_bigintLowering; static StringConstructorLowering g_stringConstructorLowering; static ConstantExpressionLowering g_constantExpressionLowering; -static ConstStringToCharLowering g_constStringToCharLowering; static InterfacePropertyDeclarationsPhase g_interfacePropDeclPhase; // NOLINT(fuchsia-statically-constructed-objects) static EnumLoweringPhase g_enumLoweringPhase; static EnumPostCheckLoweringPhase g_enumPostCheckLoweringPhase; @@ -174,7 +172,6 @@ std::vector GetETSPhaseList() &g_bigintLowering, &g_opAssignmentLowering, &g_extensionAccessorPhase, - &g_constStringToCharLowering, &g_boxingForLocals, &g_recordLowering, &g_boxedTypeLowering, diff --git a/ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets b/ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets deleted file mode 100644 index 4d96d8de99..0000000000 --- a/ets2panda/test/runtime/ets/ImplicitCharToStringConversion.ets +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -function main(): void { - let c:char = c'X'; - let s:string = c; - - assertEQ(s, "X") -} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/boxing_1.ets b/ets2panda/test/runtime/ets/boxing_1.ets index 4dd0b40fc8..4a8f4492e8 100644 --- a/ets2panda/test/runtime/ets/boxing_1.ets +++ b/ets2panda/test/runtime/ets/boxing_1.ets @@ -26,13 +26,13 @@ class A { } function main(): void { - assertEQ(global_Int_.intValue(), 2_000_000) - assertEQ((global_Object_Int_ as Int).intValue(), 2_000_001) - assertEQ(const_global_Int_.intValue(), 2_000_002) - assertEQ((const_global_Object_Int_ as Int).intValue(), 2_000_003) + assertEQ(global_Int_.toInt(), 2_000_000) + assertEQ((global_Object_Int_ as Int).toInt(), 2_000_001) + assertEQ(const_global_Int_.toInt(), 2_000_002) + assertEQ((const_global_Object_Int_ as Int).toInt(), 2_000_003) - assertEQ(A.Int_.intValue(), 2_000_004) - assertEQ((A.Object_Int_ as Int).intValue(), 2_000_005) - assertEQ(A.readonly_Int_.intValue(), 2_000_006) - assertEQ((A.readonly_Object_Int_ as Int).intValue(), 2_000_007) + assertEQ(A.Int_.toInt(), 2_000_004) + assertEQ((A.Object_Int_ as Int).toInt(), 2_000_005) + assertEQ(A.readonly_Int_.toInt(), 2_000_006) + assertEQ((A.readonly_Object_Int_ as Int).toInt(), 2_000_007) } diff --git a/ets2panda/test/runtime/ets/charToStringCast.ets b/ets2panda/test/runtime/ets/charToStringCast.ets index 0d4ed953f3..1fe3d11813 100644 --- a/ets2panda/test/runtime/ets/charToStringCast.ets +++ b/ets2panda/test/runtime/ets/charToStringCast.ets @@ -14,7 +14,7 @@ */ function main(): void { - let s:string = c'X' as string; + let s:string = c'X'.toString(); assertEQ(s, "X") -} \ No newline at end of file +} diff --git a/ets2panda/test/runtime/ets/primitive_to_boxed.ets b/ets2panda/test/runtime/ets/primitive_to_boxed.ets index 15e7c37f59..b81a523121 100644 --- a/ets2panda/test/runtime/ets/primitive_to_boxed.ets +++ b/ets2panda/test/runtime/ets/primitive_to_boxed.ets @@ -26,7 +26,7 @@ function fooShort() : Short { } function fooChar() : Char { - return "c"; + return c'c'; } @@ -66,7 +66,7 @@ function main() { let val2 : Short = fooShort() assertEQ(val2, c2) - let c3 : Char = 'c'; + let c3 : Char = c'c'; let val3 : Char = fooChar() assertEQ(val3, c3) @@ -82,7 +82,7 @@ function main() { let val6 : Float = fooFloat() assertEQ(val6, c6) - + let c7 : Double = 1; let val7 : Double = fooDouble() assertEQ(val7, c7) @@ -90,4 +90,4 @@ function main() { let c8 : Color = Color.Green; let val8 : Color = fooEnum(); assertEQ(c8, val8) -} \ No newline at end of file +} diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index 7d0bcb90f6..37923997cf 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -128,3 +128,4 @@ enum-relational-operators.ets local-enum-relational-operators.ets rest_object_literal.ets union_generic_class.ets +stringliteral_to_char.ets diff --git a/ets2panda/util/ustring.cpp b/ets2panda/util/ustring.cpp index 7a8d1ace6d..4d4f7a0e1f 100644 --- a/ets2panda/util/ustring.cpp +++ b/ets2panda/util/ustring.cpp @@ -80,14 +80,6 @@ void StringView::Iterator::SkipCp() } } -bool StringView::IsConvertibleToChar() const -{ - Iterator it(*this); - size_t size = 0; - char32_t ch = it.PeekCp(&size); - return size == Length() && ch != Iterator::INVALID_CP; -} - } // namespace ark::es2panda::util // NOLINTNEXTLINE(cert-dcl58-cpp) diff --git a/ets2panda/util/ustring.h b/ets2panda/util/ustring.h index a1fc97e97d..d5d44e41b0 100644 --- a/ets2panda/util/ustring.h +++ b/ets2panda/util/ustring.h @@ -156,8 +156,6 @@ public: template static void Mutf8Encode(T *str, char32_t cu); - bool IsConvertibleToChar() const; - class Iterator { public: static char32_t constexpr INVALID_CP = std::numeric_limits::max(); -- Gitee From 5071eea07169e91b467d9f7b6609d8522285e427 Mon Sep 17 00:00:00 2001 From: Zhelyapov Aleksey Date: Wed, 23 Apr 2025 18:48:01 +0300 Subject: [PATCH 09/12] Removed cast Union to primitive Signed-off-by: Zhelyapov Aleksey --- ets2panda/checker/types/ets/etsUnionType.cpp | 59 ----------------- ets2panda/checker/types/ets/etsUnionType.h | 3 - .../compiler/lowering/ets/unionLowering.cpp | 64 ------------------- 3 files changed, 126 deletions(-) diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index 2652ec4908..a901f975b5 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -635,50 +635,6 @@ Type *ETSUnionType::FindTypeIsCastableToThis(ir::Expression *node, TypeRelation return nullptr; } -Type *ETSUnionType::FindTypeIsCastableToSomeType(ir::Expression *node, TypeRelation *relation, Type *target) const -{ - ES2PANDA_ASSERT(node); - bool nodeWasSet = false; - if (relation->GetNode() == nullptr) { - nodeWasSet = true; - relation->SetNode(node); - relation->SetFlags(TypeRelationFlag::CASTING_CONTEXT); - } - auto isCastablePred = [](TypeRelation *r, Type *sourceType, Type *targetType) { - if (targetType->IsETSUnionType()) { - auto *foundTargetType = targetType->AsETSUnionType()->FindTypeIsCastableToThis(r->GetNode(), r, sourceType); - r->Result(foundTargetType != nullptr); - } else { - r->IsCastableTo(sourceType, targetType); - } - return r->IsTrue(); - }; - // Prioritize object to object conversion - auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), - [relation, target, &isCastablePred](Type *source) { - return isCastablePred(relation, source, target) && source->IsETSReferenceType() && - target->IsETSReferenceType(); - }); // CC-OFF(G.FMT.02) project code style - if (it != constituentTypes_.end()) { - if (nodeWasSet) { - relation->SetNode(nullptr); - relation->RemoveFlags(TypeRelationFlag::CASTING_CONTEXT); - } - return *it; - } - it = std::find_if( - constituentTypes_.begin(), constituentTypes_.end(), - [relation, target, &isCastablePred](Type *source) { return isCastablePred(relation, source, target); }); - if (nodeWasSet) { - relation->SetNode(nullptr); - relation->RemoveFlags(TypeRelationFlag::CASTING_CONTEXT); - } - if (it != constituentTypes_.end()) { - return *it; - } - return nullptr; -} - Type *ETSUnionType::FindUnboxableType() const { auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), @@ -697,21 +653,6 @@ bool ETSUnionType::HasObjectType(ETSObjectFlags flag) const return it != constituentTypes_.end(); } -Type *ETSUnionType::FindExactOrBoxedType(ETSChecker *checker, Type *const type) const -{ - auto it = std::find_if(constituentTypes_.begin(), constituentTypes_.end(), [checker, type](Type *ct) { - if (ct->IsETSUnboxableObject()) { - auto *const unboxedCt = checker->MaybeUnboxInRelation(ct); - return unboxedCt == type; - } - return ct == type; - }); - if (it != constituentTypes_.end()) { - return *it; - } - return nullptr; -} - bool ETSUnionType::HasType(Type *type) const { for (const auto &cType : constituentTypes_) { diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index 5cbf51a099..962abbe0ce 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -46,7 +46,6 @@ public: void IsSubtypeOf(TypeRelation *relation, Type *target) override; void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; Type *FindTypeIsCastableToThis(ir::Expression *node, TypeRelation *relation, Type *source) const; - Type *FindTypeIsCastableToSomeType(ir::Expression *node, TypeRelation *relation, Type *target) const; Type *FindUnboxableType() const; bool HasObjectType(ETSObjectFlags flag) const; @@ -54,8 +53,6 @@ public: bool IsOverlapWith(TypeRelation *relation, Type *type); - Type *FindExactOrBoxedType(ETSChecker *checker, Type *type) const; - static void NormalizeTypes(TypeRelation *relation, ArenaVector &types); static ArenaVector GetNonConstantTypes(ETSChecker *checker, const ArenaVector &types); diff --git a/ets2panda/compiler/lowering/ets/unionLowering.cpp b/ets2panda/compiler/lowering/ets/unionLowering.cpp index 8b94066abc..c409aeca04 100644 --- a/ets2panda/compiler/lowering/ets/unionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unionLowering.cpp @@ -203,64 +203,6 @@ static void HandleUnionPropertyAccess(checker::ETSChecker *checker, varbinder::V ES2PANDA_ASSERT(expr->PropVar() != nullptr); } -static ir::TSAsExpression *GenAsExpression(checker::ETSChecker *checker, checker::Type *const opaqueType, - ir::Expression *const node, ir::AstNode *const parent) -{ - auto *const typeNode = checker->AllocNode(opaqueType, checker->Allocator()); - auto *const asExpression = checker->AllocNode(node, typeNode, false); - asExpression->SetParent(parent); - asExpression->Check(checker); - return asExpression; -} - -/* - * Function that generates conversion from (union) to (primitive) type as to `as` expressions: - * (union) as (prim) => ((union) as (ref)) as (prim), - * where (ref) is some unboxable type from union constituent types. - * Finally, `(union) as (prim)` expression replaces union_node that came above. - */ -static ir::TSAsExpression *UnionCastToPrimitive(checker::ETSChecker *checker, checker::ETSObjectType *unboxableRef, - checker::Type *unboxedPrim, ir::Expression *unionNode) -{ - auto *const unionAsRefExpression = GenAsExpression(checker, unboxableRef, unionNode, nullptr); - return GenAsExpression(checker, unboxedPrim, unionAsRefExpression, unionNode->Parent()); -} - -static ir::TSAsExpression *HandleUnionCastToPrimitive(checker::ETSChecker *checker, ir::TSAsExpression *expr) -{ - auto *const unionType = expr->Expr()->TsType()->AsETSUnionType(); - auto *sourceType = unionType->FindExactOrBoxedType(checker, expr->TsType()); - if (sourceType == nullptr) { - sourceType = unionType->AsETSUnionType()->FindTypeIsCastableToSomeType(expr->Expr(), checker->Relation(), - expr->TsType()); - } - - if (sourceType != nullptr && expr->Expr()->GetBoxingUnboxingFlags() != ir::BoxingUnboxingFlags::NONE) { - auto *maybeUnboxingType = checker->MaybeUnboxInRelation(sourceType); - // when sourceType get `object`, it could cast to any primitive type but can't be unboxed; - if (maybeUnboxingType != nullptr && expr->TsType()->IsETSPrimitiveType()) { - auto *const asExpr = GenAsExpression(checker, sourceType, expr->Expr(), expr); - asExpr->SetBoxingUnboxingFlags(checker->GetUnboxingFlag(maybeUnboxingType)); - expr->Expr()->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); - expr->SetExpr(asExpr); - } - - return expr; - } - - auto *const unboxableUnionType = sourceType != nullptr ? sourceType : unionType->FindUnboxableType(); - auto *const unboxedUnionType = checker->MaybeUnboxInRelation(unboxableUnionType); - if (unboxableUnionType == nullptr || !unboxableUnionType->IsETSObjectType() || unboxedUnionType == nullptr) { - return expr; - } - - auto *const node = - UnionCastToPrimitive(checker, unboxableUnionType->AsETSObjectType(), unboxedUnionType, expr->Expr()); - node->SetParent(expr->Parent()); - - return node; -} - bool UnionLowering::PerformForModule(public_lib::Context *ctx, parser::Program *program) { checker::ETSChecker *checker = ctx->checker->AsETSChecker(); @@ -276,12 +218,6 @@ bool UnionLowering::PerformForModule(public_lib::Context *ctx, parser::Program * return ast; } } - if (ast->IsTSAsExpression() && ast->AsTSAsExpression()->Expr()->TsType() != nullptr && - ast->AsTSAsExpression()->Expr()->TsType()->IsETSUnionType() && - ast->AsTSAsExpression()->TsType() != nullptr && - ast->AsTSAsExpression()->TsType()->IsETSPrimitiveType()) { - return HandleUnionCastToPrimitive(checker, ast->AsTSAsExpression()); - } return ast; }, -- Gitee From 1f35f0f730cd0a982f806ef0a4e3a084cf6d0327 Mon Sep 17 00:00:00 2001 From: aakmaev Date: Thu, 24 Apr 2025 13:49:23 +0300 Subject: [PATCH 10/12] Fix tests after intrinsics Signed-off-by: Akmaev Aleksey --- .../ast/parser/ets/keyof_predefined_type.ets | 4 ++-- ets2panda/test/runtime/ets/CastReference.ets | 2 +- .../test/runtime/ets/RecordKeyTypeCheck.ets | 22 ++++++++--------- .../test/runtime/ets/UnaryExpression.ets | 4 ++-- .../test/runtime/ets/UpdateExpression.ets | 24 +++++++++---------- .../test/runtime/ets/keyof_primitive_type.ets | 12 +++++----- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets b/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets index 4d006cbe63..ca91aaa14d 100644 --- a/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets +++ b/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets @@ -18,5 +18,5 @@ function main():void{ let c2:keyof Int = /* @@ label2 */"field1" } -/* @@@ label1 Error TypeError: Type '"field1"' cannot be assigned to type '"$_hashCode"|"add"|"unboxed"|"isGreaterThan"|"compareTo"|"createFromJSONValue"|"isLessEqualThan"|"mul"|"doubleValue"|"toString"|"byteValue"|"isLessThan"|"shortValue"|"sub"|"intValue"|"div"|"floatValue"|"equals"|"longValue"|"isGreaterEqualThan"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ -/* @@@ label2 Error TypeError: Type '"field1"' cannot be assigned to type '"$_hashCode"|"add"|"unboxed"|"isGreaterThan"|"compareTo"|"createFromJSONValue"|"isLessEqualThan"|"mul"|"doubleValue"|"toString"|"byteValue"|"isLessThan"|"shortValue"|"sub"|"intValue"|"div"|"floatValue"|"equals"|"longValue"|"isGreaterEqualThan"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ +/* @@@ label1 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"$_hashCode"|"add"|"toByte"|"unboxed"|"isGreaterThan"|"compareTo"|"toLong"|"createFromJSONValue"|"isLessEqualThan"|"isLessThan"|"toFloat"|"toString"|"mul"|"sub"|"isGreaterEqualThan"|"equals"|"div"|"toInt"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ +/* @@@ label2 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"$_hashCode"|"add"|"toByte"|"unboxed"|"isGreaterThan"|"compareTo"|"toLong"|"createFromJSONValue"|"isLessEqualThan"|"isLessThan"|"toFloat"|"toString"|"mul"|"sub"|"isGreaterEqualThan"|"equals"|"div"|"toInt"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ diff --git a/ets2panda/test/runtime/ets/CastReference.ets b/ets2panda/test/runtime/ets/CastReference.ets index e5bab15d39..e2adc3233a 100644 --- a/ets2panda/test/runtime/ets/CastReference.ets +++ b/ets2panda/test/runtime/ets/CastReference.ets @@ -97,7 +97,7 @@ function primitive_reference_test(): void { let int_: int = 42; let Int_ = int_ as Int; assertTrue(Int_ instanceof Int) - assertEQ(Int_.intValue(), 42) + assertEQ(Int_.toInt(), 42) assertEQ(Int_.add(1) as int, 43) } diff --git a/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets b/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets index df06bcf254..55e80f6b07 100644 --- a/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets +++ b/ets2panda/test/runtime/ets/RecordKeyTypeCheck.ets @@ -24,28 +24,28 @@ class A extends Numeric { this.value = value; } - public override byteValue(): byte { - return this.value as byte; + public override toByte(): byte { + return Int.toByte(this.value); } - public override shortValue(): short { - return this.value as short; + public override toShort(): short { + return Int.toShort(this.value); } - public override intValue(): int { + public override toInt(): int { return this.value; } - public override longValue(): long { - return this.value as long; + public override toLong(): long { + return Int.toLong(this.value); } - public override floatValue(): float { - return this.value as float; + public override toFloat(): float { + return Int.toFloat(this.value); } - public override doubleValue(): double { - return this.value as double; + public override toDouble(): double { + return Int.toDouble(this.value); } public override toString(): String { diff --git a/ets2panda/test/runtime/ets/UnaryExpression.ets b/ets2panda/test/runtime/ets/UnaryExpression.ets index 9e62a100e6..2b6bf0bc21 100644 --- a/ets2panda/test/runtime/ets/UnaryExpression.ets +++ b/ets2panda/test/runtime/ets/UnaryExpression.ets @@ -49,7 +49,7 @@ function main(): void { a = -a; assertEQ(a, -30.0) - assertEQ(a.doubleValue(), -30.0) + assertEQ(a.toDouble(), -30.0) let c = +a; assertEQ(c, -30.0) @@ -64,7 +64,7 @@ function main(): void { a = -a; assertEQ(a, -40) - assertEQ(a.intValue(), -40) + assertEQ(a.toInt(), -40) let c = +a; assertEQ(c, -40) diff --git a/ets2panda/test/runtime/ets/UpdateExpression.ets b/ets2panda/test/runtime/ets/UpdateExpression.ets index edefa18467..7c764d28ce 100644 --- a/ets2panda/test/runtime/ets/UpdateExpression.ets +++ b/ets2panda/test/runtime/ets/UpdateExpression.ets @@ -40,30 +40,30 @@ function main(): void { let a: Double = new Double(30.0); let b = ++a; assertEQ(a, 31.0) - assertEQ(a.doubleValue(), 31.0) + assertEQ(a.toDouble(), 31.0) assertEQ(b, 31.0) - assertEQ(b.doubleValue(), 31.0) + assertEQ(b.toDouble(), 31.0) - assertEQ((++a).doubleValue(), 32.0) + assertEQ((++a).toDouble(), 32.0) assertEQ(a, 32.0) - assertEQ(a.doubleValue(), 32.0) + assertEQ(a.toDouble(), 32.0) assertEQ(b, 31.0) - assertEQ(b.doubleValue(), 31.0) + assertEQ(b.toDouble(), 31.0) } { let a: Int = new Int(40); let b = a++; assertEQ(a, 41) - assertEQ(a.intValue(), 41) + assertEQ(a.toInt(), 41) assertEQ(b, 40) - assertEQ(b.intValue(), 40) + assertEQ(b.toInt(), 40) - assertEQ((a++).intValue(), 41) + assertEQ((a++).toInt(), 41) assertEQ(a, 42) - assertEQ(a.intValue(), 42) + assertEQ(a.toInt(), 42) assertEQ(b, 40) - assertEQ(b.intValue(), 40) + assertEQ(b.toInt(), 40) } { @@ -71,9 +71,9 @@ function main(): void { let a: Int = new Int(50); let b = fn(a++); assertEQ(a, 51) - assertEQ(a.intValue(), 51) + assertEQ(a.toInt(), 51) assertEQ(b, 50) - assertEQ(b.intValue(), 50) + assertEQ(b.toInt(), 50) assertEQ(fn(++a), 52) assertEQ(a, 52) diff --git a/ets2panda/test/runtime/ets/keyof_primitive_type.ets b/ets2panda/test/runtime/ets/keyof_primitive_type.ets index fdbaed33b7..bb93cec92d 100644 --- a/ets2panda/test/runtime/ets/keyof_primitive_type.ets +++ b/ets2panda/test/runtime/ets/keyof_primitive_type.ets @@ -18,10 +18,10 @@ function main() : void { let c2:keyof number = "toPrecision" let c3:keyof number = "toLocaleString" let c4:keyof boolean = "valueOf" - let c5:keyof byte = "byteValue" - let c6:keyof short = "shortValue" - let c7:keyof int = "intValue" - let c8:keyof long = "longValue" - let c9:keyof float = "floatValue" - let c10:keyof double = "doubleValue" + let c5:keyof byte = "toByte" + let c6:keyof short = "toShort" + let c7:keyof int = "toInt" + let c8:keyof long = "toLong" + let c9:keyof float = "toFloat" + let c10:keyof double = "toDouble" } -- Gitee From a9ec0555bc7b93a1cc62b2513b287f33039eda69 Mon Sep 17 00:00:00 2001 From: Maxim Bolshov Date: Thu, 24 Apr 2025 14:58:56 +0300 Subject: [PATCH 11/12] Add folded flag to Literal node Signed-off-by: Maxim Bolshov --- .../lowering/ets/constantExpressionLowering.cpp | 3 +++ ets2panda/ir/expressions/literal.h | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index df830e8780..39e33dfc10 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -32,6 +32,7 @@ static ir::BooleanLiteral *CreateBooleanLiteral(bool val, ir::AstNode *parent, c auto resNode = util::NodeAllocator::Alloc(allocator, val); resNode->SetParent(parent); resNode->SetRange(loc); + resNode->SetFolded(); return resNode; } @@ -48,6 +49,7 @@ static ir::NumberLiteral *CreateNumberLiteral(T val, ir::AstNode *parent, const resNode->SetParent(parent); resNode->SetRange(loc); + resNode->SetFolded(); return resNode; } @@ -67,6 +69,7 @@ static ir::CharLiteral *CreateCharLiteral(char16_t val, ir::AstNode *parent, con auto *result = util::NodeAllocator::Alloc(allocator, val); result->SetParent(parent); result->SetRange(loc); + result->SetFolded(); return result; } diff --git a/ets2panda/ir/expressions/literal.h b/ets2panda/ir/expressions/literal.h index e4ad8c033a..b8e7ea3b86 100644 --- a/ets2panda/ir/expressions/literal.h +++ b/ets2panda/ir/expressions/literal.h @@ -32,8 +32,21 @@ public: return true; } + [[nodiscard]] bool IsFolded() const noexcept + { + return folded_; + } + + void SetFolded(bool folded = true) noexcept + { + folded_ = folded; + } + protected: explicit Literal(AstNodeType const type) : Expression(type) {} + +private: + bool folded_ = false; }; } // namespace ark::es2panda::ir -- Gitee From 3e0f80be28a0281df2a1c4d22ae0d76c89d79118 Mon Sep 17 00:00:00 2001 From: Daniel Kofanov Date: Fri, 25 Apr 2025 03:06:53 +0800 Subject: [PATCH 12/12] Fixup enum Also forbid 'lexer::Number' to implicitly infer '(int8_t) 0' value --- ets2panda/checker/ets/arithmetic.cpp | 188 +++++------------- .../compiler/lowering/ets/enumLowering.cpp | 28 +-- .../compiler/lowering/ets/enumLowering.h | 3 +- .../lowering/ets/enumPostCheckLowering.cpp | 2 +- .../lowering/ets/stringComparison.cpp | 2 +- .../compiler/lowering/ets/unboxLowering.cpp | 2 +- .../methodBuilder.cpp | 3 +- .../ir/expressions/literals/numberLiteral.h | 1 - ets2panda/lexer/token/number.h | 36 ++-- 9 files changed, 84 insertions(+), 181 deletions(-) diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index e488b24ddf..ba6cb5e753 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -736,14 +736,6 @@ static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOper return checker->CreateETSUnionType({typeL, typeR}); } - if (typeL->IsETSEnumType() && typeR->IsETSEnumType()) { - if (!checker->Relation()->IsIdenticalTo(typeL, typeR)) { - checker->LogError(diagnostic::BINOP_INCOMPARABLE, {}, expr->Start()); - return checker->GlobalTypeError(); - } - return typeL; - } - if (typeL->IsETSReferenceType() && typeR->IsETSReferenceType()) { checker->Relation()->SetNode(expr->Left()); if (!checker->CheckValidEqualReferenceType(typeL, typeR)) { @@ -769,8 +761,6 @@ static Type *CheckBinaryOperatorEqual(ETSChecker *checker, BinaryArithmOperands { [[maybe_unused]] auto const [expr, typeL, typeR, reducedL, reducedR] = ops; - expr->Left()->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - expr->Right()->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); if (typeL->IsTypeError()) { // both are errors return checker->GlobalTypeError(); } @@ -986,6 +976,7 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, checker::Type *const leftType = typeParams.leftType; checker::Type *const rightType = typeParams.rightType; checker::Type *tsType {}; + BinaryArithmOperands ops = GetBinaryOperands(checker, binaryParams.expr->AsBinaryExpression()); BinaryArithmOperands opsRepaired = RepairTypeErrorsInOperands(ops); @@ -1029,148 +1020,67 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, return {tsType, tsType}; } -namespace { - -bool IsEnum(const ir::Expression *expr) +static void TryAddValueOfFlagToStringEnumOperand(ir::Expression *op, const ir::Expression *otherOp) { - if (expr == nullptr) { - return false; - } - - auto type = expr->TsType(); - if (type == nullptr) { - return false; + auto type = op->TsType(); + auto otherType = otherOp->TsType(); + if (type->IsETSStringEnumType() && (otherType->IsETSStringType() || otherType->IsETSStringEnumType())) { + op->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); } - - return type->IsETSEnumType(); } -bool IsStringEnum(const ir::Expression *expr) +static void TryAddValueOfFlagToIntEnumOperand(ir::Expression *op) { - if (expr == nullptr) { - return false; + if (op->TsType()->IsETSIntEnumType()) { + op->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); } - - auto type = expr->TsType(); - if (type == nullptr) { - return false; - } - - return type->IsETSStringEnumType(); } -bool IsIntEnum(const ir::Expression *expr) +static void CheckEnumInOperatorContext(ir::Expression *expression, lexer::TokenType opType, ir::Expression *left, + ir::Expression *right, ETSChecker *checker) { - if (expr == nullptr) { - return false; - } + auto [lType, rType] = std::tuple {left->TsType(), right->TsType()}; - auto type = expr->TsType(); - if (type == nullptr) { - return false; - } - - return type->IsETSIntEnumType(); -} - -bool CheckNumericOperatorContext(ir::Expression *expression, lexer::TokenType op) -{ - const bool isMultiplicative = op == lexer::TokenType::PUNCTUATOR_MULTIPLY || - op == lexer::TokenType::PUNCTUATOR_DIVIDE || op == lexer::TokenType::PUNCTUATOR_MOD; - const bool isAdditive = op == lexer::TokenType::PUNCTUATOR_PLUS || op == lexer::TokenType::PUNCTUATOR_MINUS; - const bool isShift = op == lexer::TokenType::PUNCTUATOR_LEFT_SHIFT || - op == lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT || - op == lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT; - const bool isRelational = - op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; - const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - const bool isBitwise = op == lexer::TokenType::PUNCTUATOR_BITWISE_AND || - op == lexer::TokenType::PUNCTUATOR_BITWISE_OR || - op == lexer::TokenType::PUNCTUATOR_BITWISE_XOR; - const bool isConditionalAndOr = - op == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || op == lexer::TokenType::PUNCTUATOR_LOGICAL_OR; - - if (IsIntEnum(expression)) { - if (isMultiplicative || isAdditive || isShift || isRelational || isEquality || isBitwise || - isConditionalAndOr) { - expression->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + switch (opType) { + case lexer::TokenType::PUNCTUATOR_GREATER_THAN: + case lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL: + case lexer::TokenType::PUNCTUATOR_LESS_THAN: + case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: + case lexer::TokenType::PUNCTUATOR_EQUAL: + case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { + if (lType->IsETSEnumType() && rType->IsETSEnumType() && !checker->Relation()->IsIdenticalTo(lType, rType)) { + checker->LogError(diagnostic::BINOP_INCOMPARABLE, {}, expression->Start()); + return; + } + [[fallthrough]]; } - return true; - } - return false; -} - -void CheckStringOperatorContext(ir::Expression *expression, checker::Type *otherType, lexer::TokenType op) -{ - const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - const bool isRelational = - op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; - if (IsStringEnum(expression) && (otherType->IsETSStringType() || otherType->IsETSStringEnumType())) { - if (op == lexer::TokenType::PUNCTUATOR_PLUS || isRelational || isEquality) { - expression->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + case lexer::TokenType::PUNCTUATOR_PLUS: { + TryAddValueOfFlagToStringEnumOperand(left, right); + TryAddValueOfFlagToStringEnumOperand(right, left); + [[fallthrough]]; } + case lexer::TokenType::PUNCTUATOR_MULTIPLY: + case lexer::TokenType::PUNCTUATOR_DIVIDE: + case lexer::TokenType::PUNCTUATOR_MOD: + case lexer::TokenType::PUNCTUATOR_MINUS: + case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: + case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: + case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: + case lexer::TokenType::PUNCTUATOR_BITWISE_AND: + case lexer::TokenType::PUNCTUATOR_BITWISE_OR: + case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: + case lexer::TokenType::PUNCTUATOR_LOGICAL_AND: + case lexer::TokenType::PUNCTUATOR_LOGICAL_OR: { + TryAddValueOfFlagToIntEnumOperand(left); + TryAddValueOfFlagToIntEnumOperand(right); + break; + } + default: + // NOTE(dkofanov): What about the '+=' operation? + break; } } -bool CheckRelationalOperatorsBetweenEnums(ETSChecker *checker, ir::BinaryExpression *expr) -{ - auto left = expr->Left(); - auto right = expr->Right(); - auto op = expr->OperatorType(); - - if (!IsEnum(left) || !IsEnum(right)) { - return false; - } - - if (!checker->Relation()->IsIdenticalTo(left->TsType(), right->TsType())) { - checker->LogError(diagnostic::BINOP_INCOMPARABLE, {}, expr->Start()); - return false; - } - - const bool isRelational = - op == lexer::TokenType::PUNCTUATOR_GREATER_THAN || op == lexer::TokenType::PUNCTUATOR_GREATER_THAN_EQUAL || - op == lexer::TokenType::PUNCTUATOR_LESS_THAN || op == lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL; - const bool isEquality = op == lexer::TokenType::PUNCTUATOR_EQUAL || op == lexer::TokenType::PUNCTUATOR_NOT_EQUAL; - - if (isRelational || isEquality) { - left->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - right->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - return true; - } - return false; -} - -void CheckNeedToGenerateGetValueForBinaryExpression(ir::Expression *expression, ETSChecker *checker) -{ - if (!expression->IsBinaryExpression()) { - return; - } - - auto binaryExpression = expression->AsBinaryExpression(); - auto op = binaryExpression->OperatorType(); - auto leftExp = binaryExpression->Left(); - auto rightExp = binaryExpression->Right(); - - // Numeric Operator Context - auto leftIsIntEnum = CheckNumericOperatorContext(leftExp, op); - auto rightIsIntEnum = CheckNumericOperatorContext(rightExp, op); - if (leftIsIntEnum || rightIsIntEnum) { - return; - } - - // String Operator Context - CheckStringOperatorContext(leftExp, rightExp->TsType(), op); - CheckStringOperatorContext(rightExp, leftExp->TsType(), op); - - // Relational operators if both are enumeration Types - if (CheckRelationalOperatorsBetweenEnums(checker, expression->AsBinaryExpression())) { - return; - } -} -} // namespace - std::tuple ETSChecker::CheckArithmeticOperations( ir::Expression *expr, std::tuple op, bool isEqualOp, std::tuple types) @@ -1185,6 +1095,7 @@ std::tuple ETSChecker::CheckArithmeticOperations( if (rightType->IsETSUnionType()) { rightType = GetNonConstantType(rightType); } + CheckEnumInOperatorContext(expr, operationType, left, right, this); auto checkMap = GetCheckMap(); if (checkMap.find(operationType) != checkMap.end()) { @@ -1201,7 +1112,6 @@ std::tuple ETSChecker::CheckArithmeticOperations( return {tsType, tsType}; } - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return CheckBinaryOperatorHelper(this, {left, right, expr, operationType, pos, isEqualOp}, {leftType, rightType, unboxedL, unboxedR}); } @@ -1250,8 +1160,6 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, return {leftType, leftType}; } - CheckNeedToGenerateGetValueForBinaryExpression(expr, this); - const bool isLogicalExtendedOperator = (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_AND) || (operationType == lexer::TokenType::PUNCTUATOR_LOGICAL_OR); Type *unboxedL = diff --git a/ets2panda/compiler/lowering/ets/enumLowering.cpp b/ets2panda/compiler/lowering/ets/enumLowering.cpp index 213f565763..1bb5c1f806 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumLowering.cpp @@ -164,6 +164,7 @@ template void EnumLoweringPhase::CreateEnumItemFields(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *const enumClass, EnumType enumType) { + static_assert(ORDINAL_TYPE == ir::PrimitiveType::INT); int32_t ordinal = 0; auto createEnumItemField = [this, enumClass, enumType, &ordinal](ir::TSEnumMember *const member) { auto *const enumMemberIdent = @@ -327,7 +328,7 @@ void EnumLoweringPhase::CreateCCtorForEnumClass(ir::ClassDefinition *const enumC ir::ClassProperty *EnumLoweringPhase::CreateOrdinalField(ir::ClassDefinition *const enumClass) { auto *const fieldIdent = Allocator()->New(ORDINAL_NAME, Allocator()); - auto *const intTypeAnnotation = Allocator()->New(ir::PrimitiveType::INT, Allocator()); + auto *const intTypeAnnotation = Allocator()->New(ORDINAL_TYPE, Allocator()); auto *field = checker_->AllocNode(fieldIdent, nullptr, intTypeAnnotation, ir::ModifierFlags::PRIVATE | ir::ModifierFlags::READONLY, Allocator(), false); @@ -342,7 +343,7 @@ ir::ScriptFunction *EnumLoweringPhase::CreateFunctionForCtorOfEnumClass(ir::Clas { ArenaVector params(Allocator()->Adapter()); - auto *const intTypeAnnotation = checker_->AllocNode(ir::PrimitiveType::INT, Allocator()); + auto *const intTypeAnnotation = checker_->AllocNode(ORDINAL_TYPE, Allocator()); auto *const inputOrdinalParam = MakeFunctionParam(checker_, PARAM_ORDINAL, intTypeAnnotation); params.push_back(inputOrdinalParam); @@ -787,10 +788,11 @@ void EnumLoweringPhase::CreateEnumGetNameMethod(const ir::TSEnumDeclaration *con namespace { -ir::VariableDeclaration *CreateForLoopInitVariableDeclaration(checker::ETSChecker *checker, - ir::Identifier *const loopIdentifier) +static ir::VariableDeclaration *CreateForLoopInitVariableDeclaration(checker::ETSChecker *checker, + ir::Identifier *const loopIdentifier) { - auto *const init = checker->AllocNode("0"); + static_assert(EnumLoweringPhase::ORDINAL_TYPE == ir::PrimitiveType::INT); + auto *const init = checker->AllocNode(lexer::Number((int32_t)0)); auto *const decl = checker->AllocNode(ir::VariableDeclaratorFlag::LET, loopIdentifier, init); loopIdentifier->SetParent(decl); @@ -802,9 +804,9 @@ ir::VariableDeclaration *CreateForLoopInitVariableDeclaration(checker::ETSChecke return declaration; } -ir::BinaryExpression *CreateForLoopTest(checker::ETSChecker *checker, ir::Identifier *const enumClassIdentifier, - ir::Identifier *const namesArrayIdentifier, - ir::Identifier *const loopIdentifier) +static ir::BinaryExpression *CreateForLoopTest(checker::ETSChecker *checker, ir::Identifier *const enumClassIdentifier, + ir::Identifier *const namesArrayIdentifier, + ir::Identifier *const loopIdentifier) { auto *const lengthIdent = checker->AllocNode("length", checker->Allocator()); auto *const propertyAccessExpr = @@ -817,7 +819,7 @@ ir::BinaryExpression *CreateForLoopTest(checker::ETSChecker *checker, ir::Identi return binaryExpr; } -ir::UpdateExpression *CreateForLoopUpdate(checker::ETSChecker *checker, ir::Identifier *const loopIdentifier) +static ir::UpdateExpression *CreateForLoopUpdate(checker::ETSChecker *checker, ir::Identifier *const loopIdentifier) { auto *const forLoopIdentClone = loopIdentifier->Clone(checker->Allocator(), nullptr); auto *const incrementExpr = @@ -825,9 +827,9 @@ ir::UpdateExpression *CreateForLoopUpdate(checker::ETSChecker *checker, ir::Iden return incrementExpr; } -ir::IfStatement *CreateIf(checker::ETSChecker *checker, ir::MemberExpression *propertyAccessExpr, - ir::MemberExpression *itemAccessExpr, ir::Identifier *const loopIdentifier, - ir::ETSParameterExpression *const parameter) +static ir::IfStatement *CreateIf(checker::ETSChecker *checker, ir::MemberExpression *propertyAccessExpr, + ir::MemberExpression *itemAccessExpr, ir::Identifier *const loopIdentifier, + ir::ETSParameterExpression *const parameter) { auto *const forLoopIdentClone1 = loopIdentifier->Clone(checker->Allocator(), nullptr); auto *const namesArrayElementExpr = checker->AllocNode( @@ -968,7 +970,7 @@ void EnumLoweringPhase::CreateEnumGetOrdinalMethod(const ir::TSEnumDeclaration * body.push_back(returnStmt); ArenaVector params(Allocator()->Adapter()); - auto *const intTypeAnnotation = Allocator()->New(ir::PrimitiveType::INT, Allocator()); + auto *const intTypeAnnotation = Allocator()->New(ORDINAL_TYPE, Allocator()); auto *const function = MakeFunction({std::move(params), std::move(body), intTypeAnnotation, enumDecl, ir::ModifierFlags::PUBLIC}); diff --git a/ets2panda/compiler/lowering/ets/enumLowering.h b/ets2panda/compiler/lowering/ets/enumLowering.h index e62fb133c2..c1ab9c989c 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.h +++ b/ets2panda/compiler/lowering/ets/enumLowering.h @@ -33,8 +33,9 @@ public: static constexpr std::string_view STRING_VALUES_ARRAY_NAME {checker::ETSEnumType::STRING_VALUES_ARRAY_NAME}; static constexpr std::string_view NAMES_ARRAY_NAME {checker::ETSEnumType::NAMES_ARRAY_NAME}; static constexpr std::string_view VALUES_ARRAY_NAME {checker::ETSEnumType::VALUES_ARRAY_NAME}; - static constexpr std::string_view ORDINAL_NAME {"#ordinal"}; static constexpr std::string_view BASE_CLASS_NAME {"BaseEnum"}; + static constexpr std::string_view ORDINAL_NAME {"#ordinal"}; + static constexpr auto ORDINAL_TYPE {ir::PrimitiveType::INT}; enum EnumType { INT = 0, LONG = 1, STRING = 2 }; diff --git a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp index 5badcb8516..e5ba691c7a 100644 --- a/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumPostCheckLowering.cpp @@ -344,10 +344,10 @@ ir::AstNode *EnumPostCheckLoweringPhase::GenerateValueOfCall(ir::AstNode *const if (!node->IsExpression()) { return node; } + node->Parent()->AddAstNodeFlags(ir::AstNodeFlags::RECHECK); if (node->AsExpression()->TsType()->AsETSEnumType()->NodeIsEnumLiteral(node->AsExpression())) { return InlineValueOf(node->AsMemberExpression(), checker_->Allocator()); } - node->Parent()->AddAstNodeFlags(ir::AstNodeFlags::RECHECK); auto *callExpr = CreateCallInstanceEnumExpression(checker_, node, checker::ETSEnumType::VALUE_OF_METHOD_NAME); return callExpr; } diff --git a/ets2panda/compiler/lowering/ets/stringComparison.cpp b/ets2panda/compiler/lowering/ets/stringComparison.cpp index e7f0cb4f16..17d48fbbef 100644 --- a/ets2panda/compiler/lowering/ets/stringComparison.cpp +++ b/ets2panda/compiler/lowering/ets/stringComparison.cpp @@ -81,7 +81,7 @@ void StringComparisonLowering::ProcessBinaryExpression(ir::BinaryExpression *exp checker::ETSChecker *checker = ctx->checker->AsETSChecker(); ArenaVector callArgs(checker->Allocator()->Adapter()); ir::Expression *accessor = nullptr; - auto *zeroExpr = checker->AllocNode(util::StringView("0")); + auto *zeroExpr = checker->AllocNode(lexer::Number(int32_t(0))); auto *const callee = checker->AllocNode("compareTo", checker->Allocator()); auto *var = checker->GlobalBuiltinETSStringType()->GetProperty(callee->AsIdentifier()->Name(), checker::PropertySearchFlags::SEARCH_METHOD); diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 4876544d46..4610361ad3 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -543,7 +543,7 @@ static ir::Expression *InsertConversionBetweenPrimitivesIfNeeded(UnboxContext *u res = PerformLiteralConversion(uctx, expr->AsNumberLiteral()->Number(), expectedType); res->SetRange(range); } else if (expr->IsCharLiteral() && expectedType->HasTypeFlag(checker::TypeFlag::ETS_NUMERIC)) { - res = PerformLiteralConversion(uctx, lexer::Number{expr->AsCharLiteral()->Char()}, expectedType); + res = PerformLiteralConversion(uctx, lexer::Number {expr->AsCharLiteral()->Char()}, expectedType); res->SetRange(range); } else { auto *allocator = checker->Allocator(); diff --git a/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp b/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp index 2f79f32dbf..581b830fde 100644 --- a/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp +++ b/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp @@ -64,7 +64,8 @@ ir::ReturnStatement *CreateTypedReturnStatement(checker::ETSChecker *checker, ir auto *callee = checker->AllocNode(apiClass, prop, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - ArenaVector args(1, checker->AllocNode("0"), allocator->Adapter()); + ArenaVector args(1, checker->AllocNode(lexer::Number((int64_t)0)), + allocator->Adapter()); auto *callExpression = checker->AllocNode(callee, std::move(args), nullptr, false); auto *asExpression = checker->AllocNode(callExpression, type->Clone(allocator, nullptr), false); diff --git a/ets2panda/ir/expressions/literals/numberLiteral.h b/ets2panda/ir/expressions/literals/numberLiteral.h index c9c4b5e2bc..00dfc4b098 100644 --- a/ets2panda/ir/expressions/literals/numberLiteral.h +++ b/ets2panda/ir/expressions/literals/numberLiteral.h @@ -29,7 +29,6 @@ public: NO_COPY_SEMANTIC(NumberLiteral); NO_MOVE_SEMANTIC(NumberLiteral); - explicit NumberLiteral(util::StringView const str) : Literal(AstNodeType::NUMBER_LITERAL), number_(str) {} explicit NumberLiteral(lexer::Number const number) : Literal(AstNodeType::NUMBER_LITERAL), number_(number) {} [[nodiscard]] const util::StringView &Str() const noexcept diff --git a/ets2panda/lexer/token/number.h b/ets2panda/lexer/token/number.h index 3dc1b3c5f3..7a79eea77b 100644 --- a/ets2panda/lexer/token/number.h +++ b/ets2panda/lexer/token/number.h @@ -55,12 +55,9 @@ template inline constexpr bool dependent_false_v = false; // NOLINTEND(readability-identifier-naming) -// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) class Number { public: - // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) explicit Number() noexcept : num_(static_cast(0)) {}; - explicit Number(util::StringView str) noexcept : str_(str) {} // NOLINTNEXTLINE(bugprone-exception-escape) explicit Number(util::StringView str, NumberFlags flags) noexcept; explicit Number(util::StringView str, double num) noexcept : str_(str), num_(num) {} @@ -77,7 +74,6 @@ public: DEFAULT_COPY_SEMANTIC(Number); DEFAULT_MOVE_SEMANTIC(Number); ~Number() = default; - // NOLINTEND(cppcoreguidelines-pro-type-member-init) bool IsByte() const noexcept { @@ -134,10 +130,7 @@ public: { return std::visit(overloaded {[](int16_t value) { return value; }, [](int8_t value) { return static_cast(value); }, - []([[maybe_unused]] auto value) { - ES2PANDA_ASSERT(false); - return static_cast(value); - }}, + []([[maybe_unused]] auto value) -> int16_t { ES2PANDA_UNREACHABLE(); }}, num_); } @@ -146,10 +139,7 @@ public: return std::visit(overloaded {[](int32_t value) { return value; }, [](int16_t value) { return static_cast(value); }, [](int8_t value) { return static_cast(value); }, - []([[maybe_unused]] auto value) { - ES2PANDA_ASSERT(false); - return static_cast(value); - }}, + []([[maybe_unused]] auto value) -> int32_t { ES2PANDA_UNREACHABLE(); }}, num_); } @@ -159,10 +149,7 @@ public: [](int32_t value) { return static_cast(value); }, [](int16_t value) { return static_cast(value); }, [](int8_t value) { return static_cast(value); }, - []([[maybe_unused]] auto value) { - ES2PANDA_ASSERT(false); - return static_cast(value); - }}, + []([[maybe_unused]] auto value) -> int64_t { ES2PANDA_UNREACHABLE(); }}, num_); } @@ -174,9 +161,10 @@ public: double GetDouble() const { - return std::visit( - overloaded {[](double value) { return value; }, [](auto value) { return static_cast(value); }}, - num_); + return std::visit(overloaded {[]([[maybe_unused]] std::monostate value) -> double { ES2PANDA_UNREACHABLE(); }, + [](double value) { return value; }, + [](auto value) { return static_cast(value); }}, + num_); } const util::StringView &Str() const @@ -191,7 +179,9 @@ public: void Negate() { - std::visit(overloaded {[](auto &value) { value = -value; }}, num_); + std::visit(overloaded {[]([[maybe_unused]] std::monostate value) { ES2PANDA_UNREACHABLE(); }, + [](auto &value) { value = -value; }}, + num_); if (std::holds_alternative(num_)) { int64_t num = std::get(num_); if (num == INT32_MIN) { @@ -202,7 +192,9 @@ public: bool IsZero() const { - return std::visit(overloaded {[](auto &value) { return value == 0; }}, num_); + return std::visit(overloaded {[]([[maybe_unused]] std::monostate value) -> bool { ES2PANDA_UNREACHABLE(); }, + [](auto &value) { return value == 0; }}, + num_); } // NOLINTBEGIN(readability-else-after-return) @@ -285,7 +277,7 @@ public: private: util::StringView str_ {}; - std::variant num_; + std::variant num_; NumberFlags flags_ {NumberFlags::NONE}; }; } // namespace ark::es2panda::lexer -- Gitee