Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[ffigen] Fix method variance issues #1714

Merged
merged 12 commits into from
Nov 13, 2024
Merged

[ffigen] Fix method variance issues #1714

merged 12 commits into from
Nov 13, 2024

Conversation

liamappelbe
Copy link
Contributor

@liamappelbe liamappelbe commented Nov 12, 2024

In Dart, method return types are covariant, and arg types are contravariant. But ObjC doesn't enforce any rules like that, and there are examples in the Apple APIs that use contravariant returns and covariant args. So I added a pass to FixOverriddenMethodsVisitation that fixes these cases.

_fixCoavariantArgs is nice and simple, because Dart already has a covariant keyword for designating args as covariant. _fixContravariantReturns is more complicated because there's no built-in workaround. Instead we have to alter the return type of the super class's method to match the more general return type of the child class's method. This may mean that we need further changes to fix methods further up the inheritance tree, so we keep walking up the supers until there are no more problematic return types.

Details

  • There are cases where these quick variance fixes won't work, so I added logging for that. I haven't seen any such cases in the wild. If users report a case we can decide what to do about them.
  • The old _fixNullability method was a special case of these variance fixes, so I removed it.
  • For _fixContravariantReturns to work reliably in all cases, it's best if supertypes are fully processed before subtypes. So I changed the iteration order of FixOverriddenMethodsVisitation to visit supertypes explicitly, then do all the processing, then visit the other children.
  • Added isSubtypeOf and isSupertypeOf to Type. isSubtypeOf just delegates to isSupertypeOf, which is what all the implementers implement. This is because it's much easier to implement the ObjCNullable logic in inSupertypeOf.
  • Removed all the special cases that were working around these bugs
  • Whether due the removal of those special cases, or due to the iteration order changes, the APIs generated by large_objc_test were reshuffled again, exposing one more unrelated bug.
    • Protocols can have properties, but I was ignoring them because from the ObjCProtocolBuilder's perspective they're just ordinary methods. But the fix for Protocol methods missing from classes #1487 copies these methods to conforming interfaces, so the getter/setter flags become relevant again.

Fixes #1220

Copy link

github-actions bot commented Nov 12, 2024

PR Health

Coverage ⚠️
File Coverage
pkgs/ffigen/lib/src/code_generator/func.dart 💔 Not covered
pkgs/ffigen/lib/src/code_generator/func_type.dart 💔 Not covered
pkgs/ffigen/lib/src/code_generator/objc_block.dart 💔 Not covered
pkgs/ffigen/lib/src/code_generator/objc_interface.dart 💔 Not covered
pkgs/ffigen/lib/src/code_generator/objc_methods.dart 💔 Not covered
pkgs/ffigen/lib/src/code_generator/objc_nullable.dart 💔 Not covered
pkgs/ffigen/lib/src/code_generator/pointer.dart 💔 Not covered
pkgs/ffigen/lib/src/code_generator/type.dart 💔 Not covered
pkgs/ffigen/lib/src/code_generator/typealias.dart 💔 Not covered
pkgs/ffigen/lib/src/header_parser/sub_parsers/objcprotocoldecl_parser.dart 💔 Not covered
pkgs/ffigen/lib/src/visitor/copy_methods_from_super_type.dart 💔 Not covered
pkgs/ffigen/lib/src/visitor/fix_overridden_methods.dart 💔 Not covered
pkgs/objective_c/lib/src/objective_c_bindings_generated.dart 💔 Not covered

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

License Headers ✔️
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/ffigen/example/libclang-example/generated_bindings.dart
pkgs/ffigen/example/shared_bindings/generate.dart
pkgs/ffigen/example/shared_bindings/lib/generated/a_gen.dart
pkgs/ffigen/example/shared_bindings/lib/generated/a_shared_b_gen.dart
pkgs/ffigen/example/shared_bindings/lib/generated/base_gen.dart
pkgs/ffigen/example/simple/generated_bindings.dart
pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_decl_collision_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_symbol_address_collision_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_type_name_collision_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_reserved_keyword_collision_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_dart_handle_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_enum_int_mimic_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_forward_decl_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_imported_types_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_native_func_typedef_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_opaque_dependencies_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_packed_structs_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_regress_384_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_sort_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_typedef_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_varargs_bindings.dart
pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart
pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart
pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart
pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart
pkgs/jni/lib/src/third_party/generated_bindings.dart
pkgs/jni/lib/src/third_party/global_env_extensions.dart
pkgs/jni/lib/src/third_party/jni_bindings_generated.dart
pkgs/jnigen/android_test_runner/lib/main.dart
pkgs/jnigen/example/in_app_java/lib/android_utils.dart
pkgs/jnigen/example/kotlin_plugin/example/lib/main.dart
pkgs/jnigen/example/kotlin_plugin/lib/kotlin_bindings.dart
pkgs/jnigen/example/kotlin_plugin/lib/kotlin_plugin.dart
pkgs/jnigen/example/pdfbox_plugin/lib/pdfbox_plugin.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocument.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocumentInformation.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/_package.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/PDFTextStripper.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/_package.dart
pkgs/jnigen/lib/src/bindings/descriptor.dart
pkgs/jnigen/lib/src/elements/elements.g.dart
pkgs/jnigen/test/jackson_core_test/third_party/bindings/com/fasterxml/jackson/core/_package.dart
pkgs/jnigen/tool/command_runner.dart
pkgs/native_assets_builder/test_data/native_dynamic_linking/bin/native_dynamic_linking.dart
pkgs/objective_c/lib/src/ns_input_stream.dart
pkgs/swift2objc/lib/src/config.dart
pkgs/swift2objc/lib/src/generate_wrapper.dart
pkgs/swift2objc/lib/src/generator/_core/utils.dart
pkgs/swift2objc/lib/src/generator/generator.dart
pkgs/swift2objc/lib/src/generator/generators/class_generator.dart
pkgs/swift2objc/lib/src/parser/parsers/declaration_parsers/parse_initializer_declaration.dart
pkgs/swift2objc/lib/src/parser/parsers/declaration_parsers/parse_variable_declaration.dart
pkgs/swift2objc/lib/src/transformer/_core/unique_namer.dart
pkgs/swift2objc/lib/src/transformer/_core/utils.dart
pkgs/swift2objc/lib/src/transformer/transformers/transform_globals.dart
pkgs/swift2objc/lib/src/transformer/transformers/transform_variable.dart
pkgs/swift2objc/test/unit/parse_initializer_param_test.dart

@coveralls
Copy link

coveralls commented Nov 12, 2024

Coverage Status

coverage: 90.287% (+0.3%) from 90.024%
when pulling 3328db7 on badoverride
into 6793812 on main.

@liamappelbe liamappelbe changed the title WIP: [ffigen] Fix method variance issues [ffigen] Fix method variance issues Nov 13, 2024
@liamappelbe liamappelbe marked this pull request as ready for review November 13, 2024 00:02
@liamappelbe liamappelbe merged commit 8c24707 into main Nov 13, 2024
20 checks passed
@liamappelbe liamappelbe deleted the badoverride branch November 13, 2024 23:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Some ObjC method overrides map to invalid Dart overrides
3 participants