Commit Graph

8682 Commits

Author SHA1 Message Date
pyos 9f4cfa2c50 FIR CFG: ignore exception edges when looking for return values
^KT-54668 Fixed
2022-12-08 10:19:34 +00:00
pyos 664a70ec13 FIR DFA: split flow for postponed lambdas from a single node
This removes the need for hacks around the order in which function
call arguments are visited, fixes called-in-place lambda arguments
for augmented assignment operators, and makes CFG dumps a bit prettier.
2022-12-08 10:19:34 +00:00
pyos 402ea98e02 FIR DFA: align FirLocalVariableAssignmentAnalyzer with the graph builder
I.e. maintain a set of seen lambdas where each marked as either "data
flow only" or "both data and control flow". The latter are truly
parallel with the function being analyzed, while the former have
technically already terminated, we just don't know the types inside them
because they may not have been analyzed yet.
2022-12-08 10:19:34 +00:00
pyos c231477375 FIR: don't call a graph builder method in finally
If an exception is thrown, trying to add more nodes to a graph that's
already missing entire subgraphs may not end well.
2022-12-08 10:19:33 +00:00
pyos 38c1ef30bc Minor: refactor FirPropertyInitializationAnalyzer
Still not sure how to implement visitUnionNode
2022-12-08 10:19:33 +00:00
pyos d66be3f82d FIR CFG: do not assume all arguments to inline funs are called in place
Only values for non-noinline, non-crossinline, functional type
parameters qualify.
2022-12-08 10:19:32 +00:00
pyos 39f88b9e87 FIR CFG: move the argument reordering hack to the expression transformer 2022-12-08 10:19:32 +00:00
pyos 9823473f63 Minor: remove a redundant transformArgumentList override 2022-12-08 10:19:32 +00:00
pyos c4c05f5248 FIR CFG: remove ordering from control flow through in-place lambdas
Old graph:

  arg -> lambda enter -> ... -> lambda exit -> lambda enter -> ... ->
   -> lambda exit -> call

New graph:

  arg -+-> lambda enter -> ... -> lambda exit -+-> call
       \-> lambda enter -> ... -> lambda exit -/
2022-12-08 10:19:31 +00:00
pyos 5dce772f0b FIR DFA: restructure handling of += to avoid losing data flow 2022-12-08 10:19:31 +00:00
pyos b2fe5831ed FIR DFA: use local function declaration nodes for non-argument lambdas 2022-12-08 10:19:30 +00:00
pyos 8a68eac5f1 FIR DFA: add a union node for property delegates
The delegate is resolved in context-dependent mode and thus can be an
incomplete call; if there is no `provideDelegate` method to complete it,
the result is effectively `val x$delegate = y.id()` where `id` is
`fun <T> id(x: T) = x`, except we don't get a real node for `id` so the
DFA edges from lambdas in `y` go who knows where.
2022-12-08 10:19:30 +00:00
pyos a9be27e330 FIR CFG: add union nodes
Quick quiz:

 Q: In a CFG, what does `a -> b -> c -> d` mean?
 A: `a`, then `b`, then `c`, then `d`.

 Q: In a CFG, what does `a -> b -> d; a -> c -> d` mean?
 A: `a`, then `b` or `c`, then `d`.

 Q: So how do you encode "a, then (b, then c) or (c, then b), then d`?
 A: You can't.

Problem is, you need to, because that's what `a; run2({ b }, { c }); d`
does when `run2` has a contract that it calls both its lambda arguments
in-place: `shuffle(listOf(block1, block2)).forEach { it() }` is a
perfectly valid implementation for it, as little sense as that makes.

So that's what union nodes solve. When a node implements
`UnionNodeMarker`, its inputs are interpreted as "all visited in some
order" instead of the normal "one of the inputs is visited".

Currently this is used for data flow. It *should* also be used for
control flow, but it isn't. But it should be. But that's not so easy.

BTW, `try` exit is NOT a union node; although lambdas in one branch can
be completed according to types' of lambdas in another, data does not
flow between the branches anyway (since we don't know how much of the
`try` executed before jumping into `catch`, and `catch`es are mutually
exclusive) so a `try` expression is more like `when` than a function
call with called-in-place-exactly-once arguments. The fact that
`exitTryExpression` used `processUnionOfArguments` in a weird way
should've hinted at that, but now we know for certain.
2022-12-08 10:19:29 +00:00
pyos 99bebfa183 FIR DFA: merge non-conflicting aliases from union flows
E.g. after `f({ x = a }, { x })`, if `f` calls both lambdas in-place,
`x` should be aliased to `a` even though only one path does that.
2022-12-08 10:19:29 +00:00
pyos e79b595639 FIR DFA: attach PersistentFlow directly to nodes 2022-12-08 10:19:29 +00:00
pyos 8d2ac141c3 FIR DFA: split Flow into PersistentFlow and MutableFlow
The distinction is similar to persistent data structures and their
builders. Only the MutableFlow can be passed to LogicSystem for
modification; when it's ready, it can be converted into PersistentFlow
and attached to a CFG node.

The result is that the API is cleaner, the implementation is a bit more
neat, and hopefully the use of PersistentHashMap.Builder improves
performance a little. Also the node-to-flow map can now be removed in
favor of just storing PersistentFlow inside a node, seeing as it's
explicitly immutable and all that.
2022-12-08 10:19:28 +00:00
pyos e1f0566738 FIR CFG: refactor handling of boolean operators a bit
To reduce the number of functions in FirDataFlowAnalyzer.
2022-12-08 10:19:28 +00:00
pyos 16b8811697 FIR DFA: take all statements from ?. if result is non-null.
I.e. a?.f(b as T) != null => b is T.

This also allows to remove the copyAllInformationFrom hack by moving the
edge directly in the control flow graph.
2022-12-08 10:19:28 +00:00
pyos 3392e066df FIR DFA: add more called-in-place tests 2022-12-08 10:19:27 +00:00
pyos f485413cfd FIR DFA: x !is T? => x != null
^KT-22996 tag fixed-in-k2
2022-12-08 10:19:27 +00:00
pyos 02fedeb9ed FIR DFA: revalidate reassigned variables after loops
If a certain type statement is true on loop entry and all continue
paths, then it is also true on exit if the condition did not reassign
the variable.

^KT-7676 tag fixed-in-k2
2022-12-08 10:19:27 +00:00
pyos f9745bd3f1 FIR DFA: make continue jump to condition entry, not loop entry
It's also not a backwards jump in do-while, unless it's in the loop's
condition, which is a stupid "feature" IMO. As you can probably tell
from the comments added in this commit.
2022-12-08 10:19:26 +00:00
Mikhail Glukhikh 5db804023e K2: inline shouldRunSamConversionForFunction
Here I delete the function which should always return true for LV>=1.4.
See different SamConversionOracle implementations for K1
2022-12-07 22:09:21 +00:00
pyos e359658c55 Minor: slightly speed up isSamType for FIR IDE 2022-12-07 22:09:20 +00:00
pyos 1232346202 Minor: merge FirSamResolver and its only implementation 2022-12-07 22:09:20 +00:00
pyos 0d46dfc1ba FIR: fix substitution of type arguments in SAM type aliases
^KT-54730 Fixed
2022-12-07 22:09:20 +00:00
pyos 3253789093 FIR: move typealias SAM constructor computation to FirSamResolver 2022-12-07 22:09:19 +00:00
Mikhail Glukhikh 982e743774 Minor: simplify FirScope.processConstructorsByName and things around 2022-12-07 22:09:19 +00:00
Pavel Mikhailovskii 4676072137 KT-51284 Fix SAM conversion for methods with context receivers 2022-12-07 09:01:21 +00:00
Pavel Mikhailovskii 2d69fd5a8a KT-52027 Encapsulate and fix calculation of parameter indices 2022-12-06 23:16:11 +00:00
Ilya Kirillov 7a89ca495c [LL FIR] do not execute resolve under a non-cancellable session
The sessions are invalidated on the PCE
2022-12-06 21:20:41 +00:00
Pavel Mikhailovskii 25ad7fe31c KT-51863 Account for context receivers in calls with changed parameter order 2022-12-06 16:28:08 +00:00
Ilya Kirillov 8e70dbc7e3 [FIR] fix SOE on cycle hierarchy of Java classes during status computation 2022-12-05 17:27:43 +01:00
Ilya Kirillov 03549d4b98 [FIR] remove suspicious safe-cast to FirResolvedDeclarationStatus in status tranformer
Statuses of super members should already be preresolved
2022-12-05 17:27:43 +01:00
Ilya Kirillov 82fe86c003 [FIR] fix lazy resolution contract violation in status resolve transformer
Previously, there was issue with resolving statuses of properties' super
declarations for anonymous/local classes.

And this problem was hidden by calling lazyResolveToPhase(STATUS) which
is a violation of lazy resolution contract as lazy resolution to status
cannot be called from the status phase itself

^KT-54890
2022-12-05 17:27:42 +01:00
Ilya Kirillov c899f6dae3 [LL FIR] fix lazy resolution of member property statuses for anonymous objects
Previously, statuses of superclass which are not local was not ignored

Sometimes it worked in the IDE by calling lazyResolveToPhase
which is a violation of the lazy resolution contract

^KT-54890
2022-12-05 17:27:42 +01:00
Ilya Kirillov c66fbf5c0e [LL FIR] fix lazy resolution of member-property statuses for local classes
Previously, statuses of superclass which are not local was not ignored

Sometimes it worked in the IDE by calling lazyResolveToPhase
which is a violation of the lazy resolution contract

^KT-54890
2022-12-05 17:27:42 +01:00
Steven Schäfer 21fef70367 Standardize context receiver parameter names
Previously, FIR used `_context_receiver_n` while FE10 used `<this>` for
all context receiver parameters. This commit changes the code in FE10
to follow the convention from FIR.
2022-12-03 00:11:38 +01:00
Mikhail Glukhikh 5cf1a88c42 FE: move delegate name functions to NameUtils 2022-12-02 21:54:18 +00:00
Steven Schäfer a7ba081d22 FIR: Fix interface delegation ABI
- Unifies the name of the `$$delegate_<n>` field between K1 and K2.
- Make the `$$delegate_<n>` field private
2022-12-02 21:54:18 +00:00
Vladislav Grechko cb93e9d408 Get rid of redundant boxing of unsigned operands of infix 'compareTo'
^KT-48759: Fixed
2022-12-02 18:25:52 +00:00
Ilya Kirillov 9dd398dc77 [FIR] do not consider FirDefaultPropertyBackingField to be always resolved to BODY_RESOLVE
Otherwise, lazy resolve will never resolve it
2022-12-02 17:08:34 +00:00
Egor Kulikov fb2485f83c [FIR] Make constructor delegate lazy in RawFirBuilder
Fifth step for ^KT-52615

Merge-request: KT-MR-7860
Merged-by: Egor Kulikov <Egor.Kulikov@jetbrains.com>
2022-12-02 03:12:51 +00:00
Sergej Jaskiewicz 1539d7ef1a [klib] Bring package names in sync with the directory layout
Basically, some package names were Native-specific, whilst the packages
themselves were not Native-specific at all. This was already reflected
in the directory layout, but not in the package names.
This is fixed here.

NFC, just an automatic rename of packages with fixes of imports.
2022-12-01 21:46:43 +00:00
Dmitriy Novozhilov 0af16f03c5 [FIR] Fix formatting 2022-12-01 07:29:39 +00:00
Dmitriy Novozhilov 8d2701209e [FIR] Add documentation to AbstractPredicate and FirPredicateBasedProvider 2022-12-01 07:29:39 +00:00
Dmitriy Novozhilov 6864433581 [FIR] Support resolution of meta-annotations before supertypes
Now annotations are resolved with following algorithm:
1. On COMPILER_REQUIRED_ANNOTATIONS we resolve all annotations
     and store results if this is compiler annotation, plugin annotation,
     or annotation with meta-annotation (meta annotations are checked
     recursively with designated resolution if needed)
2. On TYPES stage we resolve all those annotations once again and if
     some annotation changes resolution then we keep type from p.1 and
     report error on this annotation, so user should disambiguate it

Ambiguity may occur because of nested annotations with same name as
  plugin annotations:

```
annotation class SomeAnnotation // (1) plugin annotation

open class Base {
    annotation class SomeAnnotation // (2)
}

class Derived : Base() {
    @SomeAnnotation // <-----------------
    class Inner
}
```
At COMPILER_REQUIRED_ANNOTATIONS annotation call will be resolved to (1)
  because at this stage supertypes are not resolved yet, and we consider
  only importing scopes. At the TYPES stage we will find correct
  annotation from supertype
2022-12-01 07:29:39 +00:00
Dmitriy Novozhilov aaf0a1f396 [FIR] Introduce shouldNotBeCalled utility function 2022-12-01 07:29:38 +00:00
Dmitriy Novozhilov 246dc985a6 [FIR] Rework predicates system
Now predicates are split into LookupPredicate and DeclarationPredicate
  hierarchies. First one allows to perform global search for declarations
  and second one allows to check if some declaration matches the predicate.
Predicates with meta annotations are excluded from LookupPredicates,
  because it's impossible to create index of annotations with meta-annotations,
  because they can be located inside binary dependencies (so to achieve
  this we need to scan the whole classpath).
Also only one predicate with meta-annotations is left in DeclarationPredicate
  hierarchy (AnnotatedWithMeta)

^KT-53874 Fixed
^KT-53590 Fixed
2022-12-01 07:29:37 +00:00
Dmitriy Novozhilov dff5799c58 [Test] Don't create separate .fir.txt file in BytecodeListingHandler if not necessary 2022-12-01 07:29:35 +00:00