google / j2objc

A Java to iOS Objective-C translation tool and runtime.
http://j2objc.org
Apache License 2.0
5.99k stars 970 forks source link

Package prefixes from prop file are in the wrong order #995

Closed sfuku7 closed 6 years ago

sfuku7 commented 6 years ago

Hi

To translate code, I was using ‘—prefix’ options to specify multiple package prefixes. And recently the definition of the prefix mapping was moved to a prop file to translate with ‘—prefixes’ option.

But I found that prefixes of the translated code are different from before.

I guess java.util.Properties#load() causes this issue.

https://github.com/google/j2objc/blob/master/translator/src/main/java/com/google/devtools/j2objc/util/PackagePrefixes.java#L131

I’m using wildcard to specify packages.

tomball commented 6 years ago

Do you have an example demonstrating this? I agree it may be java.util.Properties, but that's just a guess now.

sfuku7 commented 6 years ago

Hi

Thanks for your comment !

Here is a demo.

$ find .
.
./prefixes.properties
./foo
./foo/bar
./foo/bar/b
./foo/bar/b/Cat.java
$ cat foo/bar/b/Cat.java 
package foo.bar.b;

class Cat {}
$ j2objc --prefix 'foo.bar.b.*=FBB' --prefix 'foo.bar.*=FBX' foo/bar/b/Cat.java && cat foo/bar/b/Cat.h
//
//  Generated by the J2ObjC translator.  DO NOT EDIT!
//  source: foo/bar/b/Cat.java
//

#include "J2ObjC_header.h"

#pragma push_macro("INCLUDE_ALL_FooBarBCat")
#ifdef RESTRICT_FooBarBCat
#define INCLUDE_ALL_FooBarBCat 0
#else
#define INCLUDE_ALL_FooBarBCat 1
#endif
#undef RESTRICT_FooBarBCat

#if !defined (FBBCat_) && (INCLUDE_ALL_FooBarBCat || defined(INCLUDE_FBBCat))
#define FBBCat_

@interface FBBCat : NSObject

#pragma mark Package-Private

- (instancetype)init;

@end

J2OBJC_EMPTY_STATIC_INIT(FBBCat)

FOUNDATION_EXPORT void FBBCat_init(FBBCat *self);

FOUNDATION_EXPORT FBBCat *new_FBBCat_init() NS_RETURNS_RETAINED;

FOUNDATION_EXPORT FBBCat *create_FBBCat_init();

J2OBJC_TYPE_LITERAL_HEADER(FBBCat)

@compatibility_alias FooBarBCat FBBCat;

#endif

#pragma pop_macro("INCLUDE_ALL_FooBarBCat")
$ cat prefixes.properties 
foo.bar.b.*=FBB
foo.bar.*=FBX
$ j2objc --prefixes prefixes.properties foo/bar/b/Cat.java && cat foo/bar/b/Cat.h
//
//  Generated by the J2ObjC translator.  DO NOT EDIT!
//  source: foo/bar/b/Cat.java
//

#include "J2ObjC_header.h"

#pragma push_macro("INCLUDE_ALL_FooBarBCat")
#ifdef RESTRICT_FooBarBCat
#define INCLUDE_ALL_FooBarBCat 0
#else
#define INCLUDE_ALL_FooBarBCat 1
#endif
#undef RESTRICT_FooBarBCat

#if !defined (FBXCat_) && (INCLUDE_ALL_FooBarBCat || defined(INCLUDE_FBXCat))
#define FBXCat_

@interface FBXCat : NSObject

#pragma mark Package-Private

- (instancetype)init;

@end

J2OBJC_EMPTY_STATIC_INIT(FBXCat)

FOUNDATION_EXPORT void FBXCat_init(FBXCat *self);

FOUNDATION_EXPORT FBXCat *new_FBXCat_init() NS_RETURNS_RETAINED;

FOUNDATION_EXPORT FBXCat *create_FBXCat_init();

J2OBJC_TYPE_LITERAL_HEADER(FBXCat)

@compatibility_alias FooBarBCat FBXCat;

#endif

#pragma pop_macro("INCLUDE_ALL_FooBarBCat")

Is my usage correct ? I'm using wildcards for over wrapped packages.

My expectation is as below

Settings

foo.bar.b.*=FBB
foo.bar.*=FBX

Expected results

foo.bar.b.Cat => FBBCat
foo.bar.Dog => FBXDog
antonio-cortes-perez commented 6 years ago

Interesting scenario, the intention is to process the wildcards in the declared order. That's the behavior that you are seeing with --prefix.

In the case of --prefixes, the order is not preserved because we are using java.util.Properties (which inherits from Hashtable) https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html

Here is a relevant link to this discussion: https://stackoverflow.com/questions/17011108/how-can-i-write-java-properties-in-a-defined-order

On Thu, Aug 2, 2018 at 4:13 AM sfuku7 notifications@github.com wrote:

Hi

Thanks for your comment !

Here is a demo.

$ find . . ./prefixes.properties ./foo ./foo/bar ./foo/bar/b ./foo/bar/b/Cat.java

$ cat foo/bar/b/Cat.java package foo.bar.b;

class Cat {}

$ j2objc --prefix 'foo.bar.b.=FBB' --prefix 'foo.bar.=FBX' foo/bar/b/Cat.java && cat foo/bar/b/Cat.h // // Generated by the J2ObjC translator. DO NOT EDIT! // source: foo/bar/b/Cat.java //

include "J2ObjC_header.h"

pragma push_macro("INCLUDE_ALL_FooBarBCat")

ifdef RESTRICT_FooBarBCat

define INCLUDE_ALL_FooBarBCat 0

else

define INCLUDE_ALL_FooBarBCat 1

endif

undef RESTRICT_FooBarBCat

if !defined (FBBCat_) && (INCLUDE_ALL_FooBarBCat || defined(INCLUDE_FBBCat))

define FBBCat_

@interface FBBCat : NSObject

pragma mark Package-Private

  • (instancetype)init;

@end

J2OBJC_EMPTY_STATIC_INIT(FBBCat)

FOUNDATION_EXPORT void FBBCat_init(FBBCat *self);

FOUNDATION_EXPORT FBBCat *new_FBBCat_init() NS_RETURNS_RETAINED;

FOUNDATION_EXPORT FBBCat *create_FBBCat_init();

J2OBJC_TYPE_LITERAL_HEADER(FBBCat)

@compatibility_alias FooBarBCat FBBCat;

endif

pragma pop_macro("INCLUDE_ALL_FooBarBCat")

$ cat prefixes.properties foo.bar.b.=FBB foo.bar.=FBX

$ j2objc --prefixes prefixes.properties foo/bar/b/Cat.java && cat foo/bar/b/Cat.h // // Generated by the J2ObjC translator. DO NOT EDIT! // source: foo/bar/b/Cat.java //

include "J2ObjC_header.h"

pragma push_macro("INCLUDE_ALL_FooBarBCat")

ifdef RESTRICT_FooBarBCat

define INCLUDE_ALL_FooBarBCat 0

else

define INCLUDE_ALL_FooBarBCat 1

endif

undef RESTRICT_FooBarBCat

if !defined (FBXCat_) && (INCLUDE_ALL_FooBarBCat || defined(INCLUDE_FBXCat))

define FBXCat_

@interface FBXCat : NSObject

pragma mark Package-Private

  • (instancetype)init;

@end

J2OBJC_EMPTY_STATIC_INIT(FBXCat)

FOUNDATION_EXPORT void FBXCat_init(FBXCat *self);

FOUNDATION_EXPORT FBXCat *new_FBXCat_init() NS_RETURNS_RETAINED;

FOUNDATION_EXPORT FBXCat *create_FBXCat_init();

J2OBJC_TYPE_LITERAL_HEADER(FBXCat)

@compatibility_alias FooBarBCat FBXCat;

endif

pragma pop_macro("INCLUDE_ALL_FooBarBCat")

Is this correct use ? I'm using wildcard with over wrapped packages.

My expectation is as below

Settings

foo.bar.b.=FBB foo.bar.=FBX

Expected results

foo.bar.b.Cat => FBBCat foo.bar.Dog => FBXDog

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/google/j2objc/issues/995#issuecomment-409891730, or mute the thread https://github.com/notifications/unsubscribe-auth/AbFr1XHrHibqxaft3tY87iq3sSJ_i2Zgks5uMt7hgaJpZM4VrbPK .

tomball commented 6 years ago

The reason Properties was used is that it was already in jre_core (the minimal set of JRE classes for j2objc-generated files), so a separate parser didn't need to be written and increase the size of jre_core. Looking at Properties, the solution may be to use its package-private LineReader class to parse each line the same as Properties, which IOSClass would save to a LinkedHashMap (also in jre_core). I'll give it a try and see what breaks. :-)

tomball commented 6 years ago

I think it will be safe to drop Properties' support for representing \uxxxx as Unicode characters, since we can instead require prefixes.properties files be encoded in UTF-8 instead of ISO 8859-1 as Properties does. Does that seem reasonable?

antonio-cortes-perez commented 6 years ago

SGTM

On Thu, Aug 2, 2018 at 10:27 AM Tom Ball notifications@github.com wrote:

I think it will be safe to drop Properties' support for representing \uxxxx as Unicode characters, since we can instead require prefixes.properties files be encoded in UTF-8 instead of ISO 8859-1 as Properties does https://docs.oracle.com/javase/7/docs/api/java/util/Properties.html. Does that seem reasonable?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/google/j2objc/issues/995#issuecomment-410005551, or mute the thread https://github.com/notifications/unsubscribe-auth/AbFr1YJcyNu6f6GSxktTSh6yiXIiQpU3ks5uMzaUgaJpZM4VrbPK .

sfuku7 commented 6 years ago

Thanks !

I’ll use prefix packages not relying on declared order at this moment.

antonio-cortes-perez commented 6 years ago

Fixed in version 2.2