Its main purpose is code simplification: ImplicitScopeTower::run
contains a lot of local functions that are needed because of
lots of shared state
So, we're moving the state to the Task class instead
NB: This change doesn't change the code of `run`, it will be done
in further commits
The idea is that all tower levels are partitioned into two groups:
- ones that may contain the target name or INVOKE; they're processed as usual
- ones that can't contain the name; they're simply skipped until
the end of resolution process when it's being passed to scope processors
to allow them record necessary lookups
definitelyDoesNotContainName is called too eagerly sometimes and it leads
to obviously redundant lookups
The idea is to put responsibility for calling recordLookup to resolution
itself
The idea is that resolution has an approximate complexity
close to (n + n*m) * 3
Where n is a number of scopes, m is a number of receivers
and 3-constant is used because each of these combinations
runs through 3 processors for functions.
And while call resolver seems to be a hot spot, it should be
useful to decreate the value of n
See
https://youtrack.jetbrains.com/issue/KT-19251https://github.com/puniverse/quasar/issues/280https://bugs.openjdk.java.net/browse/JDK-8046233
Inline function calls (as well as try/catch expressions) in constructor
arguments produce bytecode that spills stack, and stores uninitialized
objects (created by 'NEW C', but not initialized by 'C.<init>') to
local variables. Such bytecode is valid according to the JVM spec, but
confuses Quasar (and other bytecode postprocessing tools),
and fails to verify under some (buggy) versions of JDK 8.
In order to avoid that, we apply 'processUnitializedStores' already
implemented for coroutines. It moves 'NEW' instructions after the
constructor arguments evaluation, producing code like
<initialize class C using Class.forName>
<evaluate constructor arguments>
<store constructor arguments to variables>
NEW C
DUP
<load constructor arguments from variables>
INVOKESPECIAL C.<init>(...)
NB some other expressions, such as break/continue in the constructor
arguments, also can produce "weird" bytecode: object is created by a
'NEW C' instruction, but later (conditionally) POPped from stack and
left uninitialized. This, as we know, also can screw bytecode
postprocessing. However, it looks like we can get away with it ATM.
Otherwise it looks like we'd have to analyze constructor arguments, see
if the evaluation can "jump out", and perform argument linearization in
codegen.
Only top-level types on fields, methods' return types and
value parameters are supported to catch-up how class-files are loaded
in IntelliJ (see IDEA-153093)
NB: this commit also affects
ForeignJava8AnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated
that were failing before
#KT-20016 Fixed
- Apply default qualifiers to type arguments if they contain TYPE_USE
in applicability list
- Read TYPE_USE placed default qualifier annotations
#KT-19592 Fixed
#KT-20016 In Progress
Before this chanhe, these annotations are simply ignored, but they should
preserve flexibility in case of enhanced nullability obtained from
enclosing default qualifier
#KT-20158 Fixed
When IC is on and new Kotlin class is referencing
new Java class, new Kotlin file is compiled twice,
because JPS thinks new Kotlin class is affected by
new Java class (see https://youtrack.jetbrains.com/issue/KT-20318).
This does not happen when IC is off, and KotlinBuilder
requests chunk rebuild (see previous commit).
I decided to remove the reference, because the issue
is now known, and the reference is non critical for the test.
Otherwise unexpected compile error might happen,
when there are Groovy files, but they are not dirty,
so Groovy builder does not generate source stubs,
and Kotlin builder is filtering out output directory
from classpath (because it may contain outdated Java classes).
Previously the issue was not detected,
because it was not possible to turn off the IC completely (in JPS),
only switch to the legacy IC.
#KT-20138