Compare commits

...

145 Commits

Author SHA1 Message Date
Ilmir Usmanov
d8c0a81da7 IC: Forbid inner classes inside inline classes
#KT-43067 Fixed
2020-12-03 18:41:11 +01:00
Ilmir Usmanov
481a3878bd Value classes: Allow nested inline classes 2020-12-03 18:41:01 +01:00
Ilmir Usmanov
516fce37db Value classes: Allow unsigned arrays in annotations
including varargs, apparently.
So, we allow unsigned types and unsigned arrays in annotations,
but disallow user-defined inline classes.
 #KT-23816 Fixed
2020-12-03 17:22:08 +01:00
Alexander Udalov
a9c072f826 Regenerate compiler tests 2020-12-03 17:02:35 +01:00
Dmitry Petrov
caea0a9df0 JVM_IR KT-43721 coerce intrinsic result to corresponding unsigned type 2020-12-03 16:44:26 +03:00
Mads Ager
c776fcbd00 [JVM_IR] Fix incorrect name in inner class attributes. 2020-12-03 13:41:36 +01:00
Mads Ager
fae5b8da4b [JVM] Do not put the name of default lambda parameter in LVT.
If we do, the local variable table will not make sense. As as
example:

```
inline fun foo(getString: () -> String = { "OK" }) {
  println(getString())
}

inline fun bar() {
}

fun main() {
    bar()
    foo()
}
```

leads to the following bytecode:

```
  public static final void main();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
      stack=2, locals=4, args_size=0
         0: iconst_0
         1: istore_0
         2: nop
         3: nop
         4: iconst_0
         5: istore_1
         6: nop
         7: ldc           #53                 // String OK
         9: astore_2
        10: iconst_0
        11: istore_3
        12: getstatic     #30                 // Field java/lang/System.out:Ljava/io/PrintStream;
        15: aload_2
        16: invokevirtual #36                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
        19: nop
        20: return
      LineNumberTable:
        line 9: 0
        line 13: 2
        line 10: 3
        line 14: 4
        line 15: 6
        line 16: 7
        line 17: 19
        line 11: 20
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            2       1     0 $i$f$bar   I
            6      14     1 $i$f$foo   I
            4      16     0 getString$iv   Lkotlin/jvm/functions/Function0;
```

The `getString$iv` local should not be there. It has been inlined away.
Leaving it in the local variable table leads to inconsistent locals
info. Local 0 contains an int but we declare a local of type
Function0.
2020-12-03 13:41:36 +01:00
Dmitriy Dolovov
e5c46a86aa [Commonizer] Minor. Rename file 2020-12-03 15:33:26 +03:00
Dmitriy Dolovov
daf42c1ee6 [Commonizer] Remove unnecessary nullability at CirKnownClassifiers.commonDependeeLibraries 2020-12-03 15:33:20 +03:00
Vladimir Dolzhenko
984b3c2f30 Fix to address platform expectation for project path
Project path has to be absolute
2020-12-03 12:35:31 +01:00
Dmitriy Dolovov
68f8e88d8b [Commonizer] Introduce various types of classifier caches
- New CirCommonizedClassifiers and CirForwardDeclarations caches
- New CirProvidedClassifiers cache with classifier names loaded from arbitrary modules
- CirClassifiersCache is replaced by CirKnownClassifiers umbrella
- Replace the remaining usages of 'isUnderStandardKotlinPackages' by delegation to
  CirKnownClassifiers.commonDependeeLibraries
2020-12-03 13:11:40 +03:00
Dmitriy Dolovov
dce3d4d1b7 [Commonizer] Rename InputTarget and OutputTarget
Rename target classes to better reflect their meaning:
- InputTarget -> LeafTarget
- OutputTarget -> SharedTarget
2020-12-03 13:11:33 +03:00
Dmitriy Dolovov
b0ff3e7e5e [Commonizer] More fine-grained control of commonized module dependencies
- Reduce usage of 'isUnderStandardKotlinPackages' check in commonizer source code
- Rely on common module dependencies supplied via commonizer Parameters which not only
  Kotlin standard library but may also include common fragments of other libraries
2020-12-03 13:11:27 +03:00
LepilkinaElena
9d749feb64 Fix gradle test for endorsed libraries in K/N (#3953) 2020-12-03 12:57:02 +03:00
Victor Petukhov
d25ad269e0 Reuse captured arguments for flexible type's bounds properly, by equality of type constructors modulo mutability and type argument
^KT-43630 Fixed
2020-12-03 11:13:41 +03:00
Victor Petukhov
9f58e4bcfe Add FlexibleTypeBoundsChecker which can answer the question: "can two types be different bounds of the same flexible type?"; and provide the base bound for the given bound.
For instance: `MutableList` and `List` may be within the same flexible type.
2020-12-03 11:13:39 +03:00
Victor Petukhov
1ccbb09029 Fix formatting in flexibleTypes.kt 2020-12-03 11:13:38 +03:00
Shagen Ogandzhanian
8e5bcd349e [JS IR] Respect JsExport while assigning stable names
see https://youtrack.jetbrains.com/issue/KT-43404
2020-12-02 22:21:16 +01:00
Alexander Udalov
6b649d02d3 JVM IR: fix visibility/modality of $suspendImpl methods
#KT-43614 Fixed
2020-12-02 20:53:55 +01:00
Alexander Udalov
8ce2e4654b JVM IR: allow custom toArray to have any array type
To avoid breaking Java source compatibility. This problem can be fixed
later once JVM IR is stabilized.

 #KT-43111 Fixed
2020-12-02 20:53:47 +01:00
Dmitry Petrov
e6a3e38c4d JVM_IR no static inline class members for Kotlin JvmDefault methods
KT-43698 KT-43051
2020-12-02 20:04:13 +03:00
Ivan Gavrilovic
11673bd09c KAPT: add tests for processed types, remove dead code, simplify logic
Add integration test which checks if only types can be
reprocessed in an incremental round. Also, remove unused
`invalidateTypesForFiles` method.

Furthermore, clarify that types that are reprocessed
(i.e types from .class files) are not necessarily
aggregating types, but simply types that should be reprocessed.

Test: KaptIncrementalWithIsolatingApt.testClasspathChangesCauseTypesToBeReprocessed
2020-12-02 16:55:50 +01:00
Ivan Gavrilovic
08a2b47c77 Incremental KAPT: fix typo and do check processed sources on
clean build
2020-12-02 16:55:49 +01:00
Ivan Gavrilovic
0522583602 Incremental KAPT: add test for isolating AP with classpath origin
Add a regression test for KT-34340 that allows APs to have
classpath types as origins.
2020-12-02 16:55:49 +01:00
Ivan Gavrilovic
05e47da458 Incremental KAPT: simplify impacted types computation
Process aggregating types first, and when computing impacted types
compute isolating generated impacted by classpath changes first.
2020-12-02 16:55:49 +01:00
Ivan Gavrilovic
c7e5beece5 Use types are origins for incremental KAPT and track generated source
This change introduces tracking of generated sources structure in order
to e.g track classpath changes impacting generated sources. This fixes KT-42182.

Also, origin tracking for isolating processors is now using types, allowing
for origin elements from classpath. This fixes KT-34340. However, classpath
origin is used only to invalidate generated files when the type changes and
processing will not be requested for that type. This is in line with the
incap spec.
2020-12-02 16:55:49 +01:00
Shagen Ogandzhanian
d512158c25 [JS IR] Remove redundant guard assertion for extension funs with default params
Introduce corresponding test
See https://youtrack.jetbrains.com/issue/KT-41076
2020-12-02 16:45:12 +01:00
Alexander Udalov
a917ebd11e JVM IR: use origin to detect property/typealias $annotations methods
Now that DEFAULT_IMPLS origins for methods do not exist after previous
commits, the name heuristic is no longer needed.
2020-12-02 15:54:15 +01:00
Alexander Udalov
c7c793c724 JVM IR: do not use origin DEFAULT_IMPLS_BRIDGE(_TO_SYNTHETIC)
Instead, check that origin of the parent class is DEFAULT_IMPLS. Also,
add a separate origin SUPER_INTERFACE_METHOD_BRIDGE for interface
methods with bodies that are copied to classes.
2020-12-02 15:54:14 +01:00
Alexander Udalov
d41d1bf64d JVM IR: remove obsolete isDefaultImplsBridge in findInterfaceImplementation 2020-12-02 15:54:14 +01:00
Alexander Udalov
be03bc477d JVM IR: do not use origin DEFAULT_IMPLS_WITH_MOVED_RECEIVERS(_SYNTHETIC)
Instead, check that origin of the parent class is DEFAULT_IMPLS.
2020-12-02 15:54:14 +01:00
Alexander Udalov
988cc52174 JVM IR: do not use origin DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY(_SYNTHETIC)
It was only used to generate deprecation in codegen, but it's annotated
with `javaLangDeprecatedConstructorWithDeprecatedFlag`, and a similar
annotation for IrField results in ACC_DEPRECATED. Adapt codegen to
generate this flag for functions too.
2020-12-02 15:54:13 +01:00
Ilya Goncharov
697b2b02f1 [JS IR] Add properties lazy initialization with multiple modules
[JS IR] Move tests into compiler/testData

[JS IR] Add cyclic dependencies with lazy property initialization

[JS IR] Add test on not initialization in case of call non properties (classed, objects, enum classes, const vals)

[JS IR] Add initialization through top level

[JS IR] Ignore enum getInstance function in property lazy initialization

[JS IR] Use let function with useful result instead of pure apply and also

[JS IR] Remove duplicated tests in js.translator
2020-12-02 17:35:30 +03:00
pyos
6cb573cb45 [FIR] Import parents of companion objects first
Otherwise, information about members moved from companion objects to the
parent class (e.g. on JVM, companion object fields -> static fields in
parent class) will be incorrect.
2020-12-02 15:29:42 +03:00
Igor Yakovlev
4d7b6c022b [FIR IDE] LC Anonymous to SuperClass type substitution 2020-12-02 15:13:09 +03:00
Igor Yakovlev
842d31d04e [FIR IDE] Fix HL API test data
Ignore failed tests
Set passing test to comparison mode
Fix testdata for symbols
Fix invalid LAZINESS parameter reading from testdata
2020-12-02 15:13:09 +03:00
Igor Yakovlev
7cbcde77dd [FIR IDE] LC More accurate fields visibility and modality 2020-12-02 15:13:08 +03:00
Igor Yakovlev
a7d7aa123e [FIR IDE] LC minor refactorings 2020-12-02 15:13:08 +03:00
Igor Yakovlev
a1603716ed [FIR IDE] LC Add anonymous objects support
+minor fixes
2020-12-02 15:13:08 +03:00
Igor Yakovlev
5630667320 [FIR IDE] LC better support for JvmMultiFileClass annotation 2020-12-02 15:13:08 +03:00
Igor Yakovlev
56c3faee00 [FIR IDE] LC Fix generating unique field names 2020-12-02 15:13:08 +03:00
Igor Yakovlev
18e5af37ff [FIR IDE] LC Fixed incorrect JvmOverloads 2020-12-02 15:13:07 +03:00
Igor Yakovlev
535aa1e9e0 [FIR IDE] LC expand typealiases for applied annotations 2020-12-02 15:13:07 +03:00
Igor Yakovlev
229c6f97ac [FIR IDE] LC Fixed nullability for getters 2020-12-02 15:13:07 +03:00
Igor Yakovlev
aff90b335c [FIR IDE] LC Implement special keywords like transient, volatile, synchronized, strictfp 2020-12-02 15:13:07 +03:00
Igor Yakovlev
6aff96a401 [FIR IDE] Remove extra analyzing for local declarations 2020-12-02 15:13:07 +03:00
Igor Yakovlev
3fc424246b [FIR IDE] LC basic support for type arguments
+ small fixes for deprecation, etc.
2020-12-02 15:13:06 +03:00
Igor Yakovlev
2a8f783393 [FIR IDE] HL API Better support of nullability and modality 2020-12-02 15:13:06 +03:00
Igor Yakovlev
4c69043a15 [FIR IDE] Move refactoring and minor bugfixing for modality, jvmname, etc. 2020-12-02 15:13:06 +03:00
Igor Yakovlev
3e3ec5fc69 [FIR IDE] Supporting member scopes in EnumEntries 2020-12-02 15:13:06 +03:00
Igor Yakovlev
fdaf31dbf3 [FIR IDE] Fix typemapping for FirTypeAliasSymbol 2020-12-02 15:13:05 +03:00
Igor Yakovlev
aae0081f3f [FIR IDE] Fixed invalid HL API getters request 2020-12-02 15:13:05 +03:00
Mikhail Glukhikh
2429f429c5 [FIR] Set isStubTypeEqualsToAnything = true for inference as in FE 1.0
#KT-43616 Fixed
2020-12-02 14:49:08 +03:00
Mikhail Glukhikh
eae8821dec FIR Java: unbind possible named annotation cycle 2020-12-02 14:48:46 +03:00
Nikolay Krasko
2ffedd2731 Fix Daemon compiler tests on Windows
In 202 platform tearDown tries to remove temporary directory, but this
fails on Windows, because while Daemon is active directory can't be
deleted.
2020-12-02 14:23:32 +03:00
Georgy Bronnikov
8a969dab7d Bugfix for FIR 2020-12-02 09:47:34 +03:00
Georgy Bronnikov
b23d7a79b0 IR: get rid of WrappedDescriptorWithContainerSource 2020-12-02 09:47:34 +03:00
Georgy Bronnikov
c0cd9064d7 IR: IrMemberWithContainerSource 2020-12-02 09:47:34 +03:00
Georgy Bronnikov
14b773c1fd JVM_IR: do not rely on DescriptorWithContainerSource in InlineCodegen 2020-12-02 09:47:34 +03:00
Ilmir Usmanov
f0a787551a Value classes: Raise retention of @JvmInline to RUNTIME
so it will be visible by reflection
2020-12-01 23:45:50 +01:00
Ilmir Usmanov
129de76288 Value classes: Generate @JvmInline annotation for inline classes
but not for value classes.
Since inline classes and value classes share the same flag, we use
presence of the annotation to distinguish them.
2020-12-01 23:45:47 +01:00
Dmitry Petrov
ae8abd1832 Minor: ignore nestedBigArityFunCalls.kt in WASM 2020-12-01 19:43:52 +03:00
Dmitry Petrov
1412ee96f8 JVM_IR KT-43524 static wrappers for deprecated accessors are deprecated 2020-12-01 19:43:52 +03:00
Dmitry Petrov
e96fc74ffa JVM_IR KT-43519 no delegates for external funs in multifile facades
Also add ABI tests for @JvmStatic/JvmOverloads + 'external'.
2020-12-01 19:43:52 +03:00
Dmitry Petrov
2b4564059e JVM_IR KT-43459 fix $annotations method receiver type 2020-12-01 19:43:51 +03:00
Dmitry Petrov
85b5948931 JVM_IR KT-43051 no static inline class members for default Java methods 2020-12-01 19:43:51 +03:00
Dmitry Petrov
4c3ffc3451 JVM_IR KT-41911 process big arity 'invoke' arguments recursively 2020-12-01 19:43:51 +03:00
Georgy Bronnikov
b0e2d5637d Mute a test for WASM 2020-12-01 18:37:55 +03:00
Georgy Bronnikov
bb4950a021 Regenerate LightAnalysis tests 2020-12-01 16:01:48 +03:00
Dmitriy Novozhilov
91bccad72b [JS] Fix path of generated js tests 2020-12-01 15:43:25 +03:00
Mikhail Glukhikh
7550a1870b [FIR2IR] Make checks about f/o accessors necessity more precise
#KT-43342 Fixed
2020-12-01 14:23:19 +03:00
Ilya Goncharov
b179b567a9 [Gradle, JS] Add test on resolution of js project with directory dependency
^KT-43668 fixed
2020-12-01 14:12:39 +03:00
Alexander Udalov
2fdc2dfaaf JVM IR: fix regression in JvmStatic-in-object lowering for properties
References to properties with JvmStatic getter were not handled in
MakeCallsStatic (by overwriting dispatchReceiver with null) because the
property itself was not considered static.

 #KT-43672 Fixed
2020-12-01 11:54:45 +01:00
Georgy Bronnikov
4607eca987 JVM_IR: bug fix in classFileContainsMethod
The old test sequence failed for toplevel functions because of file
class wrappers, so that the second branch was never invoked.
2020-12-01 13:15:51 +03:00
Roman Golyshev
f50480d258 FIR IDE: Fix resolving of nested types in type references 2020-12-01 09:24:20 +00:00
Roman Golyshev
94a5379631 FIR IDE: Add tests for resolving from nested types references
Some of those tests are failing in the FIR IDE
2020-12-01 09:24:20 +00:00
Alexander Udalov
19ca9c0fde Enable JVM IR for bootstrap in the project 2020-11-30 22:09:24 +01:00
Alexander Udalov
606de26646 JVM IR: fix generation of equals/hashCode for fun interfaces over references
... in case `-Xno-optimized-callable-references` is enabled. Before this
change, the generated abstract equals/hashCode methods were considered
as accidental overrides because they did not have equals/hashCode from
the supertype in the overriddenSymbols list.

 #KT-43666 Fixed
2020-11-30 19:15:20 +01:00
pyos
50ae360ff9 FIR2IR: fix the way annotations are moved to fields
1. When an annotation has multiple targets, the priority goes like this:
    constructor parameter (if applicable) -> property -> backing field.

 2. The argument to `kotlin.annotation.Target` is a vararg, so that
    should be handled as well.

 3. `AnnotationTarget.VALUE_PARAMETER` allows receivers, constructor
    parameters, and setter parameters, while `AnnotationTarget.FIELD` allows
    both backing fields and delegates.

Known issue: java.lang.annotation.Target is not remapped to the Kotlin
equivalent, so things are still broken for pure Java annotations.
2020-11-30 20:29:18 +03:00
Andrei Klunnyi
4817d5e01d KTIJ-585 [Gradle Runner]: main() cannot be launched from AS 4.1
Android gradle-project model differs from what we have for pure Java
and MPP. It's the reason why application classpath cannot be collected
correctly.
Until universal solution is provided delegation to gradle is put under
the registry flag. If disable platform runner is used as before.
2020-11-30 15:44:37 +00:00
Ilya Goncharov
995d96e5a3 [JS IR] Use one concat elements for non vararg and vararg arguments
^KT-42357 fixed
2020-11-30 17:34:44 +03:00
Ilya Goncharov
67e4b0948e [JS IR] Constructor call with vararg invoking with apply
[JS IR] Nullize external empty varargs

[JS IR] Concat varargs with array of nonVarargs arguments

^KT-42357 fixed
2020-11-30 17:33:28 +03:00
Ilya Goncharov
ac42dcd8da [JS IR] Add test for external fun vararg
[JS IR] Add tests with empty vararg and default arg before it

[JS IR] Ignore backend in tests instead of target backend

[JS IR] Add function with named spread operator

[JS IR] Remove ignoring of current js backend in jsExternalVarargFun

[JS IR] Add with arguments after vararg

^KT-42357 fixed
2020-11-30 17:33:07 +03:00
Ilya Goncharov
e7789d2e30 [Gradle, JS] Add filter on file on fileCollectionDependencies because Gradle can't hash directory
^KT-43668 fixed
2020-11-30 17:04:30 +03:00
Dmitry Petrov
96ed99d62e JVM_IR KT-40305 no nullability assertions on built-in stubs 2020-11-30 15:49:02 +03:00
Dmitry Petrov
b2aed536c9 JVM_IR KT-39612 process subexpressions recursively in 'name' lowering 2020-11-30 15:49:02 +03:00
Dmitry Petrov
3b604cfa7f JVM_IR KT-32701 generate multiple big arity invokes, report error later 2020-11-30 15:49:02 +03:00
Dmitry Petrov
a157b58c61 JVM_IR KT-43610 keep track of "special bridges" for interface funs 2020-11-30 15:49:01 +03:00
Dmitriy Novozhilov
c43db2ee8d [TEST] Inherit UpdateConfigurationQuickFixTest from KotlinLightPlatformCodeInsightFixtureTestCase
This is needed for proper test muting
2020-11-30 15:39:05 +03:00
Alexander Udalov
7d9eeb6847 Minor, add workaround for KT-42137 2020-11-30 12:44:42 +01:00
Alexander Udalov
e1d54bf99f Minor, add workaround for KT-43666 2020-11-30 12:37:27 +01:00
Mikhael Bogdanov
ad579de328 Don't run KaptPathsTest.testSymbolicLinks test on Windows 2020-11-30 12:17:00 +01:00
Dmitriy Novozhilov
d706a7ff74 Build: mute failing tests
Those tests are failing only on windows agents after
  switch to 202 platform
2020-11-30 13:40:29 +03:00
pyos
1cccf2645f FIR: serialize HAS_CONSTANT at least for const properties
Non-const properties may need them too with if the 1.4 feature
NoConstantValueAttributeForNonConstVals is disabled.
2020-11-30 13:05:28 +03:00
Mikhail Glukhikh
04d9afe83e FIR Java: add workaround for classId = null in JavaAnnotation 2020-11-30 13:05:27 +03:00
Mikhail Glukhikh
feb13f98c0 [FIR2IR] Handle Java annotation parameter mapping properly
#KT-43584 Fixed
2020-11-30 13:05:26 +03:00
Mikhail Glukhikh
9b30655d66 [FIR] Load Java annotations named arguments properly (see KT-43584) 2020-11-30 13:05:23 +03:00
Roman Golyshev
e6f380182a Revert "FIR IDE: Add tests for resolving from nested types references"
This reverts commit e127ea3d
2020-11-30 12:37:40 +03:00
Roman Golyshev
f8b6559b6a Revert "FIR IDE: Fix resolving of nested types in type references"
This reverts commit dba14ba9
2020-11-30 12:37:26 +03:00
Roman Golyshev
dba14ba995 FIR IDE: Fix resolving of nested types in type references 2020-11-30 09:26:15 +00:00
Roman Golyshev
e127ea3dad FIR IDE: Add tests for resolving from nested types references
Some of those tests are failing in the FIR IDE
2020-11-30 09:26:15 +00:00
Mikhael Bogdanov
8a00470b40 Enable kotlin-annotation-processing-base tests on TC 2020-11-30 10:06:22 +01:00
Sergey Bogolepov
29bed39a54 Bump to native version version with watchos_x64 enabled 2020-11-30 14:01:12 +07:00
Sergey Bogolepov
37ee2cbe53 [KT-43276] Update tests to support watchos_x64 2020-11-30 14:01:12 +07:00
Sergey Bogolepov
d6f54a7730 [KT-43276] Fix watchos target shortcut. 2020-11-30 14:01:12 +07:00
Sergey Bogolepov
f3424a98b7 generateMppTargetContainerWithPresets: remove unneeded hack 2020-11-30 14:01:12 +07:00
Sergey Bogolepov
e39560b134 [KT-43276] Add watchos_x64 target 2020-11-30 14:01:12 +07:00
Ilya Gorbunov
0634351fbc Introduce pathString/absolute/absolutePathString
Rename invariantSeparatorsPath to invariantSeparatorsPathString
to have more consistent names of methods returning path strings.

KT-19192
2020-11-29 17:46:47 +03:00
Ilya Gorbunov
84f5a294f7 Allow passing null parent directory to createTempFile/Directory
null signifies the default temp directory.

KT-19192
2020-11-29 17:46:47 +03:00
Ilya Gorbunov
64d85f259c Relax writeText/appendText parameter type to CharSequence
KT-19192
2020-11-29 17:46:47 +03:00
Pavel Punegov
2ee8bf7dde Add fastutil dependency for 202 and higher platforms 2020-11-28 14:26:01 +03:00
Dmitriy Novozhilov
f668e906cc Build: unmute passed tests 2020-11-28 14:26:01 +03:00
Dmitriy Novozhilov
e7d305b97a Build: mute failing stepping tests 2020-11-28 14:26:00 +03:00
Dmitriy Novozhilov
78c786de46 Build: Mute failing goto declaration tests 2020-11-28 14:26:00 +03:00
Dmitriy Novozhilov
33b545aea7 Build: Mute failing gradle import with android tests 2020-11-28 14:25:59 +03:00
Dmitriy Novozhilov
85c59328c7 [DEBUGGER] Temporary mute AbstractKotlinEvaluateExpressionTest 2020-11-28 14:25:59 +03:00
Vladimir Dolzhenko
3d33ea7da8 Use absolute paths to locate existed projects to open in AbstractConfigureKotlinTest 2020-11-28 14:25:58 +03:00
Vladimir Dolzhenko
124888eb43 Revert back AddFunctionParametersFix test data output for 201- 2020-11-28 14:25:58 +03:00
Dmitriy Novozhilov
e251a9be14 Build: fix finding layout-api jar in parcelize box test due to platform change 2020-11-28 14:25:57 +03:00
Dmitriy Novozhilov
cc1a0bf6d7 [FE] Update testdata 2020-11-28 14:25:57 +03:00
Vladimir Dolzhenko
17e6e88176 Fixed AddFunctionParametersFix test data output 2020-11-28 14:25:57 +03:00
Dmitriy Novozhilov
406e863a73 [FE] Fix creating location of compiler errors in CLI 2020-11-28 14:25:56 +03:00
Dmitriy Novozhilov
dc364b8be4 Remove useless @author comment 2020-11-28 14:25:56 +03:00
Vladimir Dolzhenko
95e5ea4840 temporary ignore/disable tests 2020-11-28 14:25:55 +03:00
Dmitriy Novozhilov
02f71a63b8 [FE] Disable SKIP_DEBUG flag when building java model from binaries
This is needed to avoid skipping jvm annotations with names of
  function parameters
2020-11-28 14:25:55 +03:00
Dmitriy Novozhilov
bf1abed246 Build: add shadowing processor for core.xml in embeddable compiler 2020-11-28 14:25:54 +03:00
Dmitriy Novozhilov
ad953b6285 Build: remove redundant bunch TODO's 2020-11-28 14:25:54 +03:00
Dmitriy Novozhilov
986ab9cb54 Build: remove useless .as40 files 2020-11-28 14:25:54 +03:00
Dmitriy Novozhilov
1b559fe676 Don't set KOTLIN_BUNDLED in unit tests 2020-11-28 14:25:53 +03:00
Dmitriy Novozhilov
7396abf5a4 Build: add fastutil dependency to scripting tests 2020-11-28 14:25:53 +03:00
Dmitriy Novozhilov
5ab9710cc5 Remove ./local directory from CodeConformanceTest 2020-11-28 14:25:52 +03:00
Dmitriy Novozhilov
d3ef0eb519 Build: register missing TreeAspect service in KtParsingTestCase 2020-11-28 14:25:52 +03:00
Dmitriy Novozhilov
68719831ee Build: update asm version in kotlinp 2020-11-28 14:25:52 +03:00
Dmitriy Novozhilov
dc35a13008 Build: remove useless bunch files 2020-11-28 14:25:51 +03:00
Dmitriy Novozhilov
46fcc7d59d Build: fix registration of ClassFileDecompilers extension 2020-11-28 14:25:51 +03:00
Dmitriy Novozhilov
48cbb74a01 Build: drop deprecated extension point used in test of old j2k 2020-11-28 14:25:50 +03:00
Dmitriy Novozhilov
d887814cc5 Build: fix compilation of :libraries:tools:kotlin-maven-plugin-test 2020-11-28 14:25:50 +03:00
Dmitriy Novozhilov
4779092ba5 Build: fix API differences between 201 and 202 in idea performance tests 2020-11-28 14:25:49 +03:00
Dmitriy Novozhilov
2a053c214d Build: fix API differences between 201 and 202 in scratch tests 2020-11-28 14:25:49 +03:00
Dmitriy Novozhilov
d50d56f68c Build: fix API differences between 201 and 202 in NewKotlinFileAction 2020-11-28 14:25:49 +03:00
Dmitriy Novozhilov
e4e28a5495 Build: update grovy dependencies in :compiler:tests-spec 2020-11-28 14:25:48 +03:00
Dmitriy Novozhilov
07dd9179e8 Build: change 202 platform version 2020-11-28 14:25:48 +03:00
Dmitriy Novozhilov
eeb9b3214c Switch to 202 platform 2020-11-28 14:25:19 +03:00
Ilya Muradyan
89bba93615 Introduce GetScriptingClassByClassLoader interface
It is needed to override default JVM behaviour
2020-11-28 09:44:06 +01:00
Ilya Muradyan
65ce7cd0c2 Fix path for Windows in Fibonacci test 2020-11-28 09:44:06 +01:00
781 changed files with 13778 additions and 7746 deletions

11
.bunch
View File

@@ -1,7 +1,6 @@
201
202
203_202
193
as40_193
as41
as42_202
201
193_201
as40_193_201
as41_201
as42

View File

@@ -188,7 +188,7 @@ extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
extra["versions.ktor-network"] = "1.0.1"
if (!project.hasProperty("versions.kotlin-native")) {
extra["versions.kotlin-native"] = "1.4.30-dev-17200"
extra["versions.kotlin-native"] = "1.4.30-dev-17395"
}
val intellijUltimateEnabled by extra(project.kotlinBuildProperties.intellijUltimateEnabled)
@@ -854,6 +854,7 @@ tasks {
register("kaptIdeTest") {
dependsOn(":kotlin-annotation-processing:test")
dependsOn(":kotlin-annotation-processing-base:test")
}
register("gradleIdeTest") {

View File

@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
@@ -55,6 +56,13 @@ class ErasedInlineClassBodyCodegen(
generateUnboxMethod()
generateFunctionsFromAny()
generateSpecializedEqualsStub()
generateJvmInlineAnnotation()
}
private fun generateJvmInlineAnnotation() {
if (descriptor.isInline) {
v.newAnnotation(JVM_INLINE_ANNOTATION_FQ_NAME.topLevelClassAsmType().descriptor, true).visitEnd()
}
}
private fun generateFunctionsFromAny() {

View File

@@ -136,9 +136,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
) {
var nodeAndSmap: SMAPAndMethodNode? = null
try {
nodeAndSmap = createInlineMethodNode(
functionDescriptor, methodOwner, jvmSignature, mapDefaultSignature, typeArguments, typeSystem, state, sourceCompiler
)
nodeAndSmap = createInlineMethodNode(mapDefaultSignature, typeArguments, typeSystem)
endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas), registerLineNumberAfterwards)
} catch (e: CompilationException) {
throw e
@@ -274,6 +272,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
abstract fun extractDefaultLambdas(node: MethodNode): List<DefaultLambda>
abstract fun descriptorIsDeserialized(memberDescriptor: CallableMemberDescriptor): Boolean
fun generateAndInsertFinallyBlocks(
intoNode: MethodNode,
insertPoints: List<MethodInliner.PointForExternalFinallyBlocks>,
@@ -512,38 +512,33 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
}
companion object {
internal fun createInlineMethodNode(
functionDescriptor: FunctionDescriptor,
methodOwner: Type,
jvmSignature: JvmMethodSignature,
callDefault: Boolean,
typeArguments: List<TypeParameterMarker>?,
typeSystem: TypeSystemCommonBackendContext,
state: GenerationState,
sourceCompilerForInline: SourceCompilerForInline
): SMAPAndMethodNode {
val intrinsic = generateInlineIntrinsic(state, functionDescriptor, typeArguments, typeSystem)
if (intrinsic != null) {
return SMAPAndMethodNode(intrinsic, createDefaultFakeSMAP())
}
val asmMethod = if (callDefault)
state.typeMapper.mapDefaultMethod(functionDescriptor, sourceCompilerForInline.contextKind)
else
mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod)
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DescriptorWithContainerSource) {
val node = sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
return node
}
return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature)
internal fun createInlineMethodNode(
callDefault: Boolean,
typeArguments: List<TypeParameterMarker>?,
typeSystem: TypeSystemCommonBackendContext
): SMAPAndMethodNode {
val intrinsic = generateInlineIntrinsic(state, functionDescriptor, typeArguments, typeSystem)
if (intrinsic != null) {
return SMAPAndMethodNode(intrinsic, createDefaultFakeSMAP())
}
val asmMethod = if (callDefault)
state.typeMapper.mapDefaultMethod(functionDescriptor, sourceCompiler.contextKind)
else
mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod)
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
if (!isBuiltInArrayIntrinsic(functionDescriptor) && !descriptorIsDeserialized(directMember)) {
val node = sourceCompiler.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
return node
}
return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature)
}
companion object {
internal fun createSpecialInlineMethodNodeFromBinaries(functionDescriptor: FunctionDescriptor, state: GenerationState): MethodNode {
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
assert(directMember is DescriptorWithContainerSource) {
@@ -577,7 +572,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
doCreateMethodNodeFromCompiled(directMember, state, jvmSignature.asmMethod)
else
null
result ?: throw IllegalStateException("Couldn't obtain compiled function body for $functionDescriptor")
result ?:
throw IllegalStateException("Couldn't obtain compiled function body for $functionDescriptor")
}
return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP)

View File

@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.linkWithLabel
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
@@ -16,7 +15,6 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
class InlineCodegenForDefaultBody(
@@ -41,8 +39,10 @@ class InlineCodegenForDefaultBody(
}
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
val nodeAndSmap = InlineCodegen.createInlineMethodNode(
function, methodOwner, jvmSignature, callDefault, null, codegen.typeSystem, state, sourceCompilerForInline
val nodeAndSmap = PsiInlineCodegen(
codegen, state, function, methodOwner, jvmSignature, TypeParameterMappings(), sourceCompilerForInline
).createInlineMethodNode(
callDefault, null, codegen.typeSystem
)
val childSourceMapper = SourceMapCopier(sourceMapper, nodeAndSmap.classSMAP)

View File

@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getMethodAsmFlags
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinableParameterExpres
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
@@ -208,4 +210,7 @@ class PsiInlineCodegen(
::PsiDefaultLambda
)
}
override fun descriptorIsDeserialized(memberDescriptor: CallableMemberDescriptor): Boolean =
memberDescriptor is DescriptorWithContainerSource
}

View File

@@ -130,7 +130,9 @@ fun <T, R : DefaultLambda> expandMaskConditionsAndUpdateVariableNodes(
node.instructions.insert(position, newInsn)
}
node.localVariables.removeIf { it.start in toDelete && it.end in toDelete }
node.localVariables.removeIf {
(it.start in toDelete && it.end in toDelete) || defaultLambdas.contains(it.index)
}
node.remove(toDelete)

View File

@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.optimization.common
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>>

View File

@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.optimization.common
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>>
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>

View File

@@ -5,4 +5,4 @@
package org.jetbrains.kotlin.codegen.state
typealias JvmMethodExceptionTypes = Array<out String>?
typealias JvmMethodExceptionTypes = Array<out String?>?

View File

@@ -5,4 +5,4 @@
package org.jetbrains.kotlin.codegen.state
typealias JvmMethodExceptionTypes = Array<out String?>?
typealias JvmMethodExceptionTypes = Array<out String>?

View File

@@ -0,0 +1,10 @@
<idea-plugin>
<id>org.jetbrains.kotlin</id>
<version>1.2</version>
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.psi.classFileDecompiler"
interface="com.intellij.psi.compiled.ClassFileDecompilers$Decompiler"
dynamic="true"/>
</extensionPoints>
</idea-plugin>

View File

@@ -1,36 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.cli.common.messages
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
/**
* This class behaviour is the same as [MessageCollector.report] in [AnalyzerWithCompilerReport.reportDiagnostic].
*/
class DefaultDiagnosticReporter(override val messageCollector: MessageCollector) : MessageCollectorBasedReporter
interface MessageCollectorBasedReporter : DiagnosticMessageReporter {
val messageCollector: MessageCollector
override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) = messageCollector.report(
AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity),
render,
MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumn(diagnostic))
)
}

View File

@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.cli.common.messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.impl.jar.CoreJarVirtualFile;
import com.intellij.openapi.vfs.local.CoreLocalVirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
@@ -53,10 +51,6 @@ public class MessageUtil {
@NotNull
public static String virtualFileToPath(@NotNull VirtualFile virtualFile) {
// Convert path to platform-dependent format when virtualFile is local file.
if (virtualFile instanceof CoreLocalVirtualFile || virtualFile instanceof CoreJarVirtualFile) {
return toSystemDependentName(virtualFile.getPath());
}
return virtualFile.getPath();
return toSystemDependentName(virtualFile.getPath());
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.cli.common.messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils;
import static com.intellij.openapi.util.io.FileUtil.toSystemDependentName;
public class MessageUtil {
private MessageUtil() {}
@Nullable
public static CompilerMessageLocation psiElementToMessageLocation(@Nullable PsiElement element) {
if (element == null) return null;
PsiFile file = element.getContainingFile();
return psiFileToMessageLocation(file, "<no path>", DiagnosticUtils.getLineAndColumnInPsiFile(file, element.getTextRange()));
}
@Nullable
public static CompilerMessageLocation psiFileToMessageLocation(
@NotNull PsiFile file,
@Nullable String defaultValue,
@NotNull PsiDiagnosticUtils.LineAndColumn lineAndColumn
) {
VirtualFile virtualFile = file.getVirtualFile();
String path = virtualFile != null ? virtualFileToPath(virtualFile) : defaultValue;
return CompilerMessageLocation.create(path, lineAndColumn.getLine(), lineAndColumn.getColumn(), lineAndColumn.getLineContent());
}
@NotNull
public static String virtualFileToPath(@NotNull VirtualFile virtualFile) {
return toSystemDependentName(virtualFile.getPath());
}
}

View File

@@ -40,7 +40,6 @@ public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnviron
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
registerApplicationExtensionPoint(ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
@@ -52,4 +51,4 @@ public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnviron
protected VirtualFileSystem createJrtFileSystem() {
return new CoreJrtFileSystem();
}
}
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.cli.jvm.compiler;
import com.intellij.DynamicBundle;
import com.intellij.codeInsight.ContainerProvider;
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
import com.intellij.core.JavaCoreApplicationEnvironment;
import com.intellij.lang.MetaLanguage;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.psi.FileContextProvider;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.compiled.ClassFileDecompilers;
import com.intellij.psi.meta.MetaDataContributor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
registerExtensionPoints();
return environment;
}
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
super(parentDisposable, unitTestMode);
}
private static void registerExtensionPoints() {
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
registerApplicationExtensionPoint(ClassFileDecompilers.getInstance().EP_NAME, ClassFileDecompilers.Decompiler.class);
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
}
@Nullable
@Override
protected VirtualFileSystem createJrtFileSystem() {
return new CoreJrtFileSystem();
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.cli.jvm.compiler;
import com.intellij.DynamicBundle;
import com.intellij.codeInsight.ContainerProvider;
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
import com.intellij.core.JavaCoreApplicationEnvironment;
import com.intellij.lang.MetaLanguage;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.psi.FileContextProvider;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.meta.MetaDataContributor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
registerExtensionPoints();
return environment;
}
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
super(parentDisposable, unitTestMode);
}
private static void registerExtensionPoints() {
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
}
@Nullable
@Override
protected VirtualFileSystem createJrtFileSystem() {
return new CoreJrtFileSystem();
}
}

View File

@@ -509,6 +509,7 @@ class KotlinCoreEnvironment private constructor(
val applicationEnvironment = KotlinCoreApplicationEnvironment.create(parentDisposable, unitTestMode)
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml")
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/core.xml")
registerApplicationServicesForCLI(applicationEnvironment)
registerApplicationServices(applicationEnvironment)
@@ -692,4 +693,4 @@ class KotlinCoreEnvironment private constructor(
}
}
}
}
}

View File

@@ -686,4 +686,4 @@ class KotlinCoreEnvironment private constructor(
}
}
}
}
}

View File

@@ -12,4 +12,6 @@ fun setupIdeaStandaloneExecution() {
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
System.getProperties().setProperty("ide.hide.excluded.files", "false")
System.getProperties().setProperty("ast.loading.filter", "false")
System.getProperties().setProperty("idea.ignore.disabled.plugins", "true")
System.getProperties().setProperty("idea.home.path", System.getProperty("java.io.tmpdir"))
}

View File

@@ -12,6 +12,4 @@ fun setupIdeaStandaloneExecution() {
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
System.getProperties().setProperty("ide.hide.excluded.files", "false")
System.getProperties().setProperty("ast.loading.filter", "false")
System.getProperties().setProperty("idea.ignore.disabled.plugins", "true")
System.getProperties().setProperty("idea.home.path", System.getProperty("java.io.tmpdir"))
}

View File

@@ -28,7 +28,7 @@ public final class Test : R|kotlin/Any| {
}
public final inline class Z : R|kotlin/Any| {
@R|kotlin/jvm/JvmInline|() public final inline class Z : R|kotlin/Any| {
public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
public open fun hashCode(): R|kotlin/Int|
@@ -41,3 +41,4 @@ public final inline class Z : R|kotlin/Any| {
public constructor(x: R|kotlin/Int|): R|test/Z|
}

View File

@@ -1,4 +1,4 @@
public final inline class Z : R|kotlin/Any| {
@R|kotlin/jvm/JvmInline|() public final inline class Z : R|kotlin/Any| {
public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
public open fun hashCode(): R|kotlin/Int|
@@ -11,3 +11,4 @@ public final inline class Z : R|kotlin/Any| {
@R|kotlin/PublishedApi|() internal constructor(value: R|kotlin/Int|): R|test/Z|
}

View File

@@ -40,6 +40,6 @@ public final const val s: R|kotlin/Short| = Short(20000)
public final const val s1: R|kotlin/Short| = Short(1)
public get(): R|kotlin/Short|
public final const val str: R|kotlin/String|
public final const val str: R|kotlin/String| = String(:))
public get(): R|kotlin/String|

View File

@@ -0,0 +1,44 @@
interface CommonBackendContext
interface PhaserState<Data> {
var depth: Int
}
interface PhaseConfig {
val needProfiling: Boolean
}
inline fun <R, D> PhaserState<D>.downlevel(nlevels: Int, block: () -> R): R {
depth += nlevels
val result = block()
depth -= nlevels
return result
}
interface CompilerPhase<in Context : CommonBackendContext, Input, Output> {
fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Input>, context: Context, input: Input): Output
}
class NamedCompilerPhase<in Context : CommonBackendContext, Data>(
private val lower: CompilerPhase<Context, Data, Data>
) : CompilerPhase<Context, Data, Data> {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, input: Data): Data {
// Expected: output: Data, Actual: output: Data?
val output = if (phaseConfig.needProfiling) {
runAndProfile(phaseConfig, phaserState, context, input)
} else {
phaserState.downlevel(1) {
lower.invoke(phaseConfig, phaserState, context, input)
}
}
runAfter(phaseConfig, phaserState, context, output)
}
private fun runAfter(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, output: Data) {
}
private fun runAndProfile(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, source: Data): Data {
}
}

View File

@@ -0,0 +1,55 @@
FILE: compilerPhase.kt
public abstract interface CommonBackendContext : R|kotlin/Any| {
}
public abstract interface PhaserState<Data> : R|kotlin/Any| {
public abstract var depth: R|kotlin/Int|
public get(): R|kotlin/Int|
public set(value: R|kotlin/Int|): R|kotlin/Unit|
}
public abstract interface PhaseConfig : R|kotlin/Any| {
public abstract val needProfiling: R|kotlin/Boolean|
public get(): R|kotlin/Boolean|
}
public final inline fun <R, D> R|PhaserState<D>|.downlevel(nlevels: R|kotlin/Int|, block: R|() -> R|): R|R| {
this@R|/downlevel|.R|/PhaserState.depth| = this@R|/downlevel|.R|/PhaserState.depth|.R|kotlin/Int.plus|(R|<local>/nlevels|)
lval result: R|R| = R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|R|>|()
this@R|/downlevel|.R|/PhaserState.depth| = this@R|/downlevel|.R|/PhaserState.depth|.R|kotlin/Int.minus|(R|<local>/nlevels|)
^downlevel R|<local>/result|
}
public abstract interface CompilerPhase<in Context : R|CommonBackendContext|, Input, Output> : R|kotlin/Any| {
public abstract fun invoke(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Input>|, context: R|Context|, input: R|Input|): R|Output|
}
public final class NamedCompilerPhase<in Context : R|CommonBackendContext|, Data> : R|CompilerPhase<Context, Data, Data>| {
public constructor<in Context : R|CommonBackendContext|, Data>(lower: R|CompilerPhase<Context, Data, Data>|): R|NamedCompilerPhase<Context, Data>| {
super<R|kotlin/Any|>()
}
private final val lower: R|CompilerPhase<Context, Data, Data>| = R|<local>/lower|
private get(): R|CompilerPhase<Context, Data, Data>|
public final override fun invoke(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Data>|, context: R|Context|, input: R|Data|): R|Data| {
lval output: R|Data| = when () {
R|<local>/phaseConfig|.R|/PhaseConfig.needProfiling| -> {
this@R|/NamedCompilerPhase|.R|/NamedCompilerPhase.runAndProfile|(R|<local>/phaseConfig|, R|<local>/phaserState|, R|<local>/context|, R|<local>/input|)
}
else -> {
R|<local>/phaserState|.R|/downlevel|<R|Data|, R|Data|>(Int(1), <L> = downlevel@fun <anonymous>(): R|Data| <kind=UNKNOWN> {
^ this@R|/NamedCompilerPhase|.R|/NamedCompilerPhase.lower|.R|SubstitutionOverride</CompilerPhase.invoke: R|Data|>|(R|<local>/phaseConfig|, R|<local>/phaserState|, R|<local>/context|, R|<local>/input|)
}
)
}
}
this@R|/NamedCompilerPhase|.R|/NamedCompilerPhase.runAfter|(R|<local>/phaseConfig|, R|<local>/phaserState|, R|<local>/context|, R|<local>/output|)
}
private final fun runAfter(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Data>|, context: R|Context|, output: R|Data|): R|kotlin/Unit| {
}
private final fun runAndProfile(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Data>|, context: R|Context|, source: R|Data|): R|Data| {
}
}

View File

@@ -0,0 +1,20 @@
// FILE: AliasFor.java
public @interface AliasFor {
@AliasFor(value = "attribute")
String value() default "";
@AliasFor(value = "value")
String attribute() default "";
}
// FILE: Service.java
public @interface Service {
@AliasFor(value = "component")
String value() default "";
}
// FILE: Annotated.kt
@Service(value = "Your")
class My

View File

@@ -0,0 +1,7 @@
FILE: Annotated.kt
@R|Service|(value = String(Your)) public final class My : R|kotlin/Any| {
public constructor(): R|My| {
super<R|kotlin/Any|>()
}
}

View File

@@ -2024,6 +2024,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("compilerPhase.kt")
public void testCompilerPhase() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.kt");
}
@TestMetadata("complexLambdaWithTypeVariableAsExpectedType.kt")
public void testComplexLambdaWithTypeVariableAsExpectedType() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/complexLambdaWithTypeVariableAsExpectedType.kt");
@@ -2079,6 +2084,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/questionableSmartCast.kt");
}
@TestMetadata("recursiveNamedAnnotation.kt")
public void testRecursiveNamedAnnotation() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.kt");
}
@TestMetadata("safeCallInvoke.kt")
public void testSafeCallInvoke() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/safeCallInvoke.kt");

View File

@@ -2024,6 +2024,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("compilerPhase.kt")
public void testCompilerPhase() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.kt");
}
@TestMetadata("complexLambdaWithTypeVariableAsExpectedType.kt")
public void testComplexLambdaWithTypeVariableAsExpectedType() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/complexLambdaWithTypeVariableAsExpectedType.kt");
@@ -2079,6 +2084,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/problems/questionableSmartCast.kt");
}
@TestMetadata("recursiveNamedAnnotation.kt")
public void testRecursiveNamedAnnotation() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.kt");
}
@TestMetadata("safeCallInvoke.kt")
public void testSafeCallInvoke() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/safeCallInvoke.kt");

View File

@@ -10659,6 +10659,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.kt");
}
@TestMetadata("capturedFlexibleIntersectionTypesWithDifferentBounds.kt")
public void testCapturedFlexibleIntersectionTypesWithDifferentBounds() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedFlexibleIntersectionTypesWithDifferentBounds.kt");
}
@TestMetadata("capturedFlexibleIntersectionTypesWithDifferentConstructors.kt")
public void testCapturedFlexibleIntersectionTypesWithDifferentConstructors() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedFlexibleIntersectionTypesWithDifferentConstructors.kt");
}
@TestMetadata("capturedType.kt")
public void testCapturedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedType.kt");
@@ -12907,6 +12917,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/inlineClasses/inlineClassesInsideAnnotations.kt");
}
@TestMetadata("innerClassInsideInlineClass.kt")
public void testInnerClassInsideInlineClass() throws Exception {
runTest("compiler/testData/diagnostics/tests/inlineClasses/innerClassInsideInlineClass.kt");
}
@TestMetadata("lateinitInlineClasses.kt")
public void testLateinitInlineClasses() throws Exception {
runTest("compiler/testData/diagnostics/tests/inlineClasses/lateinitInlineClasses.kt");

View File

@@ -2024,6 +2024,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("compilerPhase.kt")
public void testCompilerPhase() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.kt");
}
@TestMetadata("complexLambdaWithTypeVariableAsExpectedType.kt")
public void testComplexLambdaWithTypeVariableAsExpectedType() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/complexLambdaWithTypeVariableAsExpectedType.kt");
@@ -2079,6 +2084,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/problems/questionableSmartCast.kt");
}
@TestMetadata("recursiveNamedAnnotation.kt")
public void testRecursiveNamedAnnotation() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.kt");
}
@TestMetadata("safeCallInvoke.kt")
public void testSafeCallInvoke() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/problems/safeCallInvoke.kt");

View File

@@ -20,24 +20,21 @@ import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerial
class FirConstDeserializer(
val session: FirSession,
private val partSource: KotlinJvmBinaryClass? = null,
private val facadeSource: KotlinJvmBinaryClass? = null
private val binaryClass: KotlinJvmBinaryClass? = null
) {
companion object {
private val constantCache = mutableMapOf<CallableId, FirExpression>()
}
private val constantCache = mutableMapOf<CallableId, FirExpression>()
fun loadConstant(propertyProto: ProtoBuf.Property, callableId: CallableId, nameResolver: NameResolver): FirExpression? {
if (!Flags.HAS_CONSTANT.get(propertyProto.flags)) return null
constantCache[callableId]?.let { return it }
if (facadeSource == null && partSource == null) {
if (binaryClass == null) {
val value = propertyProto.getExtensionOrNull(BuiltInSerializerProtocol.compileTimeValue) ?: return null
return buildFirConstant(value, null, value.type.name, nameResolver)?.apply { constantCache[callableId] = this }
}
(facadeSource ?: partSource)!!.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
binaryClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor? = null
override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor? {
@@ -60,11 +57,11 @@ class FirConstDeserializer(
"CHAR", "C" -> buildConstExpression(null, FirConstKind.Char, ((protoValue?.intValue ?: sourceValue) as Number).toChar())
"SHORT", "S" -> buildConstExpression(null, FirConstKind.Short, ((protoValue?.intValue ?: sourceValue) as Number).toShort())
"INT", "I" -> buildConstExpression(null, FirConstKind.Int, protoValue?.intValue?.toInt() ?: sourceValue as Int)
"LONG", "J" -> buildConstExpression(null, FirConstKind.Long, (protoValue?.intValue ?: sourceValue) as Long)
"FLOAT", "F" -> buildConstExpression(null, FirConstKind.Float, (protoValue?.floatValue ?: sourceValue) as Float)
"DOUBLE", "D" -> buildConstExpression(null, FirConstKind.Double, (protoValue?.doubleValue ?: sourceValue) as Double)
"LONG", "J" -> buildConstExpression(null, FirConstKind.Long, protoValue?.intValue ?: sourceValue as Long)
"FLOAT", "F" -> buildConstExpression(null, FirConstKind.Float, protoValue?.floatValue ?: sourceValue as Float)
"DOUBLE", "D" -> buildConstExpression(null, FirConstKind.Double, protoValue?.doubleValue ?: sourceValue as Double)
"BOOLEAN", "Z" -> buildConstExpression(null, FirConstKind.Boolean, (protoValue?.intValue?.toInt() ?: sourceValue) != 0)
"STRING", "Ljava/lang/String" -> buildConstExpression(
"STRING", "Ljava/lang/String;" -> buildConstExpression(
null, FirConstKind.String, protoValue?.stringValue?.let { nameResolver.getString(it) } ?: sourceValue as String
)
else -> null

View File

@@ -205,9 +205,6 @@ class FirElementSerializer private constructor(
var hasGetter = false
var hasSetter = false
//val compileTimeConstant = property.compileTimeInitializer
val hasConstant = false // TODO: compileTimeConstant != null && compileTimeConstant !is NullValue
val hasAnnotations = property.nonSourceAnnotations(session).isNotEmpty()
// TODO: hasAnnotations(descriptor) || hasAnnotations(descriptor.backingField) || hasAnnotations(descriptor.delegateField)
@@ -247,6 +244,7 @@ class FirElementSerializer private constructor(
}
}
val hasConstant = property.isConst // TODO: this is only correct with LanguageFeature.NoConstantValueAttributeForNonConstVals
val flags = Flags.getPropertyFlags(
hasAnnotations,
ProtoEnumFlags.visibility(normalizeVisibility(property)),

View File

@@ -14,14 +14,14 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.*
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.ir.util.*
@@ -86,8 +86,17 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
typeContext.hasNothingInNonContravariantPosition(type)
}
private fun FirClassLikeSymbol<*>.toRegularClassSymbol(): FirRegularClassSymbol? = when (this) {
is FirRegularClassSymbol -> this
is FirTypeAliasSymbol -> {
val expandedType = fir.expandedTypeRef.coneType.fullyExpandedType(session) as? ConeClassLikeType
expandedType?.lookupTag?.toSymbol(session) as? FirRegularClassSymbol
}
else -> null
}
private fun ConeClassLikeType.buildPossiblyInnerType(): PossiblyInnerConeType? =
buildPossiblyInnerType(lookupTag.toSymbol(session) as? FirRegularClassSymbol?, 0)
buildPossiblyInnerType(lookupTag.toSymbol(session)?.toRegularClassSymbol(), 0)
private fun ConeClassLikeType.parentClassOrNull(): FirRegularClassSymbol? {
val parentClassId = classId?.outerClassId ?: return null

View File

@@ -404,9 +404,7 @@ class Fir2IrDeclarationStorage(
factory: (IrSimpleFunctionSymbol) -> IrSimpleFunction
): IrSimpleFunction {
if (signature == null) {
val descriptor =
if (containerSource != null) WrappedFunctionDescriptorWithContainerSource()
else WrappedSimpleFunctionDescriptor()
val descriptor = WrappedSimpleFunctionDescriptor()
return symbolTable.declareSimpleFunction(descriptor, factory).apply { descriptor.bind(this) }
}
return symbolTable.declareSimpleFunction(signature, { Fir2IrSimpleFunctionSymbol(signature, containerSource) }, factory)
@@ -687,9 +685,7 @@ class Fir2IrDeclarationStorage(
factory: (IrPropertySymbol) -> IrProperty
): IrProperty {
if (signature == null) {
val descriptor =
if (containerSource != null) WrappedPropertyDescriptorWithContainerSource()
else WrappedPropertyDescriptor()
val descriptor = WrappedPropertyDescriptor()
return symbolTable.declareProperty(0, 0, IrDeclarationOrigin.DEFINED, descriptor, isDelegated = false, factory).apply {
descriptor.bind(this)
}

View File

@@ -7,14 +7,14 @@ package org.jetbrains.kotlin.fir.backend.generators
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.hasMetaAnnotationUseSiteTargets
import org.jetbrains.kotlin.fir.declarations.useSiteTargetsFromMetaAnnotation
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.util.isPropertyField
import org.jetbrains.kotlin.ir.util.isSetter
/**
@@ -36,80 +36,73 @@ class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComp
irContainer.annotations = firContainer.annotations.toIrAnnotations()
}
fun generate(irValueParameter: IrValueParameter, firValueParameter: FirValueParameter, isInConstructor: Boolean) {
irValueParameter.annotations +=
firValueParameter.annotations
.filter {
// TODO: for `null` use-site, refer to targets on the meta annotation
it.useSiteTarget == null || !isInConstructor || it.useSiteTarget == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
}
.toIrAnnotations()
private fun FirAnnotationCall.target(applicable: List<AnnotationUseSiteTarget>): AnnotationUseSiteTarget? =
useSiteTarget ?: applicable.firstOrNull(useSiteTargetsFromMetaAnnotation(session)::contains)
companion object {
// Priority order: constructor parameter (if applicable) -> property -> field. So, for example, if `A`
// can be attached to all three, then in a declaration like
// class C(@A val x: Int) { @A val y = 1 }
// the parameter `x` and the property `y` will have the annotation, while the property `x` and both backing fields will not.
private val propertyTargets = listOf(AnnotationUseSiteTarget.PROPERTY, AnnotationUseSiteTarget.FIELD)
private val constructorPropertyTargets = listOf(AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER) + propertyTargets
private val delegatedPropertyTargets = propertyTargets + listOf(AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD)
}
private fun FirAnnotationCall.targetsField(): Boolean =
// Check if the annotation has a field-targeting meta annotation, e.g., @Target(FIELD)
hasMetaAnnotationUseSiteTargets(session, AnnotationUseSiteTarget.FIELD, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD)
// TODO: third argument should be whether this parameter is a property declaration (though this probably makes no difference)
fun generate(irValueParameter: IrValueParameter, firValueParameter: FirValueParameter, isInConstructor: Boolean) {
if (isInConstructor) {
irValueParameter.annotations += firValueParameter.annotations
.filter { it.target(constructorPropertyTargets) == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER }
.toIrAnnotations()
} else {
irValueParameter.annotations += firValueParameter.annotations.toIrAnnotations()
}
}
fun generate(irProperty: IrProperty, property: FirProperty) {
irProperty.annotations +=
property.annotations
.filter {
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY ||
// NB: annotation with null use-site should be landed on the property (ahead of field),
// unless it has FIELD target on the meta annotation, like @Target(FIELD)
(it.useSiteTarget == null && !it.targetsField())
}
.toIrAnnotations()
val applicableTargets = when {
property.source?.kind == FirFakeSourceElementKind.PropertyFromParameter -> constructorPropertyTargets
irProperty.isDelegated -> delegatedPropertyTargets
else -> propertyTargets
}
irProperty.annotations += property.annotations
.filter { it.target(applicableTargets) == AnnotationUseSiteTarget.PROPERTY }
.toIrAnnotations()
}
fun generate(irField: IrField, property: FirProperty) {
assert(irField.isPropertyField) {
"$irField is not a property field."
val irProperty = irField.correspondingPropertySymbol?.owner ?: throw AssertionError("$irField is not a property field")
val applicableTargets = when {
property.source?.kind == FirFakeSourceElementKind.PropertyFromParameter -> constructorPropertyTargets
irProperty.isDelegated -> delegatedPropertyTargets
else -> propertyTargets
}
irField.annotations +=
property.annotations
.filter {
it.useSiteTarget == AnnotationUseSiteTarget.FIELD ||
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD ||
(it.useSiteTarget == null && it.targetsField())
}
.toIrAnnotations()
irField.annotations += property.annotations.filter {
val target = it.target(applicableTargets)
target == AnnotationUseSiteTarget.FIELD || target == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
}.toIrAnnotations()
}
fun generate(propertyAccessor: IrFunction, property: FirProperty) {
assert(propertyAccessor.isPropertyAccessor) {
"$propertyAccessor is not a property accessor."
}
assert(propertyAccessor.isPropertyAccessor) { "$propertyAccessor is not a property accessor." }
if (propertyAccessor.isSetter) {
propertyAccessor.annotations +=
property.annotations
.filter {
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_SETTER
}
.toIrAnnotations()
propertyAccessor.valueParameters.singleOrNull()?.annotations =
propertyAccessor.valueParameters.singleOrNull()?.annotations?.plus(
property.annotations
.filter {
it.useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER
}
.toIrAnnotations()
)!!
propertyAccessor.annotations += property.annotations
.filter { it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_SETTER }
.toIrAnnotations()
val parameter = propertyAccessor.valueParameters.single()
parameter.annotations += property.annotations
.filter { it.useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER }
.toIrAnnotations()
} else {
propertyAccessor.annotations +=
property.annotations
.filter {
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_GETTER
}
.toIrAnnotations()
propertyAccessor.annotations += property.annotations
.filter { it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_GETTER }
.toIrAnnotations()
}
propertyAccessor.extensionReceiverParameter?.let { receiver ->
receiver.annotations += property.annotations
.filter { it.useSiteTarget == AnnotationUseSiteTarget.RECEIVER }
.toIrAnnotations()
}
propertyAccessor.extensionReceiverParameter?.annotations =
propertyAccessor.extensionReceiverParameter?.annotations?.plus(
property.annotations
.filter {
it.useSiteTarget == AnnotationUseSiteTarget.RECEIVER
}
.toIrAnnotations()
)!!
}
}

View File

@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.references.FirDelegateFieldReference
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.calls.getExpectedTypeForSAMConversion
import org.jetbrains.kotlin.fir.resolve.calls.isFunctional
@@ -445,8 +446,14 @@ class CallAndReferenceGenerator(
is FirDelegatedConstructorCall -> call.calleeReference
is FirAnnotationCall -> call.calleeReference
else -> null
} as? FirResolvedNamedReference
val function = (calleeReference?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
}
val function = if (calleeReference == FirReferencePlaceholderForResolvedAnnotations) {
val coneClassLikeType = (call as FirAnnotationCall).annotationTypeRef.coneTypeSafe<ConeClassLikeType>()
val firClass = (coneClassLikeType?.lookupTag?.toSymbol(session) as? FirRegularClassSymbol)?.fir
firClass?.declarations?.filterIsInstance<FirConstructor>()?.firstOrNull()
} else {
((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
}
val valueParameters = function?.valueParameters
val argumentMapping = call.argumentMapping
if (argumentMapping != null && (annotationMode || argumentMapping.isNotEmpty())) {
@@ -559,11 +566,13 @@ class CallAndReferenceGenerator(
}
}
with(adapterGenerator) {
irArgument = irArgument.applySuspendConversionIfNeeded(argument, parameter)
if (parameter?.returnTypeRef is FirResolvedTypeRef) {
// Java type case (from annotations)
irArgument = irArgument.applySuspendConversionIfNeeded(argument, parameter)
irArgument = irArgument.applySamConversionIfNeeded(argument, parameter)
}
}
return irArgument
.applySamConversionIfNeeded(argument, parameter)
.applyAssigningArrayElementsToVarargInNamedForm(argument, parameter)
return irArgument.applyAssigningArrayElementsToVarargInNamedForm(argument, parameter)
}
private fun IrExpression.applySamConversionIfNeeded(

View File

@@ -232,13 +232,14 @@ class FakeOverrideGenerator(
private fun IrProperty.discardAccessorsAccordingToBaseVisibility(baseSymbols: List<FirPropertySymbol>) {
for (baseSymbol in baseSymbols) {
val unwrapped = baseSymbol.unwrapFakeOverrides()
val unwrappedSymbol = baseSymbol.unwrapFakeOverrides()
val unwrappedProperty = unwrappedSymbol.fir
// Do not create fake overrides for accessors if not allowed to do so, e.g., private lateinit var.
if (unwrapped.fir.getter?.allowsToHaveFakeOverride != true) {
if (!(unwrappedProperty.getter?.allowsToHaveFakeOverride ?: unwrappedProperty.allowsToHaveFakeOverride)) {
getter = null
}
// or private setter
if (unwrapped.fir.setter?.allowsToHaveFakeOverride != true) {
if (!(unwrappedProperty.setter?.allowsToHaveFakeOverride ?: unwrappedProperty.allowsToHaveFakeOverride)) {
setter = null
}
}

View File

@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.fir.symbols
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.*
@@ -42,8 +40,6 @@ abstract class Fir2IrBindableSymbol<out D : DeclarationDescriptor, B : IrSymbolO
is IrClass -> WrappedClassDescriptor().apply { bind(owner) }
is IrConstructor -> WrappedClassConstructorDescriptor().apply { bind(owner) }
is IrSimpleFunction -> when {
containerSource != null ->
WrappedFunctionDescriptorWithContainerSource()
owner.name.isSpecial && owner.name.asString().startsWith(GETTER_PREFIX) ->
WrappedPropertyGetterDescriptor()
owner.name.isSpecial && owner.name.asString().startsWith(SETTER_PREFIX) ->
@@ -54,11 +50,7 @@ abstract class Fir2IrBindableSymbol<out D : DeclarationDescriptor, B : IrSymbolO
is IrVariable -> WrappedVariableDescriptor().apply { bind(owner) }
is IrValueParameter -> WrappedValueParameterDescriptor().apply { bind(owner) }
is IrTypeParameter -> WrappedTypeParameterDescriptor().apply { bind(owner) }
is IrProperty -> if (containerSource != null) {
WrappedPropertyDescriptorWithContainerSource()
} else {
WrappedPropertyDescriptor()
}.apply { bind(owner) }
is IrProperty -> WrappedPropertyDescriptor().apply { bind(owner) }
is IrField -> WrappedFieldDescriptor().apply { bind(owner) }
is IrTypeAlias -> WrappedTypeAliasDescriptor().apply { bind(owner) }
else -> throw IllegalStateException("Unsupported owner in Fir2IrBindableSymbol: $owner")

View File

@@ -148,6 +148,11 @@ public class FirCompileKotlinAgainstKotlinTestGenerated extends AbstractFirCompi
runTest("compiler/testData/compileKotlinAgainstKotlin/expectClassActualTypeAlias.kt");
}
@TestMetadata("importCompanion.kt")
public void testImportCompanion() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/importCompanion.kt");
}
@TestMetadata("inlineClassFromBinaryDependencies.kt")
public void testInlineClassFromBinaryDependencies() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
@@ -243,6 +248,11 @@ public class FirCompileKotlinAgainstKotlinTestGenerated extends AbstractFirCompi
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmStaticInObject.kt");
}
@TestMetadata("jvmStaticInObjectPropertyReference.kt")
public void testJvmStaticInObjectPropertyReference() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmStaticInObjectPropertyReference.kt");
}
@TestMetadata("kotlinPropertyAsAnnotationParameter.kt")
public void testKotlinPropertyAsAnnotationParameter() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/kotlinPropertyAsAnnotationParameter.kt");

View File

@@ -3840,6 +3840,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/classes/exceptionConstructor.kt");
}
@TestMetadata("extensionFunWithDefaultParam.kt")
public void testExtensionFunWithDefaultParam() throws Exception {
runTest("compiler/testData/codegen/box/classes/extensionFunWithDefaultParam.kt");
}
@TestMetadata("extensionOnNamedClassObject.kt")
public void testExtensionOnNamedClassObject() throws Exception {
runTest("compiler/testData/codegen/box/classes/extensionOnNamedClassObject.kt");
@@ -5058,6 +5063,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/collections/javaCollectionWithRemovePrimitiveInt.kt");
}
@TestMetadata("kt40305.kt")
public void testKt40305() throws Exception {
runTest("compiler/testData/codegen/box/collections/kt40305.kt");
}
@TestMetadata("kt41123.kt")
public void testKt41123() throws Exception {
runTest("compiler/testData/codegen/box/collections/kt41123.kt");
@@ -9833,6 +9843,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/defaultArguments/function/covariantOverrideGeneric.kt");
}
@TestMetadata("defaultLambdaInline.kt")
public void testDefaultLambdaInline() throws Exception {
runTest("compiler/testData/codegen/box/defaultArguments/function/defaultLambdaInline.kt");
}
@TestMetadata("extensionFunctionManyArgs.kt")
public void testExtensionFunctionManyArgs() throws Exception {
runTest("compiler/testData/codegen/box/defaultArguments/function/extensionFunctionManyArgs.kt");
@@ -12189,6 +12204,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/funInterface/multimodule.kt");
}
@TestMetadata("noOptimizedCallableReferences.kt")
public void testNoOptimizedCallableReferences() throws Exception {
runTest("compiler/testData/codegen/box/funInterface/noOptimizedCallableReferences.kt");
}
@TestMetadata("nonAbstractMethod.kt")
public void testNonAbstractMethod() throws Exception {
runTest("compiler/testData/codegen/box/funInterface/nonAbstractMethod.kt");
@@ -12562,6 +12582,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/functions/bigArity/javaLambda.kt");
}
@TestMetadata("nestedBigArityFunCalls.kt")
public void testNestedBigArityFunCalls() throws Exception {
runTest("compiler/testData/codegen/box/functions/bigArity/nestedBigArityFunCalls.kt");
}
@TestMetadata("subclass.kt")
public void testSubclass() throws Exception {
runTest("compiler/testData/codegen/box/functions/bigArity/subclass.kt");
@@ -14127,6 +14152,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/inlineClasses/mappingOfBoxedFlexibleInlineClassType.kt");
}
@TestMetadata("multifileClass.kt")
public void testMultifileClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt");
}
@TestMetadata("nestedInlineClass.kt")
public void testNestedInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
}
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -15139,6 +15174,59 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
}
}
@TestMetadata("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Jvm8DefaultInterfaceMethods extends AbstractFirBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
}
public void testAllFilesPresentInJvm8DefaultInterfaceMethods() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@TestMetadata("javaDefaultMethod.kt")
public void testJavaDefaultMethod() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/javaDefaultMethod.kt");
}
@TestMetadata("javaDefaultMethodOverriddenByKotlin.kt")
public void testJavaDefaultMethodOverriddenByKotlin() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/javaDefaultMethodOverriddenByKotlin.kt");
}
@TestMetadata("jvmDefaultAll.kt")
public void testJvmDefaultAll() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultAll.kt");
}
@TestMetadata("jvmDefaultAllPrimaryProperty.kt")
public void testJvmDefaultAllPrimaryProperty() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultAllPrimaryProperty.kt");
}
@TestMetadata("jvmDefaultAllProperty.kt")
public void testJvmDefaultAllProperty() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultAllProperty.kt");
}
@TestMetadata("jvmDefaultEnable.kt")
public void testJvmDefaultEnable() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultEnable.kt");
}
@TestMetadata("jvmDefaultEnablePrimaryProperty.kt")
public void testJvmDefaultEnablePrimaryProperty() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultEnablePrimaryProperty.kt");
}
@TestMetadata("jvmDefaultEnableProperty.kt")
public void testJvmDefaultEnableProperty() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultEnableProperty.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/inlineClasses/propertyDelegation")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -17959,6 +18047,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/jvmStatic/propertyGetterDelegatesToAnother.kt");
}
@TestMetadata("propertyReference.kt")
public void testPropertyReference() throws Exception {
runTest("compiler/testData/codegen/box/jvmStatic/propertyReference.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/box/jvmStatic/simple.kt");
@@ -21443,6 +21536,31 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/properties/kt9603.kt");
}
@TestMetadata("lazyInitialization.kt")
public void testLazyInitialization() throws Exception {
runTest("compiler/testData/codegen/box/properties/lazyInitialization.kt");
}
@TestMetadata("lazyInitializationCyclicImports.kt")
public void testLazyInitializationCyclicImports() throws Exception {
runTest("compiler/testData/codegen/box/properties/lazyInitializationCyclicImports.kt");
}
@TestMetadata("lazyInitializationMultiModule.kt")
public void testLazyInitializationMultiModule() throws Exception {
runTest("compiler/testData/codegen/box/properties/lazyInitializationMultiModule.kt");
}
@TestMetadata("lazyInitializationOrder.kt")
public void testLazyInitializationOrder() throws Exception {
runTest("compiler/testData/codegen/box/properties/lazyInitializationOrder.kt");
}
@TestMetadata("lazyInitializationSplitPerModule.kt")
public void testLazyInitializationSplitPerModule() throws Exception {
runTest("compiler/testData/codegen/box/properties/lazyInitializationSplitPerModule.kt");
}
@TestMetadata("primitiveOverrideDefaultAccessor.kt")
public void testPrimitiveOverrideDefaultAccessor() throws Exception {
runTest("compiler/testData/codegen/box/properties/primitiveOverrideDefaultAccessor.kt");
@@ -32016,6 +32134,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt");
}
@TestMetadata("evaluateConstructorOfUnsignedArrayType.kt")
public void testEvaluateConstructorOfUnsignedArrayType() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedArrayType.kt");
}
@TestMetadata("evaluateConstructorOfUnsignedType.kt")
public void testEvaluateConstructorOfUnsignedType() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedType.kt");
@@ -32195,6 +32318,59 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
public void testWhenByUnsigned() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt");
}
@TestMetadata("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Jvm8Intrinsics extends AbstractFirBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
}
public void testAllFilesPresentInJvm8Intrinsics() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@TestMetadata("unsignedIntCompare_jvm8.kt")
public void testUnsignedIntCompare_jvm8() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedIntCompare_jvm8.kt");
}
@TestMetadata("unsignedIntDivide_jvm8.kt")
public void testUnsignedIntDivide_jvm8() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedIntDivide_jvm8.kt");
}
@TestMetadata("unsignedIntRemainder_jvm8.kt")
public void testUnsignedIntRemainder_jvm8() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedIntRemainder_jvm8.kt");
}
@TestMetadata("unsignedIntToString_jvm8.kt")
public void testUnsignedIntToString_jvm8() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedIntToString_jvm8.kt");
}
@TestMetadata("unsignedLongCompare_jvm8.kt")
public void testUnsignedLongCompare_jvm8() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedLongCompare_jvm8.kt");
}
@TestMetadata("unsignedLongDivide_jvm8.kt")
public void testUnsignedLongDivide_jvm8() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedLongDivide_jvm8.kt");
}
@TestMetadata("unsignedLongRemainder_jvm8.kt")
public void testUnsignedLongRemainder_jvm8() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedLongRemainder_jvm8.kt");
}
@TestMetadata("unsignedLongToString_jvm8.kt")
public void testUnsignedLongToString_jvm8() throws Exception {
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedLongToString_jvm8.kt");
}
}
}
@TestMetadata("compiler/testData/codegen/box/vararg")

View File

@@ -774,6 +774,11 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/callableReference/kt36975.kt");
}
@TestMetadata("kt39612.kt")
public void testKt39612() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/callableReference/kt39612.kt");
}
@TestMetadata("nameIntrinsicWithImplicitThis.kt")
public void testNameIntrinsicWithImplicitThis() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/callableReference/nameIntrinsicWithImplicitThis.kt");

View File

@@ -1812,6 +1812,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/firProblems/InnerClassInAnonymous.kt");
}
@TestMetadata("kt43342.kt")
public void testKt43342() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/kt43342.kt");
}
@TestMetadata("MultiList.kt")
public void testMultiList() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/MultiList.kt");

View File

@@ -50,7 +50,7 @@ class JavaSymbolProvider(
private val searchScope: GlobalSearchScope,
) : FirSymbolProvider(session) {
companion object {
private val VALUE_METHOD_NAME = Name.identifier("value")
internal val VALUE_METHOD_NAME = Name.identifier("value")
}
private val classCache = SymbolProviderCache<ClassId, FirRegularClassSymbol>()
@@ -168,6 +168,7 @@ class JavaSymbolProvider(
javaTypeParameterStack.addStack(parentStack)
}
}
val methodMap = mutableMapOf<JavaMethod, FirJavaMethod>()
val firJavaClass = buildJavaClass {
source = (javaClass as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
session = this@JavaSymbolProvider.session
@@ -219,7 +220,9 @@ class JavaSymbolProvider(
classIsAnnotation,
valueParametersForAnnotationConstructor,
dispatchReceiver
)
).apply {
methodMap[javaMethod] = this
}
}
val javaClassDeclaredConstructors = javaClass.constructors
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
@@ -270,6 +273,10 @@ class JavaSymbolProvider(
}
)
firJavaClass.addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
// NB: this is done here to unbind possible annotation cycle
for ((javaMethod, firJavaMethod) in methodMap) {
firJavaMethod.annotations.addAnnotationsFrom(session, javaMethod, javaTypeParameterStack)
}
return firJavaClass
}
@@ -364,7 +371,6 @@ class JavaSymbolProvider(
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
isStatic = javaMethod.isStatic
typeParameters += javaMethod.typeParameters.convertTypeParameters(javaTypeParameterStack)
addAnnotationsFrom(this@JavaSymbolProvider.session, javaMethod, javaTypeParameterStack)
for ((index, valueParameter) in javaMethod.valueParameters.withIndex()) {
valueParameters += valueParameter.toFirValueParameter(
this@JavaSymbolProvider.session, index, javaTypeParameterStack,

View File

@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
import org.jetbrains.kotlin.fir.resolve.bindSymbolToLookupTag
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredCallableSymbols
import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -31,6 +33,7 @@ import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
@@ -418,16 +421,51 @@ private fun FirRegularClass.createRawArguments(
computeRawProjection(session, typeParameter, position, erasedUpperBound)
}
private fun FirAnnotationCallBuilder.buildArgumentMapping(
session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack,
classId: ClassId?,
annotationArguments: Collection<JavaAnnotationArgument>
): LinkedHashMap<FirExpression, FirValueParameter>? {
if (classId == null) {
annotationTypeRef = buildErrorTypeRef { diagnostic = ConeUnresolvedReferenceError() }
return null
}
val lookupTag = ConeClassLikeLookupTagImpl(classId)
annotationTypeRef = buildResolvedTypeRef {
type = ConeClassLikeTypeImpl(lookupTag, emptyArray(), isNullable = false)
}
if (annotationArguments.any { it.name != null }) {
val mapping = linkedMapOf<FirExpression, FirValueParameter>()
val annotationClassSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId).also {
lookupTag.bindSymbolToLookupTag(session, it)
}
if (annotationClassSymbol != null) {
val annotationConstructor =
(annotationClassSymbol.fir as FirRegularClass).declarations.filterIsInstance<FirConstructor>().first()
for (argument in annotationArguments) {
mapping[argument.toFirExpression(session, javaTypeParameterStack)] =
annotationConstructor.valueParameters.find { it.name == (argument.name ?: JavaSymbolProvider.VALUE_METHOD_NAME) }
?: return null
}
return mapping
}
}
return null
}
internal fun JavaAnnotation.toFirAnnotationCall(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
): FirAnnotationCall {
return buildAnnotationCall {
annotationTypeRef = buildResolvedTypeRef {
type = ConeClassLikeTypeImpl(FirRegularClassSymbol(classId!!).toLookupTag(), emptyArray(), isNullable = false)
}
argumentList = buildArgumentList {
for (argument in this@toFirAnnotationCall.arguments) {
arguments += argument.toFirExpression(session, javaTypeParameterStack)
val mapping = buildArgumentMapping(session, javaTypeParameterStack, classId, arguments)
argumentList = if (mapping != null) {
buildResolvedArgumentList(mapping)
} else {
buildArgumentList {
for (argument in this@toFirAnnotationCall.arguments) {
arguments += argument.toFirExpression(session, javaTypeParameterStack)
}
}
}
calleeReference = FirReferencePlaceholderForResolvedAnnotations
@@ -447,7 +485,7 @@ internal fun FirJavaClass.addAnnotationsFrom(
annotations.addAnnotationsFrom(session, javaAnnotationOwner, javaTypeParameterStack)
}
private fun MutableList<FirAnnotationCall>.addAnnotationsFrom(
internal fun MutableList<FirAnnotationCall>.addAnnotationsFrom(
session: FirSession,
javaAnnotationOwner: JavaAnnotationOwner,
javaTypeParameterStack: JavaTypeParameterStack

View File

@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.load.kotlin.*
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
@@ -126,7 +127,7 @@ class KotlinDeserializedJvmSymbolsProvider(
FirDeserializationContext.createForPackage(
packageFqName, packageProto, nameResolver, session,
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, byteContent),
FirConstDeserializer(session, kotlinJvmBinaryClass, facadeBinaryClass),
FirConstDeserializer(session, facadeBinaryClass ?: kotlinJvmBinaryClass),
source
),
source,
@@ -300,6 +301,12 @@ class KotlinDeserializedJvmSymbolsProvider(
return loadAnnotation(annotationClassId, result)
}
private fun findAndDeserializeClassViaParent(classId: ClassId): FirRegularClassSymbol? {
val outerClassId = classId.outerClassId ?: return null
findAndDeserializeClass(outerClassId) ?: return null
return classCache[classId]
}
private fun findAndDeserializeClass(
classId: ClassId,
parentContext: FirDeserializationContext? = null
@@ -314,7 +321,7 @@ class KotlinDeserializedJvmSymbolsProvider(
} catch (e: ProcessCanceledException) {
return null
}
val kotlinClassWithContent = when (result) {
val (kotlinJvmBinaryClass, byteContent) = when (result) {
is KotlinClassFinder.Result.KotlinClass -> result
is KotlinClassFinder.Result.ClassFileContent -> {
handledByJava.add(classId)
@@ -324,45 +331,39 @@ class KotlinDeserializedJvmSymbolsProvider(
null
}
}
null -> null
null -> return findAndDeserializeClassViaParent(classId)
}
if (kotlinClassWithContent == null) {
val outerClassId = classId.outerClassId ?: return null
findAndDeserializeClass(outerClassId) ?: return null
} else {
val (kotlinJvmBinaryClass, byteContent) = kotlinClassWithContent
if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null
val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return null
if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null
val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return null
val symbol = FirRegularClassSymbol(classId)
deserializeClassToSymbol(
classId, classProto, symbol, nameResolver, session,
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, byteContent),
kotlinScopeProvider,
parentContext, KotlinJvmBinarySourceElement(kotlinJvmBinaryClass),
this::findAndDeserializeClass
)
classCache[classId] = symbol
val annotations = mutableListOf<FirAnnotationCall>()
kotlinJvmBinaryClass.loadClassAnnotations(
object : KotlinJvmBinaryClass.AnnotationVisitor {
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
return loadAnnotationIfNotSpecial(classId, annotations)
}
override fun visitEnd() {
}
},
byteContent,
)
(symbol.fir.annotations as MutableList<FirAnnotationCall>) += annotations
if (parentContext == null && Flags.CLASS_KIND.get(classProto.flags) == ProtoBuf.Class.Kind.COMPANION_OBJECT) {
return findAndDeserializeClassViaParent(classId)
}
return classCache[classId]
val symbol = FirRegularClassSymbol(classId)
deserializeClassToSymbol(
classId, classProto, symbol, nameResolver, session,
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, byteContent),
kotlinScopeProvider,
parentContext, KotlinJvmBinarySourceElement(kotlinJvmBinaryClass),
this::findAndDeserializeClass
)
classCache[classId] = symbol
val annotations = mutableListOf<FirAnnotationCall>()
kotlinJvmBinaryClass.loadClassAnnotations(
object : KotlinJvmBinaryClass.AnnotationVisitor {
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
return loadAnnotationIfNotSpecial(classId, annotations)
}
override fun visitEnd() {
}
},
byteContent,
)
(symbol.fir.annotations as MutableList<FirAnnotationCall>) += annotations
return symbol
}
private fun loadFunctionsByName(part: PackagePartsCacheData, name: Name): List<FirCallableSymbol<*>> {

View File

@@ -54,36 +54,36 @@ inline val FirProperty.hasJvmFieldAnnotation: Boolean
val FirAnnotationCall.isJvmFieldAnnotation: Boolean
get() = toAnnotationClassId() == JVM_FIELD_CLASS_ID
private fun FirAnnotationCall.useSiteTargetsFromMetaAnnotation(session: FirSession): List<AnnotationUseSiteTarget> {
val metaAnnotationAboutTarget =
toAnnotationClass(session)?.annotations?.find { it.toAnnotationClassId() == TARGET_CLASS_ID }
?: return emptyList()
return metaAnnotationAboutTarget.argumentList.arguments.toAnnotationUseSiteTargets()
}
fun FirAnnotationCall.useSiteTargetsFromMetaAnnotation(session: FirSession): Set<AnnotationUseSiteTarget> =
toAnnotationClass(session)?.annotations?.find { it.toAnnotationClassId() == TARGET_CLASS_ID }?.argumentList?.arguments
?.toAnnotationUseSiteTargets() ?: DEFAULT_USE_SITE_TARGETS
private fun List<FirExpression>.toAnnotationUseSiteTargets(): List<AnnotationUseSiteTarget> =
flatMap { arg ->
val unwrappedArg = if (arg is FirNamedArgumentExpression) arg.expression else arg
if (unwrappedArg is FirArrayOfCall) {
unwrappedArg.argumentList.arguments.toAnnotationUseSiteTargets()
} else {
unwrappedArg.toAnnotationUseSiteTarget()?.let { listOf(it) } ?: emptyList()
private fun List<FirExpression>.toAnnotationUseSiteTargets(): Set<AnnotationUseSiteTarget> =
flatMapTo(mutableSetOf()) { arg ->
when (val unwrappedArg = if (arg is FirNamedArgumentExpression) arg.expression else arg) {
is FirArrayOfCall -> unwrappedArg.argumentList.arguments.toAnnotationUseSiteTargets()
is FirVarargArgumentsExpression -> unwrappedArg.arguments.toAnnotationUseSiteTargets()
else -> USE_SITE_TARGET_NAME_MAP[unwrappedArg.callableNameOfMetaAnnotationArgument?.identifier] ?: setOf()
}
}
private val USE_SITE_TARGET_NAME_MAP =
AnnotationUseSiteTarget.values().map { it.name to it }.toMap()
// See [org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.USE_SITE_MAPPING] (it's in reverse)
private val USE_SITE_TARGET_NAME_MAP = mapOf(
"FIELD" to setOf(AnnotationUseSiteTarget.FIELD, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD),
"FILE" to setOf(AnnotationUseSiteTarget.FILE),
"PROPERTY" to setOf(AnnotationUseSiteTarget.PROPERTY),
"PROPERTY_GETTER" to setOf(AnnotationUseSiteTarget.PROPERTY_GETTER),
"PROPERTY_SETTER" to setOf(AnnotationUseSiteTarget.PROPERTY_SETTER),
"VALUE_PARAMETER" to setOf(
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER,
AnnotationUseSiteTarget.RECEIVER,
AnnotationUseSiteTarget.SETTER_PARAMETER,
),
)
private fun FirExpression.toAnnotationUseSiteTarget(): AnnotationUseSiteTarget? =
// TODO: depending on the context, "PARAMETER" can be mapped to either CONSTRUCTOR_PARAMETER or SETTER_PARAMETER ?
callableNameOfMetaAnnotationArgument?.identifier?.let {
USE_SITE_TARGET_NAME_MAP[it]
}
fun FirAnnotationCall.hasMetaAnnotationUseSiteTargets(session: FirSession, vararg useSiteTargets: AnnotationUseSiteTarget): Boolean {
val meta = useSiteTargetsFromMetaAnnotation(session)
return useSiteTargets.any { meta.contains(it) }
}
// See [org.jetbrains.kotlin.descriptors.annotations.KotlinTarget] (the second argument of each entry)
private val DEFAULT_USE_SITE_TARGETS: Set<AnnotationUseSiteTarget> =
USE_SITE_TARGET_NAME_MAP.values.fold(setOf<AnnotationUseSiteTarget>()) { a, b -> a + b } - setOf(AnnotationUseSiteTarget.FILE)
fun FirAnnotatedDeclaration.hasAnnotation(classId: ClassId): Boolean {
return annotations.any { it.toAnnotationClassId() == classId }

View File

@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.types.AbstractTypeApproximator
@NoMutableState
class InferenceComponents(val session: FirSession) : FirSessionComponent {
val ctx: ConeTypeCheckerContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = false, session)
val ctx: ConeTypeCheckerContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session)
val approximator: AbstractTypeApproximator = object : AbstractTypeApproximator(ctx) {}
val trivialConstraintTypeInferenceOracle = TrivialConstraintTypeInferenceOracle.create(ctx)

View File

@@ -584,7 +584,7 @@ class ConeTypeCheckerContext(
errorTypesEqualToAnything: Boolean,
stubTypesEqualToAnything: Boolean
): AbstractTypeCheckerContext =
if (this.isErrorTypeEqualsToAnything == errorTypesEqualToAnything)
if (this.isErrorTypeEqualsToAnything == errorTypesEqualToAnything && this.isStubTypeEqualsToAnything == stubTypesEqualToAnything)
this
else
ConeTypeCheckerContext(errorTypesEqualToAnything, stubTypesEqualToAnything, session)

View File

@@ -34,7 +34,7 @@ fun ConeClassLikeType.isByte(): Boolean = lookupTag.classId == StandardClassIds.
fun ConeClassLikeType.isBoolean(): Boolean = lookupTag.classId == StandardClassIds.Boolean
fun ConeClassLikeType.isChar(): Boolean = lookupTag.classId == StandardClassIds.Char
fun ConeClassLikeType.isPrimitiveType(): Boolean = isPrimitiveNumberOrUnsignedNumberType() || isBoolean() || isByte() || isShort()
fun ConeClassLikeType.isPrimitiveType(): Boolean = isPrimitiveNumberOrUnsignedNumberType() || isBoolean() || isByte() || isShort() || isChar()
fun ConeClassLikeType.isPrimitiveNumberType(): Boolean = lookupTag.classId in PRIMITIVE_NUMBER_CLASS_IDS
fun ConeClassLikeType.isPrimitiveUnsignedNumberType(): Boolean = lookupTag.classId in PRIMITIVE_UNSIGNED_NUMBER_CLASS_IDS
fun ConeClassLikeType.isPrimitiveNumberOrUnsignedNumberType(): Boolean = isPrimitiveNumberType() || isPrimitiveUnsignedNumberType()

View File

@@ -64,6 +64,9 @@ inline val FirPropertyAccessor.modality get() = status.modality
inline val FirPropertyAccessor.visibility get() = status.visibility
inline val FirPropertyAccessor.isInline get() = status.isInline
inline val FirPropertyAccessor.isExternal get() = status.isExternal
inline val FirProperty.allowsToHaveFakeOverride: Boolean
get() = !Visibilities.isPrivate(visibility) && visibility != Visibilities.InvisibleFake
inline val FirPropertyAccessor.allowsToHaveFakeOverride: Boolean
get() = !Visibilities.isPrivate(visibility) && visibility != Visibilities.InvisibleFake

View File

@@ -44,6 +44,7 @@ inline val FirCall.argumentMapping: LinkedHashMap<FirExpression, FirValueParamet
get() = (argumentList as? FirResolvedArgumentList)?.mapping
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
if (this is FirWrappedArgumentExpression) return expression.toResolvedCallableReference()
return (this as? FirResolvable)?.calleeReference as? FirResolvedNamedReference
}

View File

@@ -362,6 +362,7 @@ public interface Errors {
DiagnosticFactory0<KtTypeReference> INLINE_CLASS_CANNOT_BE_RECURSIVE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, String> RESERVED_MEMBER_INSIDE_INLINE_CLASS = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> INNER_CLASS_INSIDE_INLINE_CLASS = DiagnosticFactory0.create(ERROR);
// Result class

View File

@@ -704,7 +704,7 @@ public class DefaultErrorMessages {
MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_ENUM, "Constructor must be private in enum class");
MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_SEALED, "Constructor must be private in sealed class");
MAP.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes are only allowed on top level");
MAP.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes cannot be local or inner");
MAP.put(INLINE_CLASS_NOT_FINAL, "Inline classes can be only final");
MAP.put(ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS, "Primary constructor is required for inline class");
MAP.put(INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, "Inline class must have exactly one primary constructor parameter");
@@ -717,6 +717,7 @@ public class DefaultErrorMessages {
MAP.put(INLINE_CLASS_CANNOT_BE_RECURSIVE, "Inline class cannot be recursive");
MAP.put(RESERVED_MEMBER_INSIDE_INLINE_CLASS, "Member with the name ''{0}'' is reserved for future releases", STRING);
MAP.put(SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS, "Secondary constructors with bodies are reserved for for future releases");
MAP.put(INNER_CLASS_INSIDE_INLINE_CLASS, "Inline class cannot have inner classes");
MAP.put(RESULT_CLASS_IN_RETURN_TYPE, "'kotlin.Result' cannot be used as a return type");
MAP.put(RESULT_CLASS_WITH_NULLABLE_OPERATOR, "Expression of type 'kotlin.Result' cannot be used as a left operand of ''{0}''", STRING);

View File

@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -93,12 +94,16 @@ class CollectionLiteralResolver(
}
private fun getArrayFunctionCallName(expectedType: KotlinType): Name {
if (NO_EXPECTED_TYPE === expectedType || !KotlinBuiltIns.isPrimitiveArray(expectedType)) {
if (NO_EXPECTED_TYPE === expectedType ||
!(KotlinBuiltIns.isPrimitiveArray(expectedType) || KotlinBuiltIns.isUnsignedArrayType(expectedType))
) {
return ArrayFqNames.ARRAY_OF_FUNCTION
}
val descriptor = expectedType.constructor.declarationDescriptor ?: return ArrayFqNames.ARRAY_OF_FUNCTION
return ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayType(descriptor)] ?: ArrayFqNames.ARRAY_OF_FUNCTION
return ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayType(descriptor)]
?: UnsignedTypes.unsignedArrayTypeToArrayCall[UnsignedTypes.toUnsignedArrayType(descriptor)]
?: ArrayFqNames.ARRAY_OF_FUNCTION
}
}

View File

@@ -59,7 +59,11 @@ public class CompileTimeConstantUtils {
"kotlin.shortArrayOf",
"kotlin.byteArrayOf",
"kotlin.booleanArrayOf",
"kotlin.emptyArray"
"kotlin.emptyArray",
"kotlin.ubyteArrayOf",
"kotlin.ushortArrayOf",
"kotlin.uintArrayOf",
"kotlin.ulongArrayOf"
);
public static void checkConstructorParametersType(@NotNull List<KtParameter> parameters, @NotNull BindingTrace trace) {
@@ -91,7 +95,8 @@ public class CompileTimeConstantUtils {
KotlinBuiltIns.isPrimitiveArray(parameterType) ||
KotlinBuiltIns.isPrimitiveType(parameterType) ||
KotlinBuiltIns.isString(parameterType) ||
UnsignedTypes.INSTANCE.isUnsignedType(parameterType)) {
UnsignedTypes.isUnsignedType(parameterType) ||
UnsignedTypes.isUnsignedArrayType(parameterType)) {
return true;
}

View File

@@ -28,6 +28,7 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
SuspendLimitationsChecker,
InlineClassDeclarationChecker,
PropertiesWithBackingFieldsInsideInlineClass(),
InnerClassInsideInlineClass(),
AnnotationClassTargetAndRetentionChecker(),
ReservedMembersAndConstructsForInlineClass(),
ResultClassInReturnTypeChecker(),

View File

@@ -29,7 +29,7 @@ object InlineClassDeclarationChecker : DeclarationChecker {
require(inlineOrValueKeyword != null) { "Declaration of inline class must have 'inline' keyword" }
val trace = context.trace
if (!DescriptorUtils.isTopLevelDeclaration(descriptor)) {
if (descriptor.isInner || DescriptorUtils.isLocal(descriptor)) {
trace.report(Errors.INLINE_CLASS_NOT_TOP_LEVEL.on(inlineOrValueKeyword))
return
}
@@ -124,6 +124,18 @@ class PropertiesWithBackingFieldsInsideInlineClass : DeclarationChecker {
}
}
class InnerClassInsideInlineClass : DeclarationChecker {
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
if (declaration !is KtClass) return
if (descriptor !is ClassDescriptor) return
if (!descriptor.isInner) return
if (!descriptor.containingDeclaration.isInlineClass()) return
context.trace.report(Errors.INNER_CLASS_INSIDE_INLINE_CLASS.on(declaration.modifierList!!.getModifier(KtTokens.INNER_KEYWORD)!!))
}
}
class ReservedMembersAndConstructsForInlineClass : DeclarationChecker {
companion object {

View File

@@ -397,7 +397,7 @@ fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() {
@Suppress("UNCHECKED_CAST")
fun isElseBranch(branch: IrBranch) = branch is IrElseBranch || ((branch.condition as? IrConst<Boolean>)?.value == true)
fun IrSimpleFunction.isMethodOfAny() =
fun IrFunction.isMethodOfAny() =
((valueParameters.size == 0 && name.asString().let { it == "hashCode" || it == "toString" }) ||
(valueParameters.size == 1 && name.asString() == "equals" && valueParameters[0].type.isNullableAny()))
@@ -497,9 +497,7 @@ fun IrFactory.createStaticFunctionWithReceivers(
copyMetadata: Boolean = true,
typeParametersFromContext: List<IrTypeParameter> = listOf()
): IrSimpleFunction {
val descriptor = (oldFunction.descriptor as? DescriptorWithContainerSource)?.let {
WrappedFunctionDescriptorWithContainerSource()
} ?: WrappedSimpleFunctionDescriptor()
val descriptor = WrappedSimpleFunctionDescriptor()
return createFunction(
oldFunction.startOffset, oldFunction.endOffset,
origin,

View File

@@ -55,14 +55,19 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
}
override fun visitCall(expression: IrCall): IrExpression {
val callableReference = expression.dispatchReceiver as? IrCallableReference<*> ?: return expression
val callableReference = expression.dispatchReceiver as? IrCallableReference<*>
?: return super.visitCall(expression)
//TODO rewrite checking
val directMember = expression.symbol.owner.let {
(it as? IrSimpleFunction)?.correspondingPropertySymbol?.owner ?: it
}
val irClass = directMember.parent as? IrClass ?: return expression
if (!irClass.isSubclassOf(lower.context.irBuiltIns.kCallableClass.owner)) return expression
val irClass = directMember.parent as? IrClass
?: return super.visitCall(expression)
if (!irClass.isSubclassOf(lower.context.irBuiltIns.kCallableClass.owner)) {
return super.visitCall(expression)
}
val name = when (directMember) {
is IrSimpleFunction -> directMember.name
is IrProperty -> directMember.name

View File

@@ -11,8 +11,6 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunction
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyProperty
import org.jetbrains.kotlin.ir.descriptors.*
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.IrType
@@ -77,9 +75,7 @@ fun IrClass.addField(fieldName: String, fieldType: IrType, fieldVisibility: Desc
@PublishedApi
internal fun IrFactory.buildProperty(builder: IrPropertyBuilder): IrProperty = with(builder) {
val wrappedDescriptor = if (originalDeclaration is IrLazyProperty || containerSource != null)
WrappedPropertyDescriptorWithContainerSource()
else WrappedPropertyDescriptor()
val wrappedDescriptor = WrappedPropertyDescriptor()
createProperty(
startOffset, endOffset, origin,
@@ -117,9 +113,7 @@ inline fun IrProperty.addGetter(builder: IrFunctionBuilder.() -> Unit = {}): IrS
@PublishedApi
internal fun IrFactory.buildFunction(builder: IrFunctionBuilder): IrSimpleFunction = with(builder) {
val wrappedDescriptor = if (originalDeclaration is IrLazyFunction || containerSource != null)
WrappedFunctionDescriptorWithContainerSource()
else WrappedSimpleFunctionDescriptor()
val wrappedDescriptor = WrappedSimpleFunctionDescriptor()
createFunction(
startOffset, endOffset, origin,
IrSimpleFunctionSymbolImpl(wrappedDescriptor),

View File

@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
import org.jetbrains.kotlin.ir.backend.js.utils.getJsName
import org.jetbrains.kotlin.ir.backend.js.utils.hasStableJsName
import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
@@ -118,7 +118,7 @@ abstract class BridgesConstruction(val context: JsCommonBackendContext) : Declar
): IrFunction {
val origin =
if (bridge.isEffectivelyExternal() || bridge.getJsName() != null)
if (bridge.hasStableJsName())
JsLoweredDeclarationOrigin.BRIDGE_TO_EXTERNAL_FUNCTION
else
IrDeclarationOrigin.BRIDGE

View File

@@ -37,11 +37,12 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) :
): IrExpression {
val paramCount = oldIrFunction.valueParameters.size
val invokeFunctionN = resolveInvoke(paramCount)
// NOTE: currently we do not have a syntax to perform super extension call
// but in case we have such functionality in the future the logic bellow should be fixed
return irCall(invokeFunctionN, IrStatementOrigin.INVOKE).apply {
dispatchReceiver = irImplicitCast(irGet(handlerDeclaration), invokeFunctionN.dispatchReceiverParameter!!.type)
assert(newIrFunction.extensionReceiverParameter == null)
// NOTE: currently we do not have a syntax to perform super extension call
// that's why we've used to just fail with an exception in case we have extension function in for JS IR compilation
// TODO: that was overkill, however, we still need to revisit this issue later on
params.forEachIndexed { i, variable -> putValueArgument(i, irGet(variable)) }
}
}

View File

@@ -47,9 +47,11 @@ class PropertyLazyInitLowering(
return
}
if (container !is IrSimpleFunction && container !is IrField && container !is IrProperty)
if (container !is IrField && container !is IrSimpleFunction && container !is IrProperty)
return
if (container.origin !in compatibleOrigins) return
val file = container.parent as? IrFile
?: return
@@ -224,6 +226,8 @@ class RemoveInitializersForLazyProperties(
if (declaration !is IrField) return null
if (!declaration.isCompatibleDeclaration()) return null
val file = declaration.parent as? IrFile ?: return null
if (fileToInitializerPureness[file] == true) return null
@@ -257,6 +261,7 @@ class RemoveInitializersForLazyProperties(
private fun calculateFieldToExpression(declarations: Collection<IrDeclaration>): Map<IrField, IrExpression> =
declarations
.asSequence()
.filter { it.isCompatibleDeclaration() }
.map { it.correspondingProperty }
.filterNotNull()
.filter { it.isForLazyInit() }
@@ -288,4 +293,14 @@ private val IrDeclaration.correspondingProperty: IrProperty?
private fun IrDeclaration.propertyWithPersistentSafe(transform: IrDeclaration.() -> IrProperty?): IrProperty? =
if (((this as? PersistentIrElementBase<*>)?.createdOn ?: 0) <= stageController.currentStage) {
transform()
} else null
} else null
private fun IrDeclaration.isCompatibleDeclaration() =
origin in compatibleOrigins
private val compatibleOrigins = listOf(
IrDeclarationOrigin.DEFINED,
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
)

View File

@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.backend.common.ir.isElseBranch
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName
import org.jetbrains.kotlin.ir.backend.js.utils.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
@@ -156,14 +153,33 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
// Argument value constructs unboxed inline class instance
arguments.single()
} else {
val ref = when {
klass.isEffectivelyExternal() ->
context.getRefForExternalClass(klass)
else ->
context.getNameForClass(klass).makeRef()
when {
klass.isEffectivelyExternal() -> {
val refForExternalClass = context.getRefForExternalClass(klass)
val varargParameterIndex = expression.symbol.owner.varargParameterIndex()
if (varargParameterIndex == -1) {
JsNew(refForExternalClass, arguments)
} else {
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
JsNullLiteral(),
arguments,
varargParameterIndex
)
JsNew(
JsInvocation(
JsNameRef("apply", JsNameRef("bind", JsNameRef("Function"))),
refForExternalClass,
argumentsAsSingleArray
),
emptyList()
)
}
}
else -> {
val ref = context.getNameForClass(klass).makeRef()
JsNew(ref, arguments)
}
}
JsNew(ref, arguments)
}
}

View File

@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.*
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -120,7 +121,7 @@ fun translateCall(
return JsInvocation(callRef, jsDispatchReceiver?.let { receiver -> listOf(receiver) + arguments } ?: arguments)
}
val varargParameterIndex = function.valueParameters.indexOfFirst { it.varargElementType != null }
val varargParameterIndex = function.varargParameterIndex()
val isExternalVararg = function.isEffectivelyExternal() && varargParameterIndex != -1
val symbolName = when (jsDispatchReceiver) {
@@ -134,28 +135,12 @@ fun translateCall(
}
return if (isExternalVararg) {
// External vararg arguments should be represented in JS as multiple "plain" arguments (opposed to arrays in Kotlin)
// We are using `Function.prototype.apply` function to pass all arguments as a single array.
// For this purpose are concatenating non-vararg arguments with vararg.
// TODO: Don't use `Function.prototype.apply` when number of arguments is known at compile time (e.g. there are no spread operators)
val arrayConcat = JsNameRef("concat", JsArrayLiteral())
val arraySliceCall = JsNameRef("call", JsNameRef("slice", JsArrayLiteral()))
val argumentsAsSingleArray = JsInvocation(
arrayConcat,
listOfNotNull(jsExtensionReceiver) + arguments.mapIndexed { index, argument ->
when (index) {
// Call `Array.prototype.slice` on vararg arguments in order to convert array-like objects into proper arrays
// TODO: Optimize for proper arrays
varargParameterIndex -> JsInvocation(arraySliceCall, argument)
// TODO: Don't wrap non-array-like arguments with array literal
// TODO: Wrap adjacent non-vararg arguments in a single array literal
else -> JsArrayLiteral(listOf(argument))
}
}
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
jsExtensionReceiver,
arguments,
varargParameterIndex
)
if (jsDispatchReceiver != null) {
@@ -198,13 +183,66 @@ fun translateCall(
}
}
fun argumentsWithVarargAsSingleArray(
additionalReceiver: JsExpression?,
arguments: List<JsExpression>,
varargParameterIndex: Int,
): JsExpression {
// External vararg arguments should be represented in JS as multiple "plain" arguments (opposed to arrays in Kotlin)
// We are using `Function.prototype.apply` function to pass all arguments as a single array.
// For this purpose are concatenating non-vararg arguments with vararg.
var arraysForConcat: MutableList<JsExpression> = mutableListOf<JsExpression>().apply {
additionalReceiver?.let { add(it) }
}
val concatElements: MutableList<JsExpression> = mutableListOf()
arguments
.forEachIndexed { index, argument ->
when (index) {
// Call `Array.prototype.slice` on vararg arguments in order to convert array-like objects into proper arrays
varargParameterIndex -> {
concatElements.add(JsArrayLiteral(arraysForConcat))
arraysForConcat = mutableListOf()
val varargArgument = if (argument is JsArrayLiteral) {
argument
} else {
val arraySliceCall = JsNameRef("call", JsNameRef("slice", JsArrayLiteral()))
JsInvocation(arraySliceCall, argument)
}
concatElements.add(varargArgument)
}
else -> {
arraysForConcat.add(argument)
}
}
}
if (arraysForConcat.isNotEmpty() || concatElements.isEmpty()) {
concatElements.add(JsArrayLiteral(arraysForConcat))
}
return concatElements.singleOrNull()
?: JsInvocation(
JsNameRef("concat", concatElements.first()),
concatElements.drop(1)
)
}
fun IrFunction.varargParameterIndex() = valueParameters.indexOfFirst { it.varargElementType != null }
fun translateCallArguments(
expression: IrMemberAccessExpression<*>,
expression: IrMemberAccessExpression<IrFunctionSymbol>,
context: JsGenerationContext,
transformer: IrElementToJsExpressionTransformer,
): List<JsExpression> {
val size = expression.valueArgumentsCount
val varargParameterIndex = expression.symbol.owner.realOverrideTarget.varargParameterIndex()
val validWithNullArgs = expression.validWithNullArgs()
val arguments = (0 until size)
.mapTo(ArrayList(size)) { index ->
@@ -216,6 +254,16 @@ fun translateCallArguments(
assert(validWithNullArgs)
}
}
.mapIndexed { index, result ->
val isEmptyExternalVararg = validWithNullArgs &&
varargParameterIndex == index &&
result is JsArrayLiteral &&
result.expressions.isEmpty()
if (isEmptyExternalVararg) {
null
} else result
}
.dropLastWhile { it == null }
.map { it ?: JsPrefixOperation(JsUnaryOperator.VOID, JsIntLiteral(1)) }

View File

@@ -109,20 +109,13 @@ fun jsFunctionSignature(declaration: IrFunction): Signature {
require(declaration.dispatchReceiverParameter != null)
val declarationName = declaration.getJsNameOrKotlinName().asString()
val stableName = StableNameSignature(declarationName)
if (declaration.origin == JsLoweredDeclarationOrigin.BRIDGE_TO_EXTERNAL_FUNCTION) {
return stableName
}
if (declaration.isEffectivelyExternal()) {
return stableName
}
if (declaration.getJsName() != null) {
return stableName
}
// Handle names for special functions
if (declaration is IrSimpleFunction && declaration.isMethodOfAny()) {
return stableName
val needsStableName = declaration.origin == JsLoweredDeclarationOrigin.BRIDGE_TO_EXTERNAL_FUNCTION ||
declaration.hasStableJsName() ||
(declaration as? IrSimpleFunction)?.isMethodOfAny() == true // Handle names for special functions
if (needsStableName) {
return StableNameSignature(declarationName)
}
val nameBuilder = StringBuilder()

View File

@@ -15,11 +15,29 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isNullableAny
import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
import org.jetbrains.kotlin.ir.util.isTopLevelDeclaration
import org.jetbrains.kotlin.ir.util.parentClassOrNull
import org.jetbrains.kotlin.name.Name
fun TODO(element: IrElement): Nothing = TODO(element::class.java.simpleName + " is not supported yet here")
fun IrFunction.hasStableJsName(): Boolean {
val namedOrMissingGetter = when (this) {
is IrSimpleFunction -> {
val owner = correspondingPropertySymbol?.owner
if (owner == null) {
true
} else {
owner.getter?.getJsName() != null
}
}
else -> true
}
return (isEffectivelyExternal() || getJsName() != null || parentClassOrNull?.isJsExport() == true) && namedOrMissingGetter
}
fun IrFunction.isEqualsInheritedFromAny() =
name == Name.identifier("equals") &&
dispatchReceiverParameter != null &&

View File

@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.common.ir.createStaticFunctionWithReceivers
import org.jetbrains.kotlin.backend.jvm.codegen.AnnotationCodegen.Companion.annotationClass
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.copyCorrespondingPropertyFrom
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
@@ -156,27 +157,9 @@ class JvmCachedDeclarations(
//
// is supposed to allow using `I2.DefaultImpls.f` as if it was inherited from `I1.DefaultImpls`.
// The classes are not actually related and `I2.DefaultImpls.f` is not a fake override but a bridge.
val defaultImplsOrigin = when {
!forCompatibilityMode && !interfaceFun.isFakeOverride ->
when {
interfaceFun.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ->
interfaceFun.origin
interfaceFun.origin.isSynthetic ->
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS_SYNTHETIC
else ->
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS
}
interfaceFun.resolveFakeOverride()!!.origin.isSynthetic ->
if (forCompatibilityMode)
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
else
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC
else ->
if (forCompatibilityMode)
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY
else
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE
}
val defaultImplsOrigin =
if (!forCompatibilityMode && !interfaceFun.isFakeOverride) interfaceFun.origin
else interfaceFun.resolveFakeOverride()!!.origin
// Interface functions are public or private, with one exception: clone in Cloneable, which is protected.
// However, Cloneable has no DefaultImpls, so this merely replicates the incorrect behavior of the old backend.
@@ -198,11 +181,12 @@ class JvmCachedDeclarations(
typeParametersFromContext = parent.typeParameters
).also {
it.copyCorrespondingPropertyFrom(interfaceFun)
if (it.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY &&
!it.annotations.hasAnnotation(DeprecationResolver.JAVA_DEPRECATED)
) {
if (forCompatibilityMode && !interfaceFun.resolveFakeOverride()!!.origin.isSynthetic) {
context.createJvmIrBuilder(it.symbol).run {
it.annotations += irCall(irSymbols.javaLangDeprecatedConstructorWithDeprecatedFlag)
it.annotations = it.annotations
.filterNot { it.annotationClass.hasEqualFqName(DeprecationResolver.JAVA_DEPRECATED) }
.plus(irCall(irSymbols.javaLangDeprecatedConstructorWithDeprecatedFlag))
}
}
@@ -232,7 +216,7 @@ class JvmCachedDeclarations(
assert(fakeOverride.isFakeOverride)
val irClass = fakeOverride.parentAsClass
context.irFactory.buildFun {
origin = JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE
origin = JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE
name = fakeOverride.name
visibility = fakeOverride.visibility
modality = fakeOverride.modality

View File

@@ -11,13 +11,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
object CLASS_STATIC_INITIALIZER : IrDeclarationOriginImpl("CLASS_STATIC_INITIALIZER")
object DEFAULT_IMPLS : IrDeclarationOriginImpl("DEFAULT_IMPLS")
object DEFAULT_IMPLS_WITH_MOVED_RECEIVERS : IrDeclarationOriginImpl("STATIC_WITH_MOVED_RECEIVERS")
object DEFAULT_IMPLS_WITH_MOVED_RECEIVERS_SYNTHETIC :
IrDeclarationOriginImpl("STATIC_WITH_MOVED_RECEIVERS_SYNTHETIC", isSynthetic = true)
object DEFAULT_IMPLS_BRIDGE : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE")
object DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY")
object DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC", isSynthetic = true)
object DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC", isSynthetic = true)
object SUPER_INTERFACE_METHOD_BRIDGE : IrDeclarationOriginImpl("SUPER_INTERFACE_METHOD_BRIDGE")
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
object LAMBDA_IMPL : IrDeclarationOriginImpl("LAMBDA_IMPL")
object FUNCTION_REFERENCE_IMPL : IrDeclarationOriginImpl("FUNCTION_REFERENCE_IMPL", isSynthetic = true)
@@ -28,10 +22,8 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
object TO_ARRAY : IrDeclarationOriginImpl("TO_ARRAY")
object JVM_STATIC_WRAPPER : IrDeclarationOriginImpl("JVM_STATIC_WRAPPER")
object JVM_OVERLOADS_WRAPPER : IrDeclarationOriginImpl("JVM_OVERLOADS_WRAPPER")
object SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS :
IrDeclarationOriginImpl("SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS", isSynthetic = true)
object SYNTHETIC_METHOD_FOR_TYPEALIAS_ANNOTATIONS :
IrDeclarationOriginImpl("SYNTHETIC_METHOD_FOR_TYPEALIAS_ANNOTATIONS", isSynthetic = true)
object SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS :
IrDeclarationOriginImpl("SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS", isSynthetic = true)
object GENERATED_PROPERTY_REFERENCE : IrDeclarationOriginImpl("GENERATED_PROPERTY_REFERENCE", isSynthetic = true)
object GENERATED_MEMBER_IN_CALLABLE_REFERENCE : IrDeclarationOriginImpl("GENERATED_MEMBER_IN_CALLABLE_REFERENCE", isSynthetic = false)
object ENUM_MAPPINGS_FOR_WHEN : IrDeclarationOriginImpl("ENUM_MAPPINGS_FOR_WHEN", isSynthetic = true)

View File

@@ -8,6 +8,7 @@
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.Symbols
import org.jetbrains.kotlin.backend.common.ir.addChild
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods
import org.jetbrains.kotlin.builtins.StandardNames
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.types.Variance
@@ -73,6 +75,7 @@ class JvmSymbols(
"kotlin.coroutines.jvm.internal" -> kotlinCoroutinesJvmInternalPackage
"kotlin.jvm.internal" -> kotlinJvmInternalPackage
"kotlin.jvm.functions" -> kotlinJvmFunctionsPackage
"kotlin.jvm" -> kotlinJvmPackage
"kotlin.reflect" -> kotlinReflectPackage
"java.lang" -> javaLangPackage
else -> error("Other packages are not supported yet: $fqName")
@@ -392,6 +395,12 @@ class JvmSymbols(
}
}
val jvmInlineAnnotation: IrClassSymbol = createClass(JVM_INLINE_ANNOTATION_FQ_NAME, ClassKind.ANNOTATION_CLASS).apply {
owner.addConstructor {
isPrimary = true
}
}
private data class PropertyReferenceKey(
val mutable: Boolean,
val parameterCount: Int,

View File

@@ -365,7 +365,7 @@ class ClassCodegen private constructor(
when (val metadata = method.metadata) {
is MetadataSource.Property -> {
assert(method.isSyntheticMethodForProperty) {
assert(method.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS) {
"MetadataSource.Property on IrFunction should only be used for synthetic \$annotations methods: ${method.render()}"
}
metadataSerializer.bindMethodMetadata(metadata, Method(node.name, node.desc))
@@ -457,9 +457,8 @@ private val IrClass.flags: Int
private fun IrField.computeFieldFlags(context: JvmBackendContext, languageVersionSettings: LanguageVersionSettings): Int =
origin.flags or visibility.flags or
(if (isDeprecatedCallable ||
correspondingPropertySymbol?.owner?.isDeprecatedCallable == true ||
shouldHaveSpecialDeprecationFlag(context)
(if (isDeprecatedCallable(context) ||
correspondingPropertySymbol?.owner?.isDeprecatedCallable(context) == true
) Opcodes.ACC_DEPRECATED else 0) or
(if (isFinal) Opcodes.ACC_FINAL else 0) or
(if (isStatic) Opcodes.ACC_STATIC else 0) or
@@ -475,10 +474,6 @@ private fun IrField.isPrivateCompanionFieldInInterface(languageVersionSettings:
parentAsClass.isJvmInterface &&
DescriptorVisibilities.isPrivate(parentAsClass.companionObject()!!.visibility)
fun IrField.shouldHaveSpecialDeprecationFlag(context: JvmBackendContext): Boolean {
return annotations.any { it.symbol == context.ir.symbols.javaLangDeprecatedConstructorWithDeprecatedFlag }
}
private val IrDeclarationOrigin.flags: Int
get() = (if (isSynthetic) Opcodes.ACC_SYNTHETIC else 0) or
(if (this == IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) Opcodes.ACC_ENUM else 0)

View File

@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.isStaticInlineClassReplacement
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
import org.jetbrains.kotlin.backend.jvm.lower.isMultifileBridge
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
@@ -146,10 +145,7 @@ internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isInvokeSuspen
origin != JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER &&
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR &&
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR &&
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE &&
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY &&
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC &&
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC &&
origin != JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE &&
origin != IrDeclarationOrigin.BRIDGE &&
origin != IrDeclarationOrigin.BRIDGE_SPECIAL &&
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&

View File

@@ -293,8 +293,9 @@ class ExpressionCodegen(
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
// Although these are accessible from Java, the functions they bridge to already have the assertions.
irFunction.origin == IrDeclarationOrigin.BRIDGE_SPECIAL ||
irFunction.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE ||
irFunction.origin == JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE ||
irFunction.origin == JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER ||
irFunction.origin == IrDeclarationOrigin.IR_BUILTINS_STUB ||
irFunction.parentAsClass.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS ||
irFunction.parentAsClass.origin == JvmLoweredDeclarationOrigin.SUSPEND_LAMBDA ||
irFunction.isMultifileBridge()

View File

@@ -118,7 +118,7 @@ class FunctionCodegen(
private fun shouldGenerateAnnotationsOnValueParameters(): Boolean =
when {
irFunction.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS ->
irFunction.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS ->
false
irFunction is IrConstructor && irFunction.parentAsClass.shouldNotGenerateConstructorParameterAnnotations() ->
// Not generating parameter annotations for default stubs fixes KT-7892, though
@@ -146,7 +146,7 @@ class FunctionCodegen(
private fun IrFunction.calculateMethodFlags(): Int {
if (origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) {
return getVisibilityForDefaultArgumentStub() or Opcodes.ACC_SYNTHETIC or
(if (isDeprecatedFunction) Opcodes.ACC_DEPRECATED else 0) or
(if (isDeprecatedFunction(context)) Opcodes.ACC_DEPRECATED else 0) or
(if (this is IrConstructor) 0 else Opcodes.ACC_STATIC)
}
@@ -173,7 +173,7 @@ class FunctionCodegen(
val isSynchronized = hasAnnotation(SYNCHRONIZED_ANNOTATION_FQ_NAME)
return getVisibilityAccessFlag() or modalityFlag or
(if (isDeprecatedFunction) Opcodes.ACC_DEPRECATED else 0) or
(if (isDeprecatedFunction(context)) Opcodes.ACC_DEPRECATED else 0) or
(if (isStatic) Opcodes.ACC_STATIC else 0) or
(if (isVararg) Opcodes.ACC_VARARGS else 0) or
(if (isExternal) Opcodes.ACC_NATIVE else 0) or

View File

@@ -13,11 +13,11 @@ import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.ValueKind
import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.descriptors.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull
@@ -161,6 +161,9 @@ class IrInlineCodegen(
::IrDefaultLambda
)
}
override fun descriptorIsDeserialized(memberDescriptor: CallableMemberDescriptor): Boolean =
((memberDescriptor as IrBasedDeclarationDescriptor<*>).owner as IrMemberWithContainerSource).parentClassId != null
}
class IrExpressionLambdaImpl(

View File

@@ -53,6 +53,10 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
}
private fun computeClassInternalName(irClass: IrClass): StringBuilder {
context.getLocalClassType(irClass)?.internalName?.let {
return StringBuilder(it)
}
val shortName = SpecialNames.safeIdentifier(irClass.name).identifier
when (val parent = irClass.parent) {
@@ -73,11 +77,6 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
}
}
val localClassType = context.getLocalClassType(irClass)
if (localClassType != null) {
return StringBuilder(localClassType.internalName)
}
error(
"Local class should have its name computed in InventNamesForLocalClasses: ${irClass.fqNameWhenAvailable}\n" +
"Ensure that any lowering that transforms elements with local class info (classes, function references) " +

View File

@@ -187,10 +187,7 @@ class JvmSignatureClashDetector(
IrDeclarationOrigin.BRIDGE_SPECIAL,
IrDeclarationOrigin.IR_BUILTINS_STUB,
JvmLoweredDeclarationOrigin.TO_ARRAY,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE,
)
val PREDEFINED_SIGNATURES = listOf(

View File

@@ -127,10 +127,10 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
originalForDefaultAdapter?.isInvisibleInMultifilePart() == true)
private fun IrSimpleFunction.getInternalFunctionForManglingIfNeeded(): IrSimpleFunction? {
if (origin != JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_CONSTRUCTOR &&
visibility == DescriptorVisibilities.INTERNAL &&
!isPublishedApi() &&
!isSyntheticMethodForProperty
if (visibility == DescriptorVisibilities.INTERNAL &&
origin != JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_CONSTRUCTOR &&
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS &&
!isPublishedApi()
) {
return this
}

View File

@@ -14,16 +14,17 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.FrameMapBase
import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.codegen.SourceInfo
import org.jetbrains.kotlin.codegen.classFileContainsMethod
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.inline.SourceMapper
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
@@ -32,7 +33,6 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -344,19 +344,16 @@ fun IrClass.isOptionalAnnotationClass(): Boolean =
val IrDeclaration.isAnnotatedWithDeprecated: Boolean
get() = annotations.hasAnnotation(FqNames.deprecated)
val IrDeclaration.isDeprecatedCallable: Boolean
get() = isAnnotatedWithDeprecated || origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY
internal fun IrDeclaration.isDeprecatedCallable(context: JvmBackendContext): Boolean =
isAnnotatedWithDeprecated ||
annotations.any { it.symbol == context.ir.symbols.javaLangDeprecatedConstructorWithDeprecatedFlag }
// We can't check for JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS because for interface methods
// moved to DefaultImpls, origin is changed to DEFAULT_IMPLS
// TODO: Fix origin somehow
val IrFunction.isSyntheticMethodForProperty: Boolean
get() = name.asString().endsWith(JvmAbi.ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX)
val IrFunction.isDeprecatedFunction: Boolean
get() = isSyntheticMethodForProperty || isDeprecatedCallable ||
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isDeprecatedCallable == true ||
isAccessorForDeprecatedPropertyImplementedByDelegation
internal fun IrFunction.isDeprecatedFunction(context: JvmBackendContext): Boolean =
origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS ||
isDeprecatedCallable(context) ||
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isDeprecatedCallable(context) == true ||
isAccessorForDeprecatedPropertyImplementedByDelegation ||
isAccessorForDeprecatedJvmStaticProperty(context)
private val IrFunction.isAccessorForDeprecatedPropertyImplementedByDelegation: Boolean
get() =
@@ -364,9 +361,20 @@ private val IrFunction.isAccessorForDeprecatedPropertyImplementedByDelegation: B
this is IrSimpleFunction &&
correspondingPropertySymbol != null &&
overriddenSymbols.any {
it.owner.correspondingPropertySymbol?.owner?.isDeprecatedCallable == true
it.owner.correspondingPropertySymbol?.owner?.isAnnotatedWithDeprecated == true
}
private fun IrFunction.isAccessorForDeprecatedJvmStaticProperty(context: JvmBackendContext): Boolean {
if (origin != JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER) return false
val irExpressionBody = this.body as? IrExpressionBody
?: throw AssertionError("IrExpressionBody expected for JvmStatic wrapper:\n${this.dump()}")
val irCall = irExpressionBody.expression as? IrCall
?: throw AssertionError("IrCall expected inside JvmStatic wrapper:\n${this.dump()}")
val callee = irCall.symbol.owner
val property = callee.correspondingPropertySymbol?.owner ?: return false
return property.isDeprecatedCallable(context)
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
val IrDeclaration.psiElement: PsiElement?
get() = (descriptor as? DeclarationDescriptorWithSource)?.psiElement
@@ -379,7 +387,7 @@ fun IrSimpleType.isRawType(): Boolean =
hasAnnotation(JvmGeneratorExtensions.RAW_TYPE_ANNOTATION_FQ_NAME)
internal fun classFileContainsMethod(function: IrFunction, context: JvmBackendContext, name: String): Boolean? {
val classId = (function.parent as? IrClass)?.classId ?: (function.containerSource as? JvmPackagePartSource)?.classId ?: return null
val classId = function.parentClassId ?: return null
val originalDescriptor = context.methodSignatureMapper.mapSignatureWithGeneric(function).asmMethod.descriptor
val descriptor = if (function.isSuspend)
listOf(*Type.getArgumentTypes(originalDescriptor), Type.getObjectType("kotlin/coroutines/Continuation"))
@@ -388,6 +396,9 @@ internal fun classFileContainsMethod(function: IrFunction, context: JvmBackendCo
return classFileContainsMethod(classId, context.state, Method(name, descriptor))
}
val IrMemberWithContainerSource.parentClassId: ClassId?
get() = (containerSource as? JvmPackagePartSource)?.classId ?: (parent as? IrClass)?.classId
// Translated into IR-based terms from classifierDescriptor?.classId
val IrClass.classId: ClassId?
get() = when (val parent = parent) {

View File

@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.jvm.localDeclarationsPhase
import org.jetbrains.kotlin.codegen.coroutines.*
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
@@ -208,10 +209,8 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower
}
}
private fun Name.toSuspendImplementationName() = when {
isSpecial -> Name.special(asString() + SUSPEND_IMPL_NAME_SUFFIX)
else -> Name.identifier(asString() + SUSPEND_IMPL_NAME_SUFFIX)
}
private fun Name.toSuspendImplementationName(): Name =
Name.guessByFirstCharacter(asString() + SUSPEND_IMPL_NAME_SUFFIX)
private fun createStaticSuspendImpl(irFunction: IrSimpleFunction): IrSimpleFunction {
// Create static suspend impl method.
@@ -220,6 +219,8 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower
irFunction.name.toSuspendImplementationName(),
irFunction,
origin = JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION,
modality = Modality.OPEN,
visibility = JavaDescriptorVisibilities.PACKAGE_VISIBILITY,
isFakeOverride = false,
copyMetadata = false
)
@@ -341,7 +342,7 @@ internal fun IrFunction.suspendFunctionOriginal(): IrFunction =
if (this is IrSimpleFunction && isSuspend &&
!isStaticInlineClassReplacement &&
!isOrOverridesDefaultParameterStub() &&
!isDefaultImplsFunction
parentAsClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS
)
attributeOwnerId as IrFunction
else this
@@ -354,19 +355,6 @@ private fun IrSimpleFunction.isOrOverridesDefaultParameterStub(): Boolean =
{ it.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER }
)
private val defaultImplsOrigins = setOf(
IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS_SYNTHETIC,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
)
private val IrSimpleFunction.isDefaultImplsFunction: Boolean
get() = origin in defaultImplsOrigins
private fun IrFunction.createSuspendFunctionStub(context: JvmBackendContext): IrFunction {
require(this.isSuspend && this is IrSimpleFunction)
return factory.buildFun {
@@ -385,7 +373,7 @@ private fun IrFunction.createSuspendFunctionStub(context: JvmBackendContext): Ir
val substitutionMap = makeTypeParameterSubstitutionMap(this, function)
function.copyReceiverParametersFrom(this, substitutionMap)
if (origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE) {
if (origin != JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE) {
function.overriddenSymbols +=
overriddenSymbols.map { it.owner.suspendFunctionViewOrStub(context).symbol as IrSimpleFunctionSymbol }
}

View File

@@ -188,8 +188,16 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
return false
// We don't produce bridges for abstract functions in interfaces.
if (irFunction.isJvmAbstract(context.state.jvmDefaultMode))
return !irFunction.parentAsClass.isJvmInterface
if (irFunction.isJvmAbstract(context.state.jvmDefaultMode)) {
if (irFunction.parentAsClass.isJvmInterface) {
// If function requires a special bridge, we should record it for generic signatures generation.
if (irFunction.specialBridgeOrNull != null) {
context.functionsWithSpecialBridges.add(irFunction)
}
return false
}
return true
}
// Finally, the JVM backend also ignores concrete fake overrides whose implementation is directly inherited from an interface.
// This is sound, since we do not generate type-specialized versions of fake overrides and if the method

View File

@@ -57,16 +57,21 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) :
at(expression)
irCall(functionNInvokeFun).apply {
dispatchReceiver = irImplicitCast(
expression.dispatchReceiver!!,
expression.dispatchReceiver!!.transformVoid(),
this@FunctionNVarargBridgeLowering.context.ir.symbols.functionN.defaultType
)
putValueArgument(0, irArray(irSymbols.array.typeWith(context.irBuiltIns.anyNType)) {
(0 until expression.valueArgumentsCount).forEach { +expression.getValueArgument(it)!! }
(0 until expression.valueArgumentsCount).forEach {
+expression.getValueArgument(it)!!.transformVoid()
}
})
}
}
}
private fun IrExpression.transformVoid() =
transform(this@FunctionNVarargBridgeLowering, null)
override fun visitClassNew(declaration: IrClass): IrStatement {
val bigArityFunctionSuperTypes = declaration.superTypes.filterIsInstance<IrSimpleType>().filter {
it.isFunctionType && it.arguments.size > BuiltInFunctionArity.BIG_ARITY
@@ -76,26 +81,22 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) :
return super.visitClassNew(declaration)
declaration.transformChildrenVoid(this)
// Note that we allow classes with multiple function supertypes, so long as only one
// of them has more than 22 arguments.
// TODO: Add a proper diagnostic message in the frontend
assert(bigArityFunctionSuperTypes.size == 1) {
"Class has multiple big-arity function super types: ${bigArityFunctionSuperTypes.joinToString { it.render() }}"
}
// Note that we allow classes with multiple function supertypes, so long as only one of them has more than 22 arguments.
// Code below will generate one 'invoke' for each function supertype,
// which will cause conflicting inherited JVM signatures error diagnostics in case of multiple big arity function supertypes.
for (superType in bigArityFunctionSuperTypes) {
declaration.superTypes -= superType
declaration.superTypes += context.ir.symbols.functionN.typeWith(
(superType.arguments.last() as IrTypeProjection).type
)
// Fix super class
val superType = bigArityFunctionSuperTypes.single()
declaration.superTypes -= superType
declaration.superTypes += context.ir.symbols.functionN.typeWith(
(superType.arguments.last() as IrTypeProjection).type
)
// Add vararg invoke bridge
val invokeFunction = declaration.functions.single {
it.name.asString() == "invoke" && it.valueParameters.size == superType.arguments.size - if (it.isSuspend) 0 else 1
// Add vararg invoke bridge
val invokeFunction = declaration.functions.single {
it.name.asString() == "invoke" && it.valueParameters.size == superType.arguments.size - if (it.isSuspend) 0 else 1
}
invokeFunction.overriddenSymbols = emptyList()
declaration.addBridge(invokeFunction, functionNInvokeFun.owner)
}
invokeFunction.overriddenSymbols = emptyList()
declaration.addBridge(invokeFunction, functionNInvokeFun.owner)
return declaration
}
@@ -123,7 +124,7 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) :
irInt(argumentCount)
),
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
putValueArgument(0, irString("Expected ${argumentCount} arguments"))
putValueArgument(0, irString("Expected $argumentCount arguments"))
}
)

View File

@@ -245,7 +245,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
if (!useOptimizedSuperClass) {
// This is the case of a fun interface wrapper over a (maybe adapted) function reference,
// with `-Xno-optimized-callable-referenced` enabled. We can't use constructors of FunctionReferenceImpl,
// with `-Xno-optimized-callable-references` enabled. We can't use constructors of FunctionReferenceImpl,
// so we'd need to basically generate a full class for a reference inheriting from FunctionReference,
// effectively disabling the optimization of fun interface wrappers over references.
// This scenario is probably not very popular because it involves using equals/hashCode on function references
@@ -254,8 +254,11 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
// TODO: generate getFunctionDelegate, equals and hashCode properly in this case
functionReferenceClass.addFunction("equals", backendContext.irBuiltIns.booleanType, Modality.ABSTRACT).apply {
addValueParameter("other", backendContext.irBuiltIns.anyNType)
overriddenSymbols = listOf(functionSuperClass.functions.single { isEqualsFromAny(it.owner) })
}
functionReferenceClass.addFunction("hashCode", backendContext.irBuiltIns.intType, Modality.ABSTRACT).apply {
overriddenSymbols = listOf(functionSuperClass.functions.single { isHashCodeFromAny(it.owner) })
}
functionReferenceClass.addFunction("hashCode", backendContext.irBuiltIns.intType, Modality.ABSTRACT)
return
}
@@ -274,6 +277,13 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
}.generate()
}
private fun isEqualsFromAny(f: IrSimpleFunction): Boolean =
f.name.asString() == "equals" && f.extensionReceiverParameter == null &&
f.valueParameters.singleOrNull()?.type?.isNullableAny() == true
private fun isHashCodeFromAny(f: IrSimpleFunction): Boolean =
f.name.asString() == "hashCode" && f.extensionReceiverParameter == null && f.valueParameters.isEmpty()
private fun createConstructor(): IrConstructor =
functionReferenceClass.addConstructor {
origin = JvmLoweredDeclarationOrigin.GENERATED_MEMBER_IN_CALLABLE_REFERENCE

View File

@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.backend.common.phaser.makeCustomPhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
import org.jetbrains.kotlin.backend.jvm.codegen.isSyntheticMethodForProperty
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
@@ -145,6 +144,9 @@ private fun generateMultifileFacades(
for (member in partClass.declarations) {
if (member !is IrSimpleFunction) continue
// KT-43519 Don't generate delegates for external methods
if (member.isExternal) continue
val correspondingProperty = member.correspondingPropertySymbol?.owner
if (member.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) ||
correspondingProperty?.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) == true
@@ -220,7 +222,8 @@ private fun IrSimpleFunction.createMultifileDelegateIfNeeded(
name == StaticInitializersLowering.clinitName ||
origin == JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR ||
// $annotations methods in the facade are only needed for const properties.
(isSyntheticMethodForProperty && (metadata as? MetadataSource.Property)?.isConst != true)
(origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS &&
(metadata as? MetadataSource.Property)?.isConst != true)
) return null
val function = context.irFactory.buildFun {

View File

@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.builtins.StandardNames
@@ -260,24 +259,18 @@ private class InterfaceObjectCallsLowering(val context: JvmBackendContext) : IrE
* interface implementation should be generated into the class containing the fake override; or null if the given function is not a fake
* override of any interface implementation or such method was already generated into the superclass or is a method from Any.
*/
private fun isDefaultImplsBridge(f: IrSimpleFunction) =
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE ||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY ||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC ||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
internal fun IrSimpleFunction.findInterfaceImplementation(jvmDefaultMode: JvmDefaultMode): IrSimpleFunction? {
if (!isFakeOverride) return null
parent.let { if (it is IrClass && it.isJvmInterface) return null }
val implementation = resolveFakeOverride(toSkip = ::isDefaultImplsBridge) ?: return null
val implementation = resolveFakeOverride() ?: return null
// Only generate interface delegation for functions immediately inherited from an interface.
// (Otherwise, delegation will be present in the parent class)
if (overriddenSymbols.any {
!it.owner.parentAsClass.isInterface &&
it.owner.modality != Modality.ABSTRACT &&
it.owner.resolveFakeOverride(toSkip = ::isDefaultImplsBridge) == implementation
it.owner.resolveFakeOverride() == implementation
}) {
return null
}

View File

@@ -125,7 +125,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran
*/
(DescriptorVisibilities.isPrivate(function.visibility) && !function.isCompiledToJvmDefault(jvmDefaultMode))
|| (function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER && !function.isCompiledToJvmDefault(jvmDefaultMode))
|| function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS -> {
|| function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS -> {
val defaultImpl = createDefaultImpl(function)
defaultImpl.body = function.moveBodyTo(defaultImpl)
removedFunctions[function.symbol] = defaultImpl.symbol
@@ -175,7 +175,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran
private fun handleAnnotationClass(irClass: IrClass) {
// We produce $DefaultImpls for annotation classes only to move $annotations methods (for property annotations) there.
val annotationsMethods =
irClass.functions.filter { it.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS }
irClass.functions.filter { it.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS }
if (annotationsMethods.none()) return
for (function in annotationsMethods) {

View File

@@ -28,10 +28,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.transformStatement
import org.jetbrains.kotlin.ir.types.IrType
@@ -42,6 +39,7 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
val jvmInlineClassPhase = makeIrFilePhase(
@@ -98,11 +96,21 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
buildBoxFunction(declaration)
buildUnboxFunction(declaration)
buildSpecializedEqualsMethod(declaration)
addJvmInlineAnnotation(declaration)
}
return declaration
}
private fun addJvmInlineAnnotation(declaration: IrClass) {
if (declaration.hasAnnotation(JVM_INLINE_ANNOTATION_FQ_NAME)) return
val constructor = context.ir.symbols.jvmInlineAnnotation.constructors.first()
declaration.annotations = declaration.annotations + IrConstructorCallImpl.fromSymbolOwner(
constructor.owner.returnType,
constructor
)
}
private fun transformFunctionFlat(function: IrFunction): List<IrDeclaration>? {
if (function.isPrimaryInlineClassConstructor)
return null

View File

@@ -129,7 +129,7 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
private fun createSyntheticMethodForAnnotations(declaration: IrProperty): IrSimpleFunction =
backendContext.irFactory.buildFun {
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS
name = Name.identifier(computeSyntheticMethodName(declaration))
visibility = declaration.visibility
modality = Modality.OPEN
@@ -152,8 +152,10 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
private fun IrType.erasePropertyAnnotationsExtensionReceiverType(): IrType {
// Use raw type of extension receiver to avoid generic signature,
// which should not be generated for '...$annotations' method.
val classifier = classifierOrFail
return if (this is IrSimpleType && isArray()) {
if (this !is IrSimpleType) {
throw AssertionError("Unexpected property receiver type: $this")
}
val erasedType = if (isArray()) {
when (val arg0 = arguments[0]) {
is IrStarProjection -> {
// 'Array<*>' becomes 'Array<*>'
@@ -171,6 +173,9 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
} else {
classifier.typeWith()
}
return erasedType
.withHasQuestionMark(this.hasQuestionMark)
.addAnnotations(this.annotations)
}
private fun computeSyntheticMethodName(property: IrProperty): String {

View File

@@ -14,8 +14,9 @@ import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
internal val jvmStandardLibraryBuiltInsPhase = makeIrFilePhase(
@@ -60,11 +61,14 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
// Originals are so far only instance methods, and the replacements are
// statics, so we copy dispatch receivers to a value argument if needed.
// If we can't coerce arguments to required types, keep original expression (see below).
private fun IrCall.replaceWithCallTo(replacement: IrSimpleFunctionSymbol): IrCall =
IrCallImpl.fromSymbolOwner(
private fun IrCall.replaceWithCallTo(replacement: IrSimpleFunctionSymbol): IrExpression {
val expectedType = this.type
val intrinsicCallType = replacement.owner.returnType
val intrinsicCall = IrCallImpl.fromSymbolOwner(
startOffset,
endOffset,
type,
intrinsicCallType,
replacement
).also { newCall ->
var valueArgumentOffset = 0
@@ -81,6 +85,15 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
}
}
// Coerce intrinsic call result from JVM 'int' or 'long' to corresponding unsigned type if required.
return if (intrinsicCallType.isInt() || intrinsicCallType.isLong()) {
intrinsicCall.coerceIfPossible(expectedType)
?: throw AssertionError("Can't coerce '${intrinsicCallType.render()}' to '${expectedType.render()}'")
} else {
intrinsicCall
}
}
private fun IrExpression.coerceIfPossible(toType: IrType): IrExpression? {
// TODO maybe UnsafeCoerce could handle types with different, but coercible underlying representations.
// See KT-43286 and related tests for details.

View File

@@ -63,7 +63,7 @@ private class JvmStaticInCompanionLowering(val context: JvmBackendContext) : IrE
.filter {
it.isJvmStaticDeclaration() &&
it.origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER &&
it.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
it.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS
}
.forEach { declaration ->
val jvmStaticFunction = declaration as IrSimpleFunction
@@ -171,4 +171,5 @@ private class MakeCallsStatic(val context: JvmBackendContext) : IrElementTransfo
private fun IrDeclaration.isJvmStaticDeclaration(): Boolean =
hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) ||
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true ||
(this as? IrProperty)?.getter?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true

View File

@@ -156,23 +156,29 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem
val wrapper: IrFunction
)
private fun propertyReferenceKind(mutable: Boolean, i: Int) = PropertyReferenceKind(
context.ir.symbols.getPropertyReferenceClass(mutable, i, false),
context.ir.symbols.getPropertyReferenceClass(mutable, i, true),
context.ir.symbols.reflection.owner.functions.single { it.name.asString() == (if (mutable) "mutableProperty$i" else "property$i") }
)
private fun propertyReferenceKind(expression: IrCallableReference<*>, mutable: Boolean, i: Int): PropertyReferenceKind {
check(i in 0..2) { "Incorrect number of receivers ($i) for property reference: ${expression.render()}" }
return PropertyReferenceKind(
context.ir.symbols.getPropertyReferenceClass(mutable, i, false),
context.ir.symbols.getPropertyReferenceClass(mutable, i, true),
context.ir.symbols.reflection.owner.functions.single {
it.name.asString() == (if (mutable) "mutableProperty$i" else "property$i")
}
)
}
private fun propertyReferenceKindFor(expression: IrMemberAccessExpression<*>): PropertyReferenceKind =
private fun propertyReferenceKindFor(expression: IrCallableReference<*>): PropertyReferenceKind =
expression.getter?.owner?.let {
val boundReceivers = listOfNotNull(expression.dispatchReceiver, expression.extensionReceiver).size
val needReceivers = listOfNotNull(it.dispatchReceiverParameter, it.extensionReceiverParameter).size
// PropertyReference1 will swap the receivers if bound with the extension one, and PropertyReference0
// has no way to bind two receivers at once.
if (boundReceivers == 2 || (expression.extensionReceiver != null && needReceivers == 2))
TODO("property reference with 2 receivers")
propertyReferenceKind(expression.setter != null, needReceivers - boundReceivers)
check(boundReceivers < 2 && (expression.extensionReceiver == null || needReceivers < 2)) {
"Property reference with two receivers is not supported: ${expression.render()}"
}
propertyReferenceKind(expression, expression.setter != null, needReceivers - boundReceivers)
} ?: expression.field?.owner?.let {
propertyReferenceKind(!it.isFinal, if (it.isStatic || expression.dispatchReceiver != null) 0 else 1)
propertyReferenceKind(expression, !it.isFinal, if (it.isStatic || expression.dispatchReceiver != null) 0 else 1)
} ?: throw AssertionError("property has no getter and no field: ${expression.dump()}")
private data class PropertyInstance(val initializer: IrExpression, val index: Int)
@@ -343,14 +349,15 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem
fun IrBuilderWithScope.setCallArguments(call: IrCall, arguments: List<IrValueParameter>) {
var index = 1
call.copyTypeArgumentsFrom(expression)
val hasBoundReceiver = expression.getBoundReceiver() != null
call.dispatchReceiver = call.symbol.owner.dispatchReceiverParameter?.let {
if (expression.dispatchReceiver != null)
if (hasBoundReceiver)
irImplicitCast(irGetField(irGet(arguments[0]), backingField), it.type)
else
irImplicitCast(irGet(arguments[index++]), it.type)
}
call.extensionReceiver = call.symbol.owner.extensionReceiverParameter?.let {
if (expression.extensionReceiver != null)
if (hasBoundReceiver)
irImplicitCast(irGetField(irGet(arguments[0]), backingField), it.type)
else
irImplicitCast(irGet(arguments[index++]), it.type)

View File

@@ -588,7 +588,7 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
if (!withSuper && !declaration.visibility.isPrivate && !declaration.visibility.isProtected) return true
// `toArray` is always accessible cause mapped to public functions
if (symbolOwner is IrSimpleFunction && (symbolOwner.isNonGenericToArray(context) || symbolOwner.isGenericToArray(context))) {
if (symbolOwner is IrSimpleFunction && (symbolOwner.isNonGenericToArray() || symbolOwner.isGenericToArray(context))) {
if (symbolOwner.parentAsClass.isCollectionSubClass) {
return true
}

View File

@@ -11,8 +11,8 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.builders.declarations.addDispatchReceiver
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.builders.declarations.addTypeParameter
@@ -75,7 +75,7 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow
}
}
irClass.findOrCreate(indirectCollectionSubClass, { it.isNonGenericToArray(context) }) {
irClass.findOrCreate(indirectCollectionSubClass, IrSimpleFunction::isNonGenericToArray) {
irClass.addFunction {
name = Name.identifier("toArray")
origin = JvmLoweredDeclarationOrigin.TO_ARRAY
@@ -132,7 +132,12 @@ internal fun IrSimpleFunction.isGenericToArray(context: JvmBackendContext): Bool
returnType.isArrayOrNullableArrayOf(context, typeParameters[0].symbol) &&
valueParameters[0].type.isArrayOrNullableArrayOf(context, typeParameters[0].symbol)
// Match `fun toArray(): Array<Any?>`
internal fun IrSimpleFunction.isNonGenericToArray(context: JvmBackendContext): Boolean =
// Match `fun toArray(): Array<...>`.
// It would be more correct to check that the return type is erased to `Object[]`, however the old backend doesn't do that
// (see `FunctionDescriptor.isNonGenericToArray` and KT-43111).
internal fun IrSimpleFunction.isNonGenericToArray(): Boolean =
name.asString() == "toArray" && typeParameters.isEmpty() && valueParameters.isEmpty() &&
extensionReceiverParameter == null && returnType.isArrayOrNullableArrayOf(context, context.irBuiltIns.anyClass)
extensionReceiverParameter == null && returnType.isArrayOrNullableArray()
private fun IrType.isArrayOrNullableArray(): Boolean =
this is IrSimpleType && (isArray() || isNullableArray())

View File

@@ -45,7 +45,7 @@ class TypeAliasAnnotationMethodsLowering(val context: CommonBackendContext) :
visibility = alias.visibility
returnType = context.irBuiltIns.unitType
modality = Modality.OPEN
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_TYPEALIAS_ANNOTATIONS
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS
}.apply {
body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
annotations += alias.annotations

View File

@@ -12,10 +12,12 @@ import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.classFileContainsMethod
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
import org.jetbrains.kotlin.backend.jvm.ir.isFromJava
import org.jetbrains.kotlin.backend.jvm.ir.isStaticInlineClassReplacement
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi.mangledNameFor
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
@@ -70,6 +72,8 @@ class MemoizedInlineClassReplacements(
when {
it.isRemoveAtSpecialBuiltinStub() ->
null
it.isInlineClassMemberFakeOverriddenFromJvmDefaultInterfaceMethod() ->
null
it.origin == IrDeclarationOrigin.IR_BUILTINS_STUB ->
createMethodReplacement(it)
else ->
@@ -94,6 +98,23 @@ class MemoizedInlineClassReplacements(
valueParameters.size == 1 &&
valueParameters[0].type.isInt()
private fun IrFunction.isInlineClassMemberFakeOverriddenFromJvmDefaultInterfaceMethod(): Boolean {
if (this !is IrSimpleFunction) return false
if (!this.isFakeOverride) return false
val parentClass = parentClassOrNull ?: return false
if (!parentClass.isInline) return false
val overridden = resolveFakeOverride() ?: return false
if (!overridden.parentAsClass.isJvmInterface) return false
if (overridden.modality == Modality.ABSTRACT) return false
// We have a non-abstract interface member.
// It is a JVM default interface method if one of the following conditions are true:
// - it is a Java method,
// - it is a Kotlin function compiled to JVM default interface method.
return overridden.isFromJava() || overridden.isCompiledToJvmDefault(context.state.jvmDefaultMode)
}
/**
* Get the box function for an inline class. Concretely, this is a synthetic
* static function named "box-impl" which takes an unboxed value and returns

View File

@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
interface IrSymbolOwner : IrElement {
val symbol: IrSymbol
@@ -66,3 +67,7 @@ interface IrDeclarationWithName : IrDeclaration {
interface IrOverridableMember : IrDeclarationWithVisibility, IrDeclarationWithName, IrSymbolOwner {
val modality: Modality
}
interface IrMemberWithContainerSource : IrDeclarationWithName {
val containerSource: DeserializedContainerSource?
}

Some files were not shown because too many files have changed in this diff Show More