- Move the following from 'deserialization' to 'descriptors':
NotFoundClasses.kt
AdditionalClassPartsProvider.kt
ClassDescriptorFactory.kt
PlatformDependentDeclarationFilter.kt
findClassInModule.kt
- Move the following form 'descriptors' to 'deserialization':
BuiltInSerializerProtocol.kt
builtInsPackageFragmentProvider.kt
- Extract a marker interface from BuiltInsPackageFragment and move its
implementation to 'deserialization'
- Change the type of parameters in PlatformDependentDeclarationFilter
and AdditionalClassPartsProvider to ClassDescriptor
This will help in getting rid of the circular dependency of
'descriptors' <-> 'deserialization'
The problem was that an overload of CodedOutputStream.newInstance
without size uses 4000 as a default value, thus allocating
a 4k-sized byte array.
At the same time the array remained effectively unused
in the most cases since it only used for storing data
for unknown fields.
Because such arrays are being created for each read of
protobuf message, during compilation of IntelliJ project
it was producing 25% of redundant memory traffic.
Of course these arrays were all in the young gen, but still
they have some effect on GC
Backend: If kotlin class extends kotlin.collection.List
write it as it's super interface (light class mode only)
IDE: Provide wrapper classes to java resolve
that try to emulate backend behaviour
For example if kotlin class implements kotlin.collections.Map,
we provide a superinterface that has abstract 'getEntries' method
and 'entrySet' method that is considered default.
In reality all those methods are generated in the class itself.
In IDE supporting this case without hacks is not feasible performance-wise
since kotlin.collection.* may not be an immediate supertype and we need
to compute all supertypes just to calculate own methods of the class
com.typesafe.akka:akka-cluster-sharding_2.12:2.5
akka.cluster.sharding.ClusterSharding has the following methods:
public static ClusterSharding get(ActorSystem var0) {
return ClusterSharding$.MODULE$.get(var0);
}
public static Extension get(ActorSystem var0) {
return ClusterSharding$.MODULE$.get(var0);
}
NB: ClusterSharding <: Extension
None of these methods is synthetic or something, but javac allows
calls like ClusterSharding.get(null) and they get resolved
to the first method returning ClusterSharding
It seems that both javac and IntelliJ resolution algorithms filter out
such clashing declarations choosing the one that has the most
specific return type, the same idea is applied in the change
#KT-17560 Fixed
Also add a findInnerClass method that can find an inner class
by its name
This change helps to avoid loading all the inner class files
eagerly (that may be rather slow), while all the names are available
in InnerClass attribute
The reason is that canonicalText requires some additional
computations to be done when reading class files, while
in fact we only need a class name of the type
Searching for the single abstract method leads to computing
whole member scopes of given intrefaces, especially when
they contain a lot of methods (i.e. they're definitely not SAMs)
On the other side this method is very hot because it's called
for each Java interface used as a type for some value parameter
(for building SAM adapters)
The idea is to apply some heuristics to understand using only
JavaMethod and supertypes that this interface is definitely not a SAM
This fixes KT-17001 because now 'header' modifier is loaded correctly
for deserialized members and the standard disambiguation in
OverloadingConflictResolver.compareCallsByUsedArguments takes place,
where header members are discriminated against the corresponding impl
members
#KT-17001 Fixed
See how we translate raw types to Kotlin model:
RawType(A) = A<ErasedUpperBound(T1), ...>
ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
Stack overflow happens with the following classes:
class A<X extends B> // NB: raw type B in upper bound
class B<Y extends A> // NB: raw type A in upper bound
when calculating raw type for A, we start calculate ErasedUpperBound(Y),
thus starting calculating raw type for B => ErasedUpperBound(X) => RawType(A),
so we have SOE here.
The problem is that we calculating the arguments for these raw types eagerly,
while from the definition of ErasedUpperBound(Y) we only need a type constructor
of raw type B (and the number of parameters), we don't use its arguments.
The solution is to make arguments calculating for raw types lazy
#KT-16528 Fixed
The main problem here is that moduleName that is being passed to KPackageImpl
is useless: as can be seen in
ClosureCodegen.generateCallableReferenceDeclarationContainer, the name of the
current module is always written to the class file for a callable reference,
not the name of the module of the referenced declaration. This resulted in
reflection not loading the correct .kotlin_module file and subsequently not
finding the required file facade for a top-level function.
The commit does not fix the issue with the incorrect module name written in the
back-end, but workarounds it. It turns out, reflection can figure out the name
of the module of the referenced declaration itself by parsing the header from
the given java.lang.Class object for a single-file/multi-file package facade
and extract the package_module_name protobuf extension. Similar code was
already there in Member.getKPackage() in ReflectJvmMapping.kt but it did not
support multi-file classes, of which there are a lot in the standard library;
this is now supported
#KT-12630 Fixed
#KT-14731 Fixed
A lot of problem arise with current solution
(loading them with lowpriority annotation + additional call checkers):
- We errorneously treated ArrayList.stream as an existing method, while
it's just a fake override from List
- The same problem arises when creating a class delegating to List.
Also the latter case is failing with codegen internal error
(see issue KT-16171)
The negative side of this solution is that instead of reporting meaningful
diagnostic, there will be UNRESOLVED_REFERENCE.
But it seems to be better than having strange problems like ones described above.
#KT-16073 Fixed
#KT-16171 Fixed
Since now `suspend (Int) -> String` will be serialized as `(Int, Continuation<String>) -> Any?` + suspend flag.
Before this change such type serialized like this: Function2<Int, String> + suspend flag. And yes, type `Function2<Int, String>` isn't correct, because Function2 expect 3 type arguments.
We have special logic for this case and we deserialize such error-written types correctly.
(cherry picked from commit 3518cbe)
For sdkModule we create builtIns with default language feature settings.
Also when we create sdkModuleResolverProvider we create builtIns cache.
Then for every other module we get builtIns cached by value isAdditionalBuiltInsFeatureSupported.
Also move internal declarations from runtime.jvm module into new package
kotlin.coroutines.jvm.internal in stdlib
The necessity of these declarations being in built-ins is controversial,
but also it will complicate the migration of current coroutine runtime
to a separate jar if we ever need this
Inferred type of receiver of orElse is Optional<T & Any>
Generic descriptor is orElse(E!): E!
Substituted descriptor is orElse(T): T , and that is the problem.
Seems that E! => (T & Any)! gets expanded to just T or T & Any , however it should be expanded to
(T & Any) .. (T & Any)? => T & Any .. T & Any
T & Any is NotNullTypeParameter(T)
The problem is that (T & Any)? is expanded to T & Any,
that is seems to be wrong.
#KT-15236 Fixed
- calls must be prohibited iff they refer to some additonal built in member
- override must be prohibited iff all of the overridden descriptors are additional
Other usages were able to be successfully compiled by 1.0.x
Solution with @Deprecated(level=Error) doesn't work properly, because
deprecation propagates to overridden, thus call 'java.util.ArrayList<String>().stream()'
becomes invalid, while it was correct in 1.0.x
#KT-15794 Fixed
This is needed because 1.1.2 binaries are considered pre-release (see
DeserializedDescriptorResolver), so it wasn't possible to compile
non-pre-release binaries with -language-version 1.0