Skip to content

Subclass overriding methods that return/take NSRange not correctly generated #1180

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

Closed
brianquinlan opened this issue May 30, 2024 · 13 comments · Fixed by #1602
Closed

Subclass overriding methods that return/take NSRange not correctly generated #1180

brianquinlan opened this issue May 30, 2024 · 13 comments · Fixed by #1602
Assignees
Milestone

Comments

@brianquinlan
Copy link
Contributor

When generating code for NSMutableIndexSet, this code is produced:

final class _NSRange extends ffi.Struct {
  @NSUInteger()
  external int location;

  @NSUInteger()
  external int length;
}

typedef NSRange = _NSRange;

class NSMutableIndexSet extends objc.NSIndexSet {
  ...
  @override
  objc.NSIndexSet initWithIndexesInRange_(NSRange range) {
    final _ret =
        _objc_msgSend_16(this.pointer, _sel_initWithIndexesInRange_, range);
    return NSMutableIndexSet.castFromPointer(_ret, retain: true, release: true);
  }
  ...
}

But package:objective_c defines NSIndexSet` like:

class NSIndexSet extends NSObject {
   ...
  NSIndexSet initWithIndexesInRange_(_NSRange range) {
    final _ret =
        _objc_msgSend_118(this.pointer, _sel_initWithIndexesInRange_, range);
    return NSIndexSet.castFromPointer(_ret, retain: true, release: true);
  }
  ...

Since the NSRange used in the base and subclass don't match, the @override is not valid. Probably NSRange has to be part of package:objective_c and generated code must reference that.

@brianquinlan
Copy link
Contributor Author

Maybe NSMutableIndexSet should be part of package:objective_c.

@brianquinlan
Copy link
Contributor Author

Name issue for NSSimpleCString for these methods:

  • initWithCharactersNoCopy_length_deallocator_ (because of deallocator)
  • initWithFormat_arguments_ (because of va_list)
  • initWithFormat_locale_arguments_ (because of va_list)
  • initWithValidatedFormat_validFormatSpecifiers_arguments_error_ (because of va_list)
  • initWithValidatedFormat_validFormatSpecifiers_locale_arguments_error_ (becase of va_list)
  • initWithBytesNoCopy_length_encoding_deallocator_ (because of deallocator)

@brianquinlan
Copy link
Contributor Author

I think that you fixed this.

@liamappelbe
Copy link
Contributor

Not sure if it's fixed, but package:objective_c should probably export the NSRange struct, and any other structs it defines.

@brianquinlan
Copy link
Contributor Author

Doesn't package:objective_c have to export every type that appears anywhere in any API that it exports?

@liamappelbe
Copy link
Contributor

Yep. I've exported all the interfaces, but not the structs.

@brianquinlan
Copy link
Contributor Author

If you wanted to add a test that verifies that you have exported everything that you need to, you could use dart:mirrors.

@brianquinlan
Copy link
Contributor Author

Ah, that would explain why the generated buildings are still incorrect:

  @override
  NSMutableIndexSet initWithIndexesInRange_(NSRange range) {
'NSMutableIndexSet.initWithIndexesInRange_' ('NSMutableIndexSet Function(_NSRange)') isn't a valid override of 'NSIndexSet.initWithIndexesInRange_' ('NSIndexSet Function(_NSRange)').

@liamappelbe liamappelbe moved this from Todo to In progress in ObjC/Swift interop Jun 24, 2024
@liamappelbe
Copy link
Contributor

Fixed this a while ago (#1175) but forgot to close it.

@github-project-automation github-project-automation bot moved this from In progress to Done in ObjC/Swift interop Jul 2, 2024
@BestOwl
Copy link

BestOwl commented Sep 21, 2024

I can still reproduce this issue when generating code for SFTranscriptionSegment using the ffigen package version 14.0.1 and objective_c version 2.0.0.

@liamappelbe liamappelbe reopened this Sep 23, 2024
@liamappelbe
Copy link
Contributor

@BestOwl can you give me some more information? What buggy behavior are you seeing?

@liamappelbe liamappelbe moved this from Done to Todo in ObjC/Swift interop Sep 23, 2024
@liamappelbe liamappelbe added the needs-info Additional information needed from the issue author label Sep 23, 2024
@BestOwl
Copy link

BestOwl commented Sep 23, 2024

Use the following config to generate a bindings for SFTranscriptionSegment

ffigen:
  name: Speech
  description: Bindings for Apple Speech framework
  language: objc
  output: "lib/src/apple_speech_bindings_generated.dart"
  headers:
    entry-points:
      - "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Speech.framework/Headers/Speech.h"
  exclude-all-by-default: true
  objc-interfaces:
    include:
      - SFTranscriptionSegment

ffigen produces the warning:

[WARNING]: Generated declaration '_NSRange' starts with '_' and therefore will be private.

and the generated code:

final class _NSRange extends ffi.Struct {
  @ffi.UnsignedLong()
  external int location;

  @ffi.UnsignedLong()
  external int length;
}

...

/// SFTranscriptionSegment
class SFTranscriptionSegment extends objc.NSObject {

...

  /// substringRange
  void getSubstringRange(ffi.Pointer<_NSRange> stret) {
    objc.useMsgSendVariants
        ? _objc_msgSend_437Stret(stret, this.ref.pointer, _sel_substringRange)
        : stret.ref = _objc_msgSend_437(this.ref.pointer, _sel_substringRange);
  }

...

}

The generated code should use NSRange from package:objective_c instead

@github-actions github-actions bot removed the needs-info Additional information needed from the issue author label Sep 23, 2024
@liamappelbe
Copy link
Contributor

Oh ok. The bug is probably that _NSRange doesn't match package:objective_c's NSRange. I just need to have it take into account the renaming.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants