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

Question on declarations generation #205

Open
legion151 opened this issue Mar 30, 2023 · 4 comments
Open

Question on declarations generation #205

legion151 opened this issue Mar 30, 2023 · 4 comments

Comments

@legion151
Copy link

Hello and thanks for your work.

I have a question regarding the generation of ios typescript declarations hoping to be in the right place.

We're using a robovm based toolchain to build a native library for iOS from Java-code. This toolchain emits header files in the following (shortened) form:

@protocol Option                                                                                
-(NSString *) optionId;                                 
-(NSString *) type;                    
@end                                      
typedef NSObject<Option> Option; 

@protocol Info                                                                                 
-(NSArray<NSObject<Option> *> *) getOptions;
@end
typedef NSObject<Info> Info;

the (shortened) declarations in ios.d.ts are

interface Option {                                      
                                                        
        optionId(): string;                             
                                                        
        type(): string;                                 
}                                                       
declare var Option: {                                   
                                                        
        prototype: Option;                              
};

interface Info {
                                               
        getOptions(): NSArray<NSObject>;
                                           
}                  
declare var Info: {       
                                            
        prototype: Info;          
};

You may notice that the returned Array of getOptions is typed with NSObject instead of Option, which is the reason for this writing.

In fact are all argument- and return- types of functions which are defined by our headers typed with NSObject instead of the type which it should be.

After digging a while i understand that the types are evaluated in that function
https://github.com/NativeScript/ios/blob/main/metadata-generator/src/TypeScript/DefinitionWriter.cpp#L862
which might be wrong since it's been a while that i read some cpp code.

I assume that this codes falls back to NSObject if it cannot determine the correct type.
Note, that if i manually adjust the types in ios.d.ts everything works fine.

So basically my questions:

  • Are our input (the header files) missing something or do they have to be different soemhow to get beter outcomes?
  • If not would it be possible to patch the generator?
  • Am i totally wrong here?

Cheers and again thanks for your work.
legion

@rigor789
Copy link
Member

I don't know the answer, we'll have to look a bit deeper and understand what's going on - I would expect the return type to be NSArray<Option> but it's totally possible the metadata-generator/types-generator doesn't cover/handle this case yet and has to be implemented.

@edusperoni
Copy link
Collaborator

Shouldn't the generated declaration have Option extend NSObject in some way? Theoretically it returns NSObjects which is correct, but it's also Option. I might be wrong though

@rigor789
Copy link
Member

Yeah, I guess it should generate something like

interface Option extends NSObject {                                      
  optionId(): string;                             
  type(): string;                                 
}                                                       
declare var Option: {                                   
  prototype: Option;                              
};

interface Info {
  getOptions(): NSArray<Option>;                                      
}                  
declare var Info: {       
  prototype: Info;          
};

@edusperoni
Copy link
Collaborator

@rigor789 I'm not sure about it, but the runtime sometimes can do some magic when converting struct types where you can pass Option without implementing NSObject and it'll convert into an NSObject

https://docs.nativescript.org/advanced-concepts.html#struct-types

Maybe this is the correct output:

interface Option {
  optionId(): string
  type(): string
}

declare var Option: {
  prototype: Option
}

interface Info {
  getOptions(): NSArray<NSObject & Option>
}

declare var Info: {
  prototype: Info
}

This way you can use Option (and the magic) in a transparent way, but the return is NSObject & Option, so you know it's not a simple struct, but a full NSObject with those added methods

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants