This commit introduces proper handling of recursion in scopes, which
could occur when some of companion object supertypes are members of
that companion owner:
```
class Container {
open class Base
companion object : Base()
}
```
To resolve `Base`, we have to build member scope for `Container`.
In the member scope of `Container`, we see all classifiers from
companion and his supertypes
So, we have to resolve companion objects supertype, which happens to be
`Base` again - therefore, we encounter recursion here.
Previously, we created `ThrowingLexicalScope` for such recursive calls,
but didn't checked for loop explicitly, which lead to a wide variety of
bugs (see https://jetbrains.quip.com/dc5aABhZoaQY and KT-10532).
To report such cyclic declarations properly, we first change
`ThrowingLexicalScope` to `ErrorLexicalScope` -- the main difference is
that latter doesn't throws ISE when someone tries to resolve type in it,
allowing us to report error instead of crashing with exception.
Then, we add additional fake edge in supertypes graph (from
host-class to companion object) which allows us to piggyback on existing
supertypes loops detection mechanism, and report such cycles for user.
Fixes nondeterministic Default Method Order under existance of generic
type parameters.
SubstitutingScope did not respect source code method order by not using
a LinkedHashSet
In Kotlin 1.3+, assignment to the for-in-array loop range variable in
the loop body doesn't affect loop execution (as if it was a loop on an
array iterator, or some other container).
#KT-21354 In Progress
#KT-21321 In Progress
According to KT-21354, this should be a warning in 1.2 and before, and
no warning (with changed semantics) in 1.3 and later.
NB there are some false positives in this check.
#KT-21354 In Progress
#KT-21321 In Progress
When the enum entry requires a specific class, its constructor should
invoke proper supertype constructor (from the corresponding enum class).
Corresponding resolved call should be passed from the front-end in
CONSTRUCTOR_RESOLVED_DELEGATION_CALL slice.
In case of enum entries without explicit supertype initializer, this
information was missing.
This behavior was used until 6a1b6d10d8, where the JDK has
unintentionally started to be added to the end of the list, breaking
code which depended on libraries which bundle something from the JDK
#KT-21299 Fixed
For-in-string loop can be generated using specialized 'length' and
'charAt' method calls, and with cached string length.
Note that update of the string variable in loop body doesn't affect
loop execution semantics.
#KT-21322 Fixed Target versions 1.2.20
If the range expression is not a local variable (which can be updated in
the loop body affecting loop behavior, see KT-21354), we can cache the
array length, thus turning a for-in-array loop into a simple optimizable
counter loop.
#KT-21321 In Progress
Existing code for receiver generation accidentally worked in most cases
for object members imported by name. However, it generated strange
bytecode (such as
GETFIELD AnObject.INSTANCE
GETFIELD AnObject.INSTANCE
POP
), and worked incorrectly for augmented assignments.
#KT-21343 Fixed Target versions 1.2.20
This test introduces very special (for current implementation) case,
when we have smartcast indirectly, via some reified type parameter.
It covers recursive call inSmartCastManager.checkAndRecordPossibleCast(),
which wasn't previously covered by any test in testbase.
Expect members should always lose in resolution to non-expect members,
be it simple calls or callable references. Note that there should be
exactly one actual member for each expect member in correct code, so
both ways to check for expect vs non-expect are correct: either before
signature comparison, or after.
#KT-20903 Fixed
The problem is that when performing full analysis we do it in
a backward order while result for trivial vals is filled
in a forward one.
It turns out that reversedInstuctions might return a superset of
forward traversed instructions, e.g. in case of dead code in lambda.
At the same time result for trivial vals is constant
for any instruction, thus we can just return its constant value
and use it in the full analysis
#KT-20895 Fixed
Make ScriptDefinitionProvider an interface
and provide different implementation for cli and IDEA
Rework ide extension point to a simpler interface (ScriptDefinitionContributor)
Move template loading logic into a top level function
Allow script definitions to be reloaded in IDE
Consider a context with uninitialized this, e.g.:
fun foo() {
val x = "..."
class Local(y: String) : Base(L@{ x + y })
}
Lambda 'L' is an argument of a super class constructor call.
Here 'this@Local' is not initialized yet. Thus local variables captured
in 'Local' can't be used. Instead, they should be captured by lambda 'L'
itself.
Note that lambda 'L' sees both 'x' and 'y' as local variables that
should be captured.
When in context with uninitialized this (generating arguments for super
type constructor or delegating constructor call), and a variable in
question is not found in the current context, use enclosing local lookup
to determine whether a local variable should be captured by a closure.
Enclosing class for closure is a class whose instance is captured by
closure as an outer 'this', and stored in a field 'this$0'.
Usually enclosing class for closure is an immediate outer class,
including classes for nested closures. For example:
class C {
fun foo() {}
val example1 = L1@ { foo() }
// Enclosing class for lambda 'L1' is 'C'
val example2 = L2a@ { L2b@ { foo() } }
// Enclosing class for nested lambda 'L2b'
// is a closure class for outer lambda 'L2a'
}
However, if the closure is created in a super type constructor call for
the outer class, corresponding instance is considered "uninitialized",
and can't be used as a proper class instance, and can't be referenced:
corresponding code is rejected by front-end.
class Outer {
fun foo() {}
inner class Inner : Base(L3@ { foo() })
// Enclosing class for lambda 'L3' is 'Outer',
// because 'Inner' is uninitialized in super type constructor call.
}
In CodegenAnnotatingVisitor, we maintain a stack of currently
uninitialized classes, and chose enclosing class for closure
as an inner-most surrounding class with initialized instance.
When generating code for this or outer class instance, we skip
contexts corresponding to classes with uninitialized instances.
This fixes a number of bytecode verification errors caused by incorrect
enclosing class for closure.
#KT-4174 Fixed Target versions 1.2.20
#KT-13454 Fixed Target versions 1.2.20
#KT-14148 Fixed Target versions 1.2.20
... and invoke it directly in kotlin-reflect's build file, instead of
running another instance of compiler to evaluate a script. Also only
strip kotlin.Metadata, since it's the only annotation with heavy
metadata on Kotlin-generated class files
This allows to get rid of the dependency on descriptors.runtime from
compiler/IDE tests which is problematic: classes there clash with the
classes in kotlin-reflect, which reference declarations in shadowed
packages