When can Proguard optimize enums out? - proguard

https://www.guardsquare.com/en/proguard/manual/optimizations says
class/unboxing/enum
Simplifies enum types to integer constants, whenever possible.
But the obvious question is, when is it possible? I assume the enum must not have fields/methods? Does it apply only to local variables or to method arguments as well?
In particular, if I have a enum with a field and a getter for this field, I could convert it to a static method switching on the enum; will this enable the optimization?

Optimization
Your assumption is correct, for the Proguard to optimize an enum, that enum should not have methods and associated values(fields). Proguard converts these simple enums to ints so, you get the type-safety of the enums at compile-time and the performance of ints at runtime.
It applies both to variables as well as method arguments.
So for your case where you have a field in an enum, the optimization won't apply.
Jake Wharton who worked for the Android team and others have discussed enum optimization in this Reddit post.
Proguard Settings
The Proguard settings should look like following:
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
Note the inclusion of the proguard-android-optimize.txt file and not the proguard-android.txt file.
ProguardEnumIntDefTest is a sample project on Github that tries to find out if Proguard converts enums into ints.

Related

What does "Symbol" mean in KSP

Currently I am studying on KSP(Kotlin Symbol Processing), and I am curious about what does "Symbol" mean in KSP.
When it comes to comparing with KAPT, it says "To run Java annotation processors unmodified, KAPT compiles Kotlin code into Java stubs that retain information that Java annotation processors care about. To create these stubs, KAPT needs to resolve all symbols in the Kotlin program."
I don't know what does "all symbols in the Kotlin program" exactly mean?
I understand "symbols" as declarations of interfaces, classes, functions, properties, etc. It doesn't include the body or the code itself, only the API, items that are visible to others.
This term is not specific to Kotlin. I can't find any definition of "symbols" on Wikipedia, but for example native libraries also contain symbol tables.
In this specific context it means that KAPT has to create a full list of all such symbols in Kotlin code and generate their equivalents in Java, so annotation processors could work on them. This is pretty wasteful as we recreate Kotlin code structure in Java just to throw it away seconds later and replace with true compiled code.

Why Kotlin blindly change internal classes into public in JVM?

As you know the private classes in Kotlin change to package-private under the hood and internals changed to the public.
unfortunately, this can lead to the known problem here.
if the compiler sees the usage of Kotlin internal classes when it wants to change it to the byte code, it can choose package-private for internal kotlin classes that didn't use outside of the package and choose public for others, so we can handle above problem on our own.
Or they can define another annotation such as #JvmPackagePrivate before internal classes to tell the compiler we want a package-private class in java.
Or they can do both.
The question is, why they don't solve this obvious problem with such an obvious solution?
Are they have another approach to solve this?
I just got acquainted with the Kotlin, so I think that I cant create lib for java with kotlin because when I create internal concrete classes, all client can see them outside of the library and its serious problem with kotlin. why they can't see this obvious problem??????
I want to mention that none of the answers in here solve this problem because of #JvmSynthetic and #JvmName just target the fun in kotlin, not classes and at the end they both visible even if they change the name of classes.
at last kotlin claims that it is completely interoperable with java but I think it's not right. better to say that it is 99 percent interoperable with java :)

dart api crossed out variables

In most Dart documentation pages, some variables and functions are crossed out. like in https://api.dartlang.org/1.14.2/dart-js/dart-js-library.html
What does this signify?
In Dart metadata can be added to classes, fields, library declaratoins, parameters, ... as annotation.
#Deprecated('some reason')
class SomeClass {
String someField;
int otherField;
SomeClass({
this.someField,
#Deprecated('don\'t use this anymore") this.otherField});
}
is such an annotation and some tools like the Dart analyzer and dartdoc use this information to produce warnings (Analyzer) or other visual cues that some API still exists but should be avoided because it's planned to be removed eventually.
It signifies that the class, function, property etc. is deprecated
In Dart, annotations are used to mark something as deprecated. Notice the documented annotation on this class.

What are the requirements to make a Swift class and it's members be usable in Obj-C code?

Since this is nowhere documented AFAIK and I have seen problems with Swift code that cannot be bridged to Obj-C I'd like to open a thread to collect all informations regarding compatibility, work arounds and other tips here.
Classes must be marked with the #objc() annotation to make them available.
inout as well as var parameters are not supported and will cause the bridging header generation to simply ignore that function.
Tuples are not supported, neither as parameter nor as return value.
Closures are not supported, neither as parameter nor as return value.
Structures are not supported, neither as parameter nor as return value.
Anything more?

Is there anything in the C++0x standard to support separate compilation of templates?

In current g++, I typically include all my templated functions that take the template parameter as an argument because they have to be compiled for each instance.
template<typename T>
class A {
public:
void f() { ... }
};
So in a different source, I would write:
#include <A.hh>
A<int> a1;
a1.f();
A<double> a2;
a2.f();
Sometimes, when I've been desperate to not inline big methods, I've manually specified which classes will be used in the source file, but it's really obnoxious:
template<typename T>
A::A() { ... }
template<typename T>
void A::f() { ... }
A<int>; // manually trigger code generation for int and double
A<double>;
Obviously different IDEs and compilers have mechanisms to support this. Is there anything standard that has been mandated, and/or does g++ support anything like this?
There's nothing in the proposed C++0x standard. In fact, export template has been removed (few compilers implemented it anyway).
As far as inlining is concerned, it's a total non-issue. The compiler is smart enough not to inline functions which are too big, even if they're marked inline and put into a header file.
If you're looking at increased compile times from header files grown bloated from templates, use precompiled headers. These aren't standard, but almost all current compilers provide such a mechanism.
C++0x does have extern template, which allows you to prevent the instantiation of certain templates in a compilation unit. So if you have a template class SomeClass, you can put this in the header:
extern template SomeClass<int>;
extern template SomeClass<double>;
This will prevent users from instantiating the template. In the .cpp file for the template, you can force instantiation with this syntax:
template SomeClass<int>;
template SomeClass<double>;
I've manually specified which classes will be used in the source file, but it's really obnoxious:
A<int>; // manually trigger code generation for int and double
A<double>;
This is not legal (I assume you meant to declare dummy variables here, and missed their name). We will see below why
Is there anything standard that has been mandated, and/or does g++ support anything like this?
C++03 had something called export, but which turned out to be a misfeature. The EDG implemented that feature, and their experience with it indicated that it's not worth the trouble implementing it. And it doesn't provide a useful feature separate compilation usually gives you: Hiding of the code of templates which you once compiled. export still requires the code of templates, be it in raw form or encoded into a mid-level compiler-specific language. See Why we can't afford export. A short example is given by EDG worker David Vandevoorde here.
For C++0x and for C++0x sans export, we have
A function template, member function of a class template, or static data member of a class template shall be deļ¬ned in every translation unit in which it is implicitly instantiated (14.7.1) unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required
As this indicates, the only way you can achieve separate compilation is to explicitly instantiate the template you want to have separately compiled. By defining dummy variables, you merely implicitly instantiate the class template. And you do not instantiate the member functions of the class templates that way - you would need to do dummy calls or take their address. And to all this, you are not guaranteed that an implicitly instantiated function won't be discarded if it's not used in the translation unit it was instantiated by, after optimization, based on the above quote.
So you explicitly instantiate the class template, which will explicitly also instantiate its member functions the following way:
template class A<int>;
template class A<double>;
This feature, called export is present even in the current standard of C++. Unfortunately, most compilers, including gcc, do not support it. See here http://gcc.gnu.org/bugs/