Equivalent of NS_SWIFT_UNAVAILABLE for non-methods?


(Matteo) #1

Suppose I have an existing enum in Obj-C such as:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    dairyFood = 1 << 0,
    meatFood = 1 << 1,
    mushroomFood = 1 << 2
};

I want to rename all the values so that swift code can use the shorter names. i.e

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
    FoodMushroom = 1 << 2
};

generates:

public struct FoodType : OptionSetType {
    public init(rawValue: Int)

    public static var Dairy: FoodType { get }
    public static var Meat: FoodType { get }
    public static var Mushroom: FoodType { get }
}

But I still want the old names so as not to have to update all of the existing Obj-C code and mess up my SVN history.

At first I thought this would suffice:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
    FoodMushroom = 1 << 2,

// Old names
dairyFood = FoodDairy,
meatFood = FoodMeat,
mushroomFood = FoodMushroom
};

but that prevents the generated interface using the shortened names since all the values don’t follow the same pattern:

public struct FoodType : OptionSetType {
    public init(rawValue: Int)
    
    public static var FoodDairy: FoodType { get }
    public static var FoodMeat: FoodType { get }
    public static var FoodMushroom: FoodType { get }
    
    public static var dairyFood: FoodType { get }
    public static var meatFood: FoodType { get }
    public static var mushroomFood: FoodType { get }
}

I was looking for something similar to NS_SWIFT_UNAVAILABLE such that I could do:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
  FoodMushroom = 1 << 2,
  
  // Old names
  dairyFood = FoodDairy NS_SWIFT_UNAVAILABLE,
  meatFood = FoodMeat NS_SWIFT_UNAVALIBLE,
  mushroomFood = FoodMushroom NS_SWIFT_UNAVAILABLE
};

but NS_SWIFT_UNAVAILABLE can’t be used in this case.

So the only thing I seem to be able to do is #define the old names to the new names:
#define dairyFood FoodDairy
etc etc

which hides them from the generated interface, but exposes those defines to the rest of the code and in a few cases caused unwanted substitutions to happen.

Is a non-#define way of doing this possible?

Cheers


(Mark Dalrymple) #2

It'd be nice if there was a predefined macro to let you know if you're
inside of the header generation machinery. Last time I grazed the compiler
it didn't set up any custom symbols in the preprocessor it uses for the
first stage of processing the generated header. (rdar://27195567 - would
like a preprocessor symbol when building a generated interface)

If you want to get gross, the bridging header is just another header and
you can put your own defines in there - then look for it in your Food
Header: (not actually tested, Xcode8b2 is throwing a fit before I even
tried adding the #define. (rdar://27195434 - Some header files hang when
generating interface)

Project-Bridging-Header.h

...
#define SUPPRESS_OLD_FOOD 1
#import "Foodies.h"

Foodies.h

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
    FoodMushroom = 1 << 2,

#if !SUPPRESS_OLD_FOOD
// Old names
dairyFood = FoodDairy,
meatFood = FoodMeat,
mushroomFood = FoodMushroom
#endif
};

This has the unfortunate side effect (beyond making your bridging header
complicated) that Xcode's generated header preview won't take your macro
into account when previewing the generated interface. (rdar://27195567 -
would like a preprocessor symbol, again)

Cheers,
++md

···

On Wed, Jul 6, 2016 at 6:03 AM, Matteo via swift-users < swift-users@swift.org> wrote:

Suppose I have an existing enum in Obj-C such as:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    dairyFood = 1 << 0,
    meatFood = 1 << 1,
    mushroomFood = 1 << 2
};

I want to rename all the values so that swift code can use the shorter
names. i.e

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
    FoodMushroom = 1 << 2
};

generates:

public struct FoodType : OptionSetType {
    public init(rawValue: Int)

    public static var Dairy: FoodType { get }
    public static var Meat: FoodType { get }
    public static var Mushroom: FoodType { get }
}

But I still want the old names so as not to have to update all of the
existing Obj-C code and mess up my SVN history.

At first I thought this would suffice:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
    FoodMushroom = 1 << 2,

// Old names
dairyFood = FoodDairy,
meatFood = FoodMeat,
mushroomFood = FoodMushroom
};

but that prevents the generated interface using the shortened names since
all the values don’t follow the same pattern:

public struct FoodType : OptionSetType {
    public init(rawValue: Int)

    public static var FoodDairy: FoodType { get }
    public static var FoodMeat: FoodType { get }
    public static var FoodMushroom: FoodType { get }

    public static var dairyFood: FoodType { get }
    public static var meatFood: FoodType { get }
    public static var mushroomFood: FoodType { get }
}

I was looking for something similar to NS_SWIFT_UNAVAILABLE such that I
could do:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
  FoodMushroom = 1 << 2,

  // Old names
  dairyFood = FoodDairy NS_SWIFT_UNAVAILABLE,
  meatFood = FoodMeat NS_SWIFT_UNAVALIBLE,
  mushroomFood = FoodMushroom NS_SWIFT_UNAVAILABLE
};

but NS_SWIFT_UNAVAILABLE can’t be used in this case.

So the only thing I seem to be able to do is #define the old names to the
new names:
#define dairyFood FoodDairy
etc etc

which hides them from the generated interface, but exposes those defines
to the rest of the code and in a few cases caused unwanted substitutions to
happen.

Is a non-#define way of doing this possible?

Cheers

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Mark Dalrymple) #3

Another option is to rename them manually:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    dairyFood NS_SWIFT_NAME(dairy) = 1 << 0 ,
    meatFood NS_SWIFT_NAME(meat) = 1 << 1 ,
    mushroomFood NS_SWIFT_NAME(mushroomMushroom) = 1 << 2
};

···

On Wed, Jul 6, 2016 at 6:03 AM, Matteo via swift-users < swift-users@swift.org> wrote:

Suppose I have an existing enum in Obj-C such as:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    dairyFood = 1 << 0,
    meatFood = 1 << 1,
    mushroomFood = 1 << 2
};

I want to rename all the values so that swift code can use the shorter
names. i.e

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
    FoodMushroom = 1 << 2
};

generates:

public struct FoodType : OptionSetType {
    public init(rawValue: Int)

    public static var Dairy: FoodType { get }
    public static var Meat: FoodType { get }
    public static var Mushroom: FoodType { get }
}

But I still want the old names so as not to have to update all of the
existing Obj-C code and mess up my SVN history.

At first I thought this would suffice:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
    FoodMushroom = 1 << 2,

// Old names
dairyFood = FoodDairy,
meatFood = FoodMeat,
mushroomFood = FoodMushroom
};

but that prevents the generated interface using the shortened names since
all the values don’t follow the same pattern:

public struct FoodType : OptionSetType {
    public init(rawValue: Int)

    public static var FoodDairy: FoodType { get }
    public static var FoodMeat: FoodType { get }
    public static var FoodMushroom: FoodType { get }

    public static var dairyFood: FoodType { get }
    public static var meatFood: FoodType { get }
    public static var mushroomFood: FoodType { get }
}

I was looking for something similar to NS_SWIFT_UNAVAILABLE such that I
could do:

typedef NS_OPTIONS(NSInteger, FoodType)
{
    FoodDairy = 1 << 0,
    FoodMeat = 1 << 1,
  FoodMushroom = 1 << 2,

  // Old names
  dairyFood = FoodDairy NS_SWIFT_UNAVAILABLE,
  meatFood = FoodMeat NS_SWIFT_UNAVALIBLE,
  mushroomFood = FoodMushroom NS_SWIFT_UNAVAILABLE
};

but NS_SWIFT_UNAVAILABLE can’t be used in this case.

So the only thing I seem to be able to do is #define the old names to the
new names:
#define dairyFood FoodDairy
etc etc

which hides them from the generated interface, but exposes those defines
to the rest of the code and in a few cases caused unwanted substitutions to
happen.

Is a non-#define way of doing this possible?

Cheers

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users