kiwi-bdd / Kiwi

Simple BDD for iOS
BSD 3-Clause "New" or "Revised" License
4.14k stars 512 forks source link

Xcode 9: `any` Macro Conflicts with Generated Swift Header Macro `SWIFT_MODULE_NAMESPACE_PUSH` #698

Closed fabb closed 6 years ago

fabb commented 7 years ago

Xcode 9 generates a new SWIFT_MODULE_NAMESPACE_PUSH macro in generated Swift headers of mixed ObjC/Swift projects.

# define SWIFT_MODULE_NAMESPACE_PUSH(module_name) _Pragma(SWIFT_STRINGIFY(clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in=module_name, generated_declaration))), apply_to=any(function, enum, objc_interface, objc_category, objc_protocol))))

When we need to import the bridging header in a unit test file (e.g. when writing unit tests in ObjC but we need to access a Swift type), we have a problem when we first import Kiwi, and then the generated Swift header.

#import "Kiwi.h"
#import "MyProj-Swift.h"

The Swift macro references an existing any symbol, but Kiwi redefines it. https://github.com/kiwi-bdd/Kiwi/blob/master/Classes/Core/KiwiMacros.h#L65

This results in the error Too many arguments provided to function-like macro invocation.

A temporary workaround is to shuffle the import order around. A proper fix would be to rename the macro in Kiwi.

ecaselles commented 6 years ago

Thanks for raising this @fabb. We are seeing a similar issue ourselves. Not sure what would we like to go with, renaming the macro would be a first step, not sure if the best one though. Any ideas / suggestions?

fabb commented 6 years ago

I‘d suggest renaming it, maybe prefix it.

ecaselles commented 6 years ago

@fabb yeah, that makes sense 👍 I was asking for ideas / suggestions on the actual renaming / prefixing?

IMHO, I see prefixing as a fallback solution (e.g. kw_any), acceptable only if we are able to come up with a new name that represents better the purpose of this macro (e.g. anything, anyValue, matchingAny or even star 🤣)

I would like to push a new release to get a tagged version matching what it is currently on master, but I think now with Xcode 9, it would be a good time to also add these fixes in that release.

orta commented 6 years ago

In my JS, I'm used to Jest.anything() could it be something like Kiwi.any?

drosenstark commented 6 years ago

To answer my own question, @ecaselles and @fabb are saying that if you change the line in Kiwi/Classes/Core/KiwiMacros.h from:

#define any() [KWAny any]

to something with a prefix like:

#define kw_any() [KWAny any]

(and then replace any() in your code with kw_any()... the whole thing will work.

This is unless you can manage to get your Kiwi import to come after your bridging header import, which is probably the smart way to go if you can.

miscaper commented 6 years ago

Any progress on this issue?