Compare commits

..

177 Commits

Author SHA1 Message Date
Natalia Ukhorskaya
9070eff6ad KotlinPositionManager: add progress when computing classnames for inline function 2016-02-10 18:30:29 +03:00
Denis Zharkov
9ac2da8c96 Optimize 'setResultingSubstitutor'
Replace Map with plain List, use parameter's index as a key
2016-02-10 16:18:59 +03:00
Denis Zharkov
b9e677fef4 Get rid of redundant Map copy 2016-02-10 16:18:59 +03:00
Denis Zharkov
de3f507744 Add minor memory optimization
Get rid of 'unsubstitutedValueArguments' in resolved call
2016-02-10 16:18:59 +03:00
Mikhail Glukhikh
a08b8f43b2 Control flow graph for safe calls corrected #KT-10913 Fixed
Also #KT-10186 Fixed
Also #KT-5198 Fixed
2016-02-10 12:29:45 +03:00
Natalia Ukhorskaya
5ae394fec0 Optimize reference search for convention functions 2016-02-10 11:36:30 +03:00
Natalia Ukhorskaya
1f6894cdd4 EA-77626 - KNPE: AnonymousFunctionToLambdaIntention.applicabilityRange 2016-02-10 11:36:30 +03:00
Nikolay Krasko
5c6c1173a6 Aggregate configuration messages into one notification (KT-10489)
#KT-10489 Fixed
2016-02-10 01:31:38 +03:00
Nikolay Krasko
e2f1a5c092 Minor: refactoring 2016-02-10 01:31:37 +03:00
Zalim Bashorov
cf173d6963 Improve test multifilePackagePartMethodAdded: add file which should not be affected 2016-02-09 23:27:26 +03:00
Zalim Bashorov
f6e7f8c3c0 Introduce TestingContext to pass data between tests and KotlinBuilder; introduce BuildLogger to log build events (build finished, files marked as dirty) in KotlinBuilder 2016-02-09 23:27:25 +03:00
Zalim Bashorov
4ec3865830 Log final exit code instead of intermediate; change log level for build result to INFO 2016-02-09 23:27:24 +03:00
Ilya Gorbunov
1fca1cc607 Use foreach loop instead of directly taking iterator in sum and average.
Use indexed loop for arrays in reduce and reduceIndexed.
#KT-10579 Fixed
2016-02-09 22:51:39 +03:00
Ilya Gorbunov
6c7cefaae3 Use HALF_EVEN rounding mode by default for BigDecimal division operator.
#KT-10462 Fixed
2016-02-09 22:51:02 +03:00
Dmitry Jemerov
8b5e9d1685 code review; add one more missing description 2016-02-09 19:23:00 +01:00
Dmitry Jemerov
6e1705dd16 port IDEA's InspectionDescriptionTest into Kotlin
#KT-10345 Fixed
2016-02-09 19:23:00 +01:00
Dmitry Jemerov
daf26f4db3 more consistent inspection display names; add missing inspection descriptions
#KT-10908 Fixed
2016-02-09 19:22:59 +01:00
Alexey Sedunov
bb2a5b00b7 Change Signature: Fix reference substitution when default value is a single simple name reference
#KT-10954 Fixed
2016-02-09 19:18:50 +03:00
Alexey Sedunov
792d9c1ae2 Introduce Variable: Skip type in template if no resolvable/non-error types are available in the current context
#KT-10808 Fixed
2016-02-09 19:18:45 +03:00
Zalim Bashorov
eacd50c4dc FIx possible NPEs when try to use TestModuleProperties in IDEA 144.x
#EA-78931 Fixed
2016-02-09 15:55:16 +03:00
Michael Bogdanov
0f90dc1649 Code clean and some refactorings in 'getLambdaIfExistsAndMarkInstructions' 2016-02-09 10:19:16 +03:00
Michael Bogdanov
c75b514551 Get rid of InstructionsAndFrames.kt 2016-02-09 10:19:15 +03:00
Michael Bogdanov
b8ee2ecdac Support extension lambda inlining in complex stack cases (nullable receiver) 2016-02-09 10:19:15 +03:00
Ilya Gorbunov
78b7fb15f3 J2K, expected errors: for each argument of removed overloads 2016-02-09 02:58:09 +03:00
Ilya Gorbunov
b4ebaad8f5 Drop previously deprecated API. 2016-02-09 02:58:07 +03:00
Stanislav Erokhin
434bd0707d Correcting rewrite type info after compete call.
#KT-10934 Fixed
#KT-10896 Fixed
2016-02-08 20:49:31 +03:00
Zalim Bashorov
74b2c8cd31 Minor: fix method name 2016-02-08 19:31:17 +03:00
Ilya Gorbunov
17ebb36128 Test Throwable properties in JS, don't work as expected, commiting as ignored.
#KT-10911
2016-02-08 18:10:46 +03:00
Ilya Gorbunov
5361f6e941 Make Throwable properties message and cause open.
#KT-5587 Fixed
2016-02-08 18:10:46 +03:00
Pavel V. Talanov
f12c653aed KtLightClassForFacade is not valid if any of the files it was built for doesn't have top level callables
#KT-9434 Fixed
2016-02-08 16:45:47 +03:00
Pavel V. Talanov
f59a4c537e Minor: remove some dead code 2016-02-08 16:45:46 +03:00
Nikolay Krasko
909ced5fa2 Use non-local functions to avoid creating lambdas in heap 2016-02-08 16:43:55 +03:00
Nikolay Krasko
99a693a14b Too many empty ArrayList stored for arguments 2016-02-08 16:43:54 +03:00
Nikolay Krasko
ff2029035e Don't generate new empty list with TypeParameterDescriptor 2016-02-08 16:43:54 +03:00
Denis Zharkov
cd3f7df28c Create deep descriptors copy for Change signature
It's needed to prevent accesses to invalid PSI
after changes has been applied
2016-02-08 16:40:47 +03:00
Denis Zharkov
c879f83037 Fix primitive types mapping
Use boxed version if type was enhaced to not-nullable
2016-02-08 16:40:47 +03:00
Denis Zharkov
68110f5859 Add minor optimization
Do not copy overrides while creating FAKE_OVERRIDE
2016-02-08 16:40:47 +03:00
Denis Zharkov
18e7272a1e Do not force overridden descriptors computation
Currently 'overriddenDescriptors' of substituted function is lazy
and in most cases it's unnecessary to compute it
(it's enough to use the same field from 'original')
2016-02-08 16:40:47 +03:00
Denis Zharkov
9e3d381eb3 Perform computation of overridden descriptors lazy
It's makes sense in cases when descriptors are being substituted, because
in many cases their overridden are not needed.
2016-02-08 16:40:47 +03:00
Denis Zharkov
fae6de9acd Replace 'addOverriddenDescriptor' with 'setOverriddenDescriptors'
It helps to get rid of redundant SmartSets (e.g. for top-level functions)
2016-02-08 16:40:47 +03:00
Denis Zharkov
c1f57b743b Do not build enhanced descriptors if they are unchanged 2016-02-08 16:40:47 +03:00
Denis Zharkov
924d706e79 Release original Java descriptors while enhancing
It's both more correct and helps to release memory retained by
descriptor before enhancement
2016-02-08 16:40:47 +03:00
Denis Zharkov
beea2d5d10 Use source elements instead of descriptors
It's needed because resulting descriptors are different
(because they are enhanced) from ones on which load error is reported.
See where latter happens

Currently we suppose that source elements should be stable
2016-02-08 16:40:47 +03:00
Michael Bogdanov
848549dd5d Rollback "Fix for KT-10659: Debugger: Evaluate Expression and Watches fail for inline function parameter passed by reference" 2016-02-08 16:43:22 +03:00
Pavel V. Talanov
9e5c387d6c PropertyCodegen: Diagnose descriptor not found for property 2016-02-08 16:18:36 +03:00
Natalia Ukhorskaya
25b8e4f1b2 Do not compute classnames during stepping
#KT-10827 Fixed
2016-02-08 15:49:11 +03:00
Natalia Ukhorskaya
d238df8525 Debugger: add test for line breakpoint variants with inline function call. Fix testData for muted test 2016-02-08 15:49:11 +03:00
Zalim Bashorov
3c4cb54573 Allow to use internal declarations from special modules in compiler (JPS)
(e.g. IDEA 16 gradle tests loaded in separate module)

 #KT-10595 Fixed
2016-02-08 15:42:49 +03:00
Zalim Bashorov
e328c24857 J2K KotlinBuilderModuleScriptGenerator: cleanup 2016-02-08 15:42:48 +03:00
Zalim Bashorov
21e69a0a4c J2K KotlinBuilderModuleScriptGenerator: convert 2016-02-08 15:42:48 +03:00
Zalim Bashorov
d5030335b6 J2K KotlinBuilderModuleScriptGenerator: .java -> .kt 2016-02-08 15:42:48 +03:00
Zalim Bashorov
2c1d1e84a6 Allow to use internal declarations from special modules in IDEA
(e.g. IDEA 16 gradle tests loaded in separate module)

 #KT-10595 Fixed
2016-02-08 15:42:47 +03:00
Dmitry Petrov
5968ce96df KT-10939 CANNOT_COMPLETE_RESOLVE for inherited generic interface method
'original' for value parameters of fake override is not a value parameter of unsubstituted fake override.
Match value parameters by index.
2016-02-08 10:08:35 +03:00
Alexander Udalov
9f786c00a7 Fix test data after removing old annotation classes 2016-02-07 10:03:19 +05:30
Nikolay Krasko
938a435346 Allow to process return statements without parent KtDeclaration (EA-70883) 2016-02-06 17:50:17 +03:00
Nikolay Krasko
1e50847985 SOE on setEnabled(). setEnabled() changes were propagated back to action group with the request to update state (EA-71014) 2016-02-06 17:50:16 +03:00
Alexander Udalov
e82d549853 Delete old metadata annotation classes 2016-02-06 15:53:55 +05:30
Alexander Udalov
8800782c83 Move constants from JvmAnnotationNames closer to usages 2016-02-06 15:53:55 +05:30
Alexander Udalov
2f5a6ac465 Minor, add extra constant to JvmAnnotationNames, drop unneeded utility 2016-02-06 15:53:55 +05:30
Alexander Udalov
5de1cf3bb4 Do not write old metadata annotations to bytecode 2016-02-06 15:53:55 +05:30
Alexander Udalov
ba80e8ba81 Use kotlin.Metadata instead of old annotations in IDE, reflection and tests 2016-02-06 15:53:55 +05:30
Mikhail Glukhikh
7da981e12c Regression tests #KT-8168 Obsolete 2016-02-05 18:29:40 +03:00
Denis Zharkov
0efe28a12a Do not inline non-const vals
#KT-10425 Fixed
2016-02-05 17:43:55 +03:00
Yan Zhulanow
f2edcd99a8 Illegal Dalvik identifier inspection 2016-02-05 17:28:50 +03:00
Denis Zharkov
8d87800a05 Fix JVM crash
Replace inlined 'let' containing complicated control flow with common `if`
2016-02-05 17:26:10 +03:00
Valentin Kipyatkov
affbefdfbe Better diagnostic for EA-70945 2016-02-05 16:29:58 +03:00
Valentin Kipyatkov
ce8e2d7a65 Added better diagnostic for EA-75805 2016-02-05 16:29:58 +03:00
Valentin Kipyatkov
3fe6f9cad2 More correct convertation to string template when number literals involved 2016-02-05 16:29:57 +03:00
Valentin Kipyatkov
9c426e70e1 Fixed EA-75114 2016-02-05 16:29:57 +03:00
Valentin Kipyatkov
c914ca0626 Fixed EA-75251 2016-02-05 16:29:57 +03:00
Valentin Kipyatkov
eca581ef43 Fixed EA-75979 2016-02-05 16:29:56 +03:00
Valentin Kipyatkov
8b6338ce62 Fixed EA-76497 2016-02-05 16:29:56 +03:00
Michael Bogdanov
bc2077bfaf More wise lambda search during inlining 2016-02-05 15:42:46 +03:00
Denis Zharkov
16f412f993 Generate multi-files facade even if it's empty
It still contains useful information about it's parts,
that may be used while building stubs for multi-file group
containing only InlineOnly functions
2016-02-05 15:02:24 +03:00
Denis Zharkov
889b136a68 Refine multi-file facades generation
Do not generate delegation from multi-file facade to inline-only functions
because they are effectively private in bytecode

 #KT-10858 Fixed
2016-02-05 15:02:24 +03:00
Dmitry Petrov
e4583fd275 Do not report IMPLICIT_CAST_TO_ANY on last statement of lambda with Unit(?) in at least one branch. 2016-02-05 10:44:50 +03:00
Dmitry Jemerov
fa8706b46a a bit more diagnostics to track down "Cannot find package fragment for file" 2016-02-04 15:50:25 +01:00
Ilya Gorbunov
6038bde3c1 Inline-only Lazy.getValue extension 2016-02-04 17:30:12 +03:00
Yan Zhulanow
8c17c5f40b Pack actual Kotlin Android compiler plugin sources into kotlin-android-extensions-ver-sources.jar 2016-02-04 17:24:44 +03:00
Pavel V. Talanov
c600fe1dc3 Fix "Select in project view" and "autoscroll from source" not working in some cases
#KT-9278 Fixed
  #KT-8356 Fixed
2016-02-04 17:13:21 +03:00
Stanislav Erokhin
9c72a388b2 Random code change to prevent JVM crash on windows (JRE version: 6.0_45-b06)
JVM crash log:
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x06b1e0ae, pid=2908, tid=1656
#
# JRE version: 6.0_45-b06
# Java VM: Java HotSpot(TM) Client VM (20.45-b01 mixed mode windows-x86 )
# Problematic frame:
# J  org.jetbrains.kotlin.idea.formatter.KotlinPreFormatProcessor$Visitor.visitNamedDeclaration(Lorg/jetbrains/kotlin/psi/KtNamedDeclaration;)V
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

---------------  T H R E A D  ---------------

Current thread (0x5f0bb800):  JavaThread "AWT-EventQueue-1 IDEA 15.0.4#IC-143.SNAPSHOT IDEA, eap:true, os:Windows Server 2008 R2 6.1, java-version:Sun Microsystems Inc. 1.6.0_45-b06 IDEA 15.0.4#IC-143.SNAPSHOT IDEA, eap:true, os:Windows Server 2008 R2 6.1, java-version:Sun Microsystems Inc. 1.6.0_45-b06" [_thread_in_Java, id=1656, stack(0x60520000,0x60570000)]

siginfo: ExceptionCode=0xc0000005, writing address 0x8b8721bf

Registers:
EAX=0x0b8721c0, EBX=0x0b655c10, ECX=0x00000000, EDX=0x4789df50
ESP=0x6056d620, EBP=0x6056df7c, ESI=0x0b0b3618, EDI=0x0b8721d0
EIP=0x06b1e0ae, EFLAGS=0x00010246

Top of Stack: (sp=0x6056d620)
0x6056d620:   00000006 0b86d8b8 0afd5c68 026112bb
0x6056d630:   0b86f1a6 0b86f1dc 6056e088 05632944
0x6056d640:   00000004 00000000 6056e088 0b86f214
0x6056d650:   00000086 6056d668 6dae8209 0b86f214
0x6056d660:   0b86f074 00000086 6056d8b0 049aec30
0x6056d670:   0b872170 0b655c10 0b871c80 0b0b5210
0x6056d680:   0b0b4df8 0b8721c0 00000005 0b8705c0
0x6056d690:   0afd5c68 0b86eef8 0afd5c68 0b86d8b8

Instructions: (pc=0x06b1e0ae)
0x06b1e08e:   b9 0e 00 00 89 79 34 8b 4a 68 89 08 89 50 04 33
0x06b1e09e:   c9 89 48 08 89 48 0c 89 44 24 64 b9 00 00 00 00
0x06b1e0ae:   89 88 ff ff ff 7f f0 83 04 24 00 83 fb 00 0f 84
0x06b1e0be:   12 00 00 00 81 7b 04 60 06 0d 45 0f 85 05 00 00

Register to memory mapping:

EAX=
[error occurred during error reporting (printing register info), id 0xc0000005]

Stack: [0x60520000,0x60570000],  sp=0x6056d620,  free space=309k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
J  org.jetbrains.kotlin.idea.formatter.KotlinPreFormatProcessor$Visitor.visitNamedDeclaration(Lorg/jetbrains/kotlin/psi/KtNamedDeclaration;)V
J  com.intellij.psi.impl.source.PostprocessReformattingAspect.doPostponedFormattingInner(Lcom/intellij/psi/FileViewProvider;)V
2016-02-04 15:48:18 +03:00
Nikolay Krasko
63a50ca3a9 Can't get file when event is invalid (EA-77748) 2016-02-04 15:12:02 +03:00
Pavel V. Talanov
7c84225cc4 Fix typechecker when initializer of destructuring declaration is unresolved or missing 2016-02-04 15:08:39 +03:00
Pavel V. Talanov
a4e3dd7030 Minor: refactor DestructuringDeclarationResolver 2016-02-04 15:08:39 +03:00
Zalim Bashorov
ba6c738cb5 Minor: don't init AnsiConsole when coloring is disabled 2016-02-04 14:36:31 +03:00
Dmitry Jemerov
bcc3102e05 highlight usages for parameter doesn't look at base declarations
#KT-10204 Fixed
2016-02-04 11:35:22 +01:00
Dmitry Jemerov
37976e516c postpone isJsProject() check
#KT-9026 Fixed
2016-02-04 11:31:46 +01:00
Pavel V. Talanov
abcdae8e69 Prevent recursion when computing parameter list of KtLightMethod (part 2)
Use ClsWrapperStubPsiFactory when building light classes for decompiled kotlin classes
2016-02-04 12:55:19 +03:00
Alexey Sedunov
5f037d372d Intentions: Move member of companion object to corresponding class
#KT-9697 Fixed
2016-02-04 12:26:19 +03:00
Alexey Sedunov
d13ac6b5a4 Intentions: Move class member to companion object
#KT-9697 In Progress
2016-02-04 12:26:18 +03:00
Alexey Sedunov
fe8a0ec2bc Move: Additional test for KT-10553 (private top-level property with default accessors) 2016-02-04 12:26:17 +03:00
Alexey Sedunov
48b538cebf Light Classes: Provide backing fields (if any) as one of property's light elements 2016-02-04 12:26:15 +03:00
Dmitry Petrov
b5145ea68b Use implementation part class for SMAP generation when inlining function both from binaries and sources. 2016-02-04 10:17:30 +03:00
Dmitry Jemerov
0a46033d40 ensure Kotlin's move handlers run before Java's
#KT-10703 Fixed
2016-02-03 17:44:29 +01:00
Alexey Andreev
e9d5d8f0fe [KT-7683] Implement translation of 'when .. in' clause to JS 2016-02-03 19:08:58 +03:00
Natalia Ukhorskaya
6ee4071462 Debugger: use top elements to cache classnames to minimize cache size 2016-02-03 18:53:50 +03:00
Natalia Ukhorskaya
2fa00f87e0 Minor: add some clarifications 2016-02-03 18:53:50 +03:00
Natalia Ukhorskaya
9b978377d0 Debugger: merge KotlinPositionManagerCache into KotlinDebuggerCaches 2016-02-03 18:53:50 +03:00
Natalia Ukhorskaya
b5b2bbc9ab Minor: rename KotlinEvaluateExpressionCache 2016-02-03 18:53:50 +03:00
Natalia Ukhorskaya
ccd22cd5ca KotlinPositionManager: use cache for classNames where possible 2016-02-03 18:53:50 +03:00
Natalia Ukhorskaya
f28f7eaa3b ExtraSteppingFilter: do not compute classNames for inline 2016-02-03 18:53:50 +03:00
Natalia Ukhorskaya
876e458c04 Add cache for library files 2016-02-03 18:53:50 +03:00
Natalia Ukhorskaya
e89638f937 Move typeMappers cache to KotlinPositionManagerCache 2016-02-03 18:53:50 +03:00
Natalia Ukhorskaya
c808f4ec2a KotlinPositionManager: add cache for classNames by psiElement 2016-02-03 18:53:50 +03:00
Mikhail Glukhikh
60d56b30bf Safe call arguments are now handled as nullable in generic resolver #KT-9985 Fixed 2016-02-03 18:34:10 +03:00
Dmitry Jemerov
187694d1b0 don't veto rename of constructors
#KT-9693 Fixed
2016-02-03 15:58:05 +01:00
Stanislav Erokhin
34d8dd9127 Add optimization for fake overrides creation. 2016-02-03 17:47:40 +03:00
Stanislav Erokhin
ec991b4ced Minor. Update run configuration. 2016-02-03 17:47:39 +03:00
Zalim Bashorov
030c55ebb2 Minor: fix testdata 2016-02-03 17:35:14 +03:00
Ilya Gorbunov
805410bb19 J2K: Remove special conversion for String.format. 2016-02-03 17:14:02 +03:00
Ilya Gorbunov
c243a2bdd5 In addition to extension String.format introduce String.Companion.format(format, args) to be used like in java. 2016-02-03 17:14:01 +03:00
Ilya Gorbunov
7105c7c182 Documentation stubs for new packages. 2016-02-03 17:04:28 +03:00
Mikhail Glukhikh
0c32fab690 Type comparison: first check for star projections, then obtain constructor parameters #KT-10893 Fixed
Also #EA-78405 Fixed
2016-02-03 16:26:39 +03:00
Pavel V. Talanov
c5be8ce1d3 Prevent recursion when computing parameter list of KtLightMethod
#KT-10890 Fixed
 #KT-10851 Fixed
2016-02-03 16:08:05 +03:00
Dmitry Petrov
4afe98a0f6 Better diagnostics for conflicting overloads.
Skip declarations without sources in reporting, not when determining redeclaration groups:
this allows emitting informative diagnostics for incremental compilation.
Provide containing declaration with "kind", e.g., "package '<root>'", "class A", and so on.
2016-02-03 15:53:07 +03:00
Zalim Bashorov
130301aa27 Minor: log the content of module.xml when a source root not found on FS
Related issues: #KT-9587 #KT-10394
2016-02-03 15:28:20 +03:00
Dmitry Jemerov
e227f6fc74 use more deterministic check to determine that "Configure Kotlin in project" notification should be displayed
#KT-10898 Fixed
2016-02-03 13:18:54 +01:00
Michael Bogdanov
394221fefb Updated test data 2016-02-03 10:35:32 +03:00
Michael Bogdanov
6ae6f72156 Fix for crashed build 2016-02-03 10:35:31 +03:00
Michael Bogdanov
4b203de608 INVISIBLE_MEMBER_FROM_INLINE renamed to NON_PUBLIC_CALL_FROM_PUBLIC_INLINE 2016-02-03 10:35:29 +03:00
Michael Bogdanov
d1db404959 Error diagnostic for private classes in inline functions; Fix for KT-7545: IllegalAccessError when accessing private nested class through inlined function from different package
#KT-7545 Fixed
2016-02-03 10:32:41 +03:00
Michael Bogdanov
71c2a6e792 Generate package private visibility in bytecode for private classes 2016-02-03 10:32:41 +03:00
Ilya Gorbunov
751ac3912d IDEA version for bootstrapping (use IDEA built with kotlin rc branch) 2016-02-03 00:23:10 +03:00
Ilya Gorbunov
f19ef6e3d5 SAM-constructors for Iterable and Sequence interfaces. 2016-02-03 00:13:17 +03:00
Ilya Gorbunov
947fd84f1e Minor: reorder primitive specializations in generated code (according to the order they defined in java). 2016-02-02 22:06:34 +03:00
Ilya Gorbunov
7a50562a4e Minor: reorder families in generated code. 2016-02-02 22:06:34 +03:00
Ilya Gorbunov
477b57cdfd Rearrange stdlib, part 2: rename files to better represent their content. 2016-02-02 22:06:33 +03:00
Ilya Gorbunov
57cfa54957 Rearrange stdlib between files and folders, rename files to better represent their content.
Fix package part name in testData
2016-02-02 22:06:32 +03:00
Dmitry Jemerov
c881cd1070 use new API for excluding Kotlin plugin from update checks 2016-02-02 16:19:29 +01:00
Dmitry Jemerov
45a387668b don't show two "Rename variables" checkboxes for a Kotlin class
#KT-8509 Fixed
2016-02-02 15:55:54 +01:00
Dmitry Jemerov
db5191041f better place for J2K options
#KT-10513 Fixed
2016-02-02 14:43:26 +01:00
Mikhail Glukhikh
45298e0bad Delegated properties now cannot be used before initialization #KT-10869 Fixed 2016-02-02 16:27:20 +03:00
Dmitry Petrov
65f754ffca Fix KT-10764 IDEA doesn't show overload conflict between constructor and function...
When checking for overloads in package, consider functions and top-level class constructors as possibly conflicting between each other. NB OverloadUtil uses containing package scope from module descriptor.

Change diagnostic message for CONFLICTING_OVERLOAD: it's misleading in case of fun vs constructor conflict.

Add custom multifile test for diagnostics in IDE (probably not the best; should preprocess file content if it's required to check highlighting in multiple files, not only in the first file).

Add test for KT-10765 Incremental compilation misses overload conflict between constructor and function ...
2016-02-02 16:21:26 +03:00
Nikolay Krasko
7dd725f0a4 Failed build is good enough for version increment 2016-02-02 16:10:54 +03:00
Dmitry Jemerov
4a1d282de6 don't try to parse empty text as XML 2016-02-02 13:40:23 +01:00
Denis Zharkov
8df05c6c4c Refine 'isMoreSpecific' calculation
Choose member with better visibility, it's needed for proper calculation
of types intersection member scope

 #KT-10481 Fixed
2016-02-02 15:26:49 +03:00
Ilya Gorbunov
148b53fc62 Add UTF_32 charsets to Charsets object as lazy initialized properties.
#KT-10379 Fixed
2016-02-02 15:23:22 +03:00
Natalia Ukhorskaya
f29efc2ca2 Evaluate expression shouldn't be applicable for class name of Java class in static call
#KT-7261 Fixed
2016-02-02 15:16:14 +03:00
Natalia Ukhorskaya
893c2495fe Minor: regenerate tests 2016-02-02 15:16:14 +03:00
Natalia Ukhorskaya
51ea804d88 Debugger: do not write exception to log in some valid cases 2016-02-02 15:16:14 +03:00
Natalia Ukhorskaya
45f96f8f32 Evaluate expression shouldn't be applicable for name of named parameter in function call
#KT-7266 Fixed
2016-02-02 15:16:14 +03:00
Natalia Ukhorskaya
4f76207a27 Fix breakpoints in inline function with generic crossinline argument
#KT-10673 Fixed
2016-02-02 15:16:14 +03:00
Natalia Ukhorskaya
b19d32e4f2 Public members should have bigger priority in debugContext
#KT-10634 Fixed
2016-02-02 15:16:14 +03:00
Natalia Ukhorskaya
d60a5e65c1 Debugger: skip visibility check 2016-02-02 15:16:14 +03:00
Dmitry Petrov
bad8320038 Fix for KT-10881 Declaring constant in a mutlifile class causes an IllegalAccessError on its usage.
Generate fields for 'const' properties in facade class.

NB reading annotations for 'const' vals in multifile class doesn't work, KT-10892.
2016-02-02 15:06:21 +03:00
Dmitry Jemerov
970d6f6834 generate local variables table for @JvmOverloads-generated methods
#KT-7319 Fixed
2016-02-02 12:11:51 +01:00
Yan Zhulanow
da7acd5e73 Check annotations on default property getter/setter 2016-02-02 13:14:56 +03:00
Mikhail Glukhikh
7e528da00a Regression codegen test #KT-8344 Obsolete 2016-02-02 12:43:52 +03:00
Denis Zharkov
816c66063b Report special diagnostic when fake-call receiver is nullable
#KT-3602 Fixed
2016-02-02 08:17:49 +03:00
Denis Zharkov
829a5639f1 Rework error reporting for fake call resolution
Move diagnostic creation to one place
2016-02-02 08:17:48 +03:00
Denis Zharkov
9b3f557337 Report MEMBER_PROJECTED_OUT on calls with smart cast receiver
#KT-10856 Fixed
2016-02-02 08:17:48 +03:00
Ilya Gorbunov
05192547da Make DEFAULT_BUFFER_SIZE a constant. 2016-02-01 22:20:31 +03:00
Ilya Gorbunov
801a26a544 Fix testData 2016-02-01 22:20:30 +03:00
Ilya Gorbunov
a192915c82 Do not inline Regex.replace 2016-02-01 22:20:28 +03:00
Ilya Gorbunov
dccae6c3ff Introduce annotation InlineExposed to indicate internal members effectively public due to usage in inlined functions.
Currently, doesn't affect anything.

Make collectionSizeOrDefault and collectionSizeOrNull internal, but expose them via inlining together with mapCapacity.

Make Regex(Pattern) constructor exposed by inlined Pattern.toRegex
2016-02-01 22:20:27 +03:00
Ilya Gorbunov
dacf25fdec Make all assert inline. Field _Assertions.ENABLED instead of property ASSERTIONS_ENABLED 2016-02-01 22:09:19 +03:00
Ilya Gorbunov
c763b592a5 IDEA version for bootstrapping
Build markdown every time (again).
2016-02-01 22:09:18 +03:00
Ilya Gorbunov
1cef327880 Throw assertion when inline-only is applied without inline 2016-02-01 22:09:17 +03:00
Ilya Gorbunov
a12fe2c18a Do not use inline-only in java 2016-02-01 22:09:17 +03:00
Ilya Gorbunov
8a00db5661 Include internal annotatations in mock runtime 2016-02-01 22:09:16 +03:00
Ilya Gorbunov
fc3f98dae2 Deprecate currentThread property 2016-02-01 22:09:15 +03:00
Ilya Gorbunov
42bd8df2ca Drop CharSequence.get extension 2016-02-01 22:09:14 +03:00
Ilya Gorbunov
1eee1fa803 Swap parameters in File.forEachBlock 2016-02-01 22:09:13 +03:00
Ilya Gorbunov
abe927056b Inline-only in kotlin.comparisons 2016-02-01 22:09:13 +03:00
Ilya Gorbunov
54977ee09a Inline-only in kotlin.io 2016-02-01 22:09:12 +03:00
Ilya Gorbunov
47d580cbc5 Inline-only in kotlin.text 2016-02-01 22:09:11 +03:00
Ilya Gorbunov
56c5758db1 Inline-only in kotlin and kotlin.system packages, split Float/Double extension implementations for JVM and JS to make them inline-only in JVM. 2016-02-01 22:09:10 +03:00
Ilya Gorbunov
40fae0463f Inline-only in kotlin.concurrent, make all timer utilities inline. 2016-02-01 22:09:09 +03:00
Ilya Gorbunov
ce5fd3ee77 Inline-only in kotlin.collections 2016-02-01 22:09:08 +03:00
Ilya Gorbunov
c7bd70732c Inline-only in generated code 2016-02-01 22:09:07 +03:00
Ilya Gorbunov
8c0008aa2e StdLib Generators: support three flavors of inline 2016-02-01 22:09:07 +03:00
Dmitry Jemerov
38b58db4f9 don't apply StandardScriptDefinition in REPL 2016-02-01 19:16:31 +01:00
Dmitry Jemerov
84f9cb9bfd correctly separate stdout and stderr when parsing REPL output 2016-02-01 19:06:17 +01:00
Ilya Gorbunov
3ae4c033b6 Wrap exceptions thrown by class builders and add details about class file being generated. 2016-02-01 19:59:06 +03:00
Michael Bogdanov
5f38c1d571 Fix for KT-10729: Accessing private const field in companion object from a function in the same companion generates run-time error 2016-02-01 18:42:19 +03:00
Michael Bogdanov
9790afb1bd Idea dependency updated to 143.2072 2016-02-01 18:32:13 +03:00
Michael Bogdanov
328b9bfeda Removed old default generation 2016-02-01 18:32:12 +03:00
989 changed files with 20324 additions and 12103 deletions

View File

@@ -15,7 +15,7 @@
<method>
<option name="Make" enabled="false" />
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="clean_idea_output" />
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/update_dependencies.xml" target="update" />
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/update_dependencies.xml" target="update_teamcity" />
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="dist" />
<option name="MakeProject" enabled="true" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Generate Tests" run_configuration_type="Application" />

View File

@@ -1130,6 +1130,7 @@
<delete dir="${output}/mock-runtime-src" failonerror="false"/>
<mkdir dir="${output}/mock-runtime-src"/>
<copy file="${basedir}/libraries/stdlib/src/kotlin/util/Standard.kt" todir="${output}/mock-runtime-src"/>
<copy file="${basedir}/libraries/stdlib/src/kotlin/internal/Annotations.kt" todir="${output}/mock-runtime-src"/>
<new-kotlinc output="${output}/classes/mock-runtime" moduleName="kotlin-stdlib">
<src>

View File

@@ -63,7 +63,6 @@ import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_SYNTHETIC_CLASS;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
@@ -257,8 +256,7 @@ public class AsmUtil {
Classes in byte code should be public or package private
*/
public static int getVisibilityAccessFlagForClass(ClassDescriptor descriptor) {
if (DescriptorUtils.isTopLevelDeclaration(descriptor) ||
descriptor.getVisibility() == Visibilities.PUBLIC ||
if (descriptor.getVisibility() == Visibilities.PUBLIC ||
// TODO: should be package private, but for now Kotlin's reflection can't access members of such classes
descriptor.getVisibility() == Visibilities.LOCAL ||
descriptor.getVisibility() == Visibilities.INTERNAL) {
@@ -782,39 +780,26 @@ public class AsmUtil {
}
}
public static void writeKotlinSyntheticClassAnnotation(@NotNull ClassBuilder v, @NotNull GenerationState state) {
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(KOTLIN_SYNTHETIC_CLASS), true);
JvmCodegenUtil.writeAbiVersion(av);
av.visitEnd();
}
public static void writeAnnotationData(
@NotNull AnnotationVisitor av,
@NotNull DescriptorSerializer serializer,
@NotNull MessageLite message,
boolean old
@NotNull MessageLite message
) {
byte[] bytes = serializer.serialize(message);
AnnotationVisitor data = av.visitArray(old ? JvmAnnotationNames.DATA_FIELD_NAME : JvmAnnotationNames.METADATA_DATA_FIELD_NAME);
AnnotationVisitor data = av.visitArray(JvmAnnotationNames.METADATA_DATA_FIELD_NAME);
for (String string : BitEncoding.encodeBytes(bytes)) {
data.visit(null, string);
}
data.visitEnd();
AnnotationVisitor strings = av.visitArray(
old ? JvmAnnotationNames.STRINGS_FIELD_NAME : JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME
);
AnnotationVisitor strings = av.visitArray(JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME);
for (String string : ((JvmStringTable) serializer.getStringTable()).getStrings()) {
strings.visit(null, string);
}
strings.visitEnd();
}
@NotNull
public static String asmDescByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
return asmTypeByFqNameWithoutInnerClasses(fqName).getDescriptor();
}
@NotNull
public static Type asmTypeByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
return Type.getObjectType(internalNameByFqNameWithoutInnerClasses(fqName));

View File

@@ -286,13 +286,23 @@ public class ClassFileFactory implements OutputFileCollection {
@NotNull
@Override
public byte[] asByteArray() {
return generators.get(relativeClassFilePath).asBytes(builderFactory);
try {
return generators.get(relativeClassFilePath).asBytes(builderFactory);
}
catch (RuntimeException e) {
throw new RuntimeException("Error generating class file " + this.toString() + ": " + e.getMessage(), e);
}
}
@NotNull
@Override
public String asText() {
return generators.get(relativeClassFilePath).asText(builderFactory);
try {
return generators.get(relativeClassFilePath).asText(builderFactory);
}
catch (RuntimeException e) {
throw new RuntimeException("Error generating class file " + this.toString() + ": " + e.getMessage(), e);
}
}
@NotNull

View File

@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.psi.KtElement;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -60,7 +59,6 @@ import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.ExpressionCodegen.generateClassLiteralReference;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeAbiVersion;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
@@ -197,7 +195,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
erasedInterfaceFunction.getValueParameters(), erasedInterfaceFunction.getReturnType(),
Modality.OPEN, erasedInterfaceFunction.getVisibility());
descriptorForBridges.addOverriddenDescriptor(erasedInterfaceFunction);
DescriptorUtilsKt.setSingleOverridden(descriptorForBridges, erasedInterfaceFunction);
functionCodegen.generateBridges(descriptorForBridges);
}
@@ -219,9 +217,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
}
@Override
protected void generateKotlinAnnotation() {
writeKotlinSyntheticClassAnnotation(v, state);
protected void generateKotlinMetadataAnnotation() {
final DescriptorSerializer serializer =
DescriptorSerializer.createForLambda(new JvmSerializerExtension(v.getSerializationBindings(), state));
@@ -230,15 +226,10 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.SYNTHETIC_CLASS, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, functionProto, false);
writeAnnotationData(av, serializer, functionProto);
return Unit.INSTANCE;
}
});
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FUNCTION), true);
writeAbiVersion(av);
writeAnnotationData(av, serializer, functionProto, true);
av.visitEnd();
}
@Override

View File

@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmOverloadsAnnotation
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
@@ -134,6 +135,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
}
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) {
FunctionCodegen.generateLocalVariablesForParameters(mv, signature, null, Label(), Label(), remainingParameters, isStatic)
mv.visitEnd()
return
}
@@ -142,6 +144,9 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
val v = InstructionAdapter(mv)
mv.visitCode()
val methodBegin = Label()
mv.visitLabel(methodBegin)
val methodOwner = typeMapper.mapToCallableMethod(delegateFunctionDescriptor, false).owner
if (!isStatic) {
val thisIndex = frameMap.enterTemp(AsmTypes.OBJECT_TYPE)
@@ -201,6 +206,13 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
v.invokestatic(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
}
v.areturn(signature.returnType)
val methodEnd = Label()
mv.visitLabel(methodEnd)
FunctionCodegen.generateLocalVariablesForParameters(mv, signature, null, methodBegin, methodEnd,
remainingParameters, isStatic)
FunctionCodegen.endVisit(mv, null, methodElement)
}

View File

@@ -1246,6 +1246,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (compileTimeValue == null) {
return null;
}
if (compileTimeValue.getUsesNonConstValAsConstant()) return null;
KotlinType expectedType = bindingContext.getType(expression);
return compileTimeValue.toConstantValue(expectedType);
}
@@ -2119,7 +2122,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL;
boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
if (isBackingFieldInClassCompanion && forceField) {
if (isBackingFieldInClassCompanion && (forceField || propertyDescriptor.isConst() && Visibilities.isPrivate(propertyDescriptor.getVisibility()))) {
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
}
else if (syntheticBackingField && context.getFirstCrossInlineOrNonInlineContext().getParentContext().getContextDescriptor() != containingDeclaration) {

View File

@@ -400,11 +400,24 @@ public class FunctionCodegen {
@NotNull Label methodEnd,
@NotNull OwnerKind ownerKind
) {
Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator();
generateLocalVariablesForParameters(mv, jvmMethodSignature, thisType, methodBegin, methodEnd,
functionDescriptor.getValueParameters(),
AsmUtil.isStaticMethod(ownerKind, functionDescriptor));
}
public static void generateLocalVariablesForParameters(
@NotNull MethodVisitor mv,
@NotNull JvmMethodSignature jvmMethodSignature,
@Nullable Type thisType,
@NotNull Label methodBegin,
@NotNull Label methodEnd,
Collection<ValueParameterDescriptor> valueParameters,
boolean isStatic
) {
Iterator<ValueParameterDescriptor> valueParameterIterator = valueParameters.iterator();
List<JvmMethodParameterSignature> params = jvmMethodSignature.getValueParameters();
int shift = 0;
boolean isStatic = AsmUtil.isStaticMethod(ownerKind, functionDescriptor);
if (!isStatic) {
//add this
if (thisType != null) {
@@ -422,7 +435,7 @@ public class FunctionCodegen {
String parameterName;
if (kind == JvmMethodParameterKind.VALUE) {
ValueParameterDescriptor parameter = valueParameters.next();
ValueParameterDescriptor parameter = valueParameterIterator.next();
parameterName = parameter.getName().asString();
}
else {
@@ -676,15 +689,6 @@ public class FunctionCodegen {
generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen, defaultMethod);
endVisit(mv, "default method", getSourceFromDescriptor(functionDescriptor));
}
generateOldDefaultForFun(defaultMethod,
JvmDeclarationOriginKt.Synthetic(function, functionDescriptor),
flags,
getThrownExceptions(functionDescriptor, typeMapper),
(owner.getContextKind() == OwnerKind.DEFAULT_IMPLS ?
typeMapper.mapDefaultImpls((ClassDescriptor) functionDescriptor.getContainingDeclaration()) :
typeMapper.mapImplementationOwner(functionDescriptor)).getInternalName()
);
}
}
@@ -767,38 +771,6 @@ public class FunctionCodegen {
iv.visitLabel(end);
}
private void generateOldDefaultForFun(
Method newDefaultMethod,
JvmDeclarationOrigin origin,
int flags,
String[] exceptions,
String owner
) {
if ("<init>".equals(newDefaultMethod.getName())) {
return;
}
String oldSignature = newDefaultMethod.getDescriptor().replaceFirst("Ljava/lang/Object;\\)", ")");
MethodVisitor mv = v.newMethod(
origin,
flags,
newDefaultMethod.getName(),
oldSignature,
null,
exceptions
);
mv.visitCode();
int index = 0;
InstructionAdapter iv = new InstructionAdapter(mv);
for (Type type: Type.getArgumentTypes(oldSignature)) {
iv.load(index, type);
index += type.getSize();
}
iv.aconst(null);
iv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, newDefaultMethod.getName(), newDefaultMethod.getDescriptor(), false);
iv.areturn(newDefaultMethod.getReturnType());
mv.visitEnd();
}
@NotNull
private static FrameMap createFrameMap(
@NotNull GenerationState state,

View File

@@ -41,7 +41,6 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.name.FqName;
@@ -248,7 +247,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
protected void generateKotlinAnnotation() {
protected void generateKotlinMetadataAnnotation() {
final DescriptorSerializer serializer =
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings(), state));
@@ -257,15 +256,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.CLASS, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, classProto, false);
writeAnnotationData(av, serializer, classProto);
return Unit.INSTANCE;
}
});
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CLASS), true);
writeAbiVersion(av);
writeAnnotationData(av, serializer, classProto, true);
av.visitEnd();
}
private void writeEnclosingMethod() {

View File

@@ -146,11 +146,9 @@ class InterfaceImplBodyCodegen(
})
}
override fun generateKotlinAnnotation() {
override fun generateKotlinMetadataAnnotation() {
(v as InterfaceImplClassBuilder).stopCounting()
AsmUtil.writeKotlinSyntheticClassAnnotation(v, state)
writeSyntheticClassMetadata(v);
}

View File

@@ -30,8 +30,6 @@ import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.context.RootContext;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
import org.jetbrains.kotlin.psi.KtFile;
@@ -43,7 +41,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import java.io.File;
@@ -220,8 +217,4 @@ public class JvmCodegenUtil {
public static String getMappingFileName(@NotNull String moduleName) {
return "META-INF/" + moduleName + "." + ModuleMapping.MAPPING_FILE_EXT;
}
public static void writeAbiVersion(@NotNull AnnotationVisitor av) {
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmMetadataVersion.INSTANCE.toArray());
}
}

View File

@@ -119,7 +119,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
generateSyntheticParts();
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
generateKotlinAnnotation();
generateKotlinMetadataAnnotation();
}
done();
@@ -132,7 +132,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
protected void generateSyntheticParts() {
}
protected abstract void generateKotlinAnnotation();
protected abstract void generateKotlinMetadataAnnotation();
@Nullable
protected ClassDescriptor classForInnerClassRecord() {
@@ -601,12 +601,13 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal;
boolean forceField = (JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration())) ||
boolean forceFieldForCompanionProperty = JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration());
boolean forceField = forceFieldForCompanionProperty ||
syntheticBackingField ||
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
StackValue property = codegen.intermediateValueForProperty(
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(), true, StackValue.none()
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(), forceFieldForCompanionProperty, StackValue.none()
);
InstructionAdapter iv = codegen.v;

View File

@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
@@ -113,7 +112,7 @@ class MultifileClassCodegen(
generateDelegatesToPreviouslyCompiledParts(generateCallableMemberTasks, partFqNames)
if (!generateCallableMemberTasks.isEmpty()) {
if (!partFqNames.isEmpty()) {
generateMultifileFacadeClass(generateCallableMemberTasks, partFqNames)
}
}
@@ -213,7 +212,8 @@ class MultifileClassCodegen(
if (declaration is KtNamedFunction || declaration is KtProperty) {
val descriptor = state.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
assert(descriptor is CallableMemberDescriptor) { "Expected callable member, was " + descriptor + " for " + declaration.text }
if (!Visibilities.isPrivate((descriptor as CallableMemberDescriptor).visibility)) {
if (!Visibilities.isPrivate((descriptor as CallableMemberDescriptor).visibility)
&& AsmUtil.getVisibilityAccessFlag(descriptor) != Opcodes.ACC_PRIVATE) {
generateCallableMemberTasks.put(descriptor, { memberCodegen.genFunctionOrProperty(declaration) })
}
}
@@ -273,31 +273,20 @@ class MultifileClassCodegen(
if (state.classBuilderMode != ClassBuilderMode.FULL) return
if (files.any { it.isScript }) return
val partInternalNames = partFqNames.map(AsmUtil::internalNameByFqNameWithoutInnerClasses).sorted()
fun writePartNames(av: AnnotationVisitor, fieldName: String) {
val arv = av.visitArray(fieldName)
for (internalName in partInternalNames) {
writeKotlinMetadata(classBuilder, KotlinClassHeader.Kind.MULTIFILE_CLASS) { av ->
val arv = av.visitArray(JvmAnnotationNames.METADATA_DATA_FIELD_NAME)
for (internalName in partFqNames.map(AsmUtil::internalNameByFqNameWithoutInnerClasses).sorted()) {
arv.visit(null, internalName)
}
arv.visitEnd()
}
writeKotlinMetadata(classBuilder, KotlinClassHeader.Kind.MULTIFILE_CLASS) { av ->
writePartNames(av, JvmAnnotationNames.METADATA_DATA_FIELD_NAME)
}
val av = classBuilder.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS), true)
JvmCodegenUtil.writeAbiVersion(av)
writePartNames(av, JvmAnnotationNames.FILE_PART_CLASS_NAMES_FIELD_NAME)
av.visitEnd()
}
private fun createCodegenForPartOfMultifileFacade(facadeContext: FieldOwnerContext<*>): MemberCodegen<KtFile> =
object : MemberCodegen<KtFile>(state, null, facadeContext, null, classBuilder) {
override fun generateDeclaration() = throw UnsupportedOperationException()
override fun generateBody() = throw UnsupportedOperationException()
override fun generateKotlinAnnotation() = throw UnsupportedOperationException()
override fun generateKotlinMetadataAnnotation() = throw UnsupportedOperationException()
}
fun done() {

View File

@@ -69,7 +69,7 @@ class MultifileClassPartCodegen(
}
}
override fun generateKotlinAnnotation() {
override fun generateKotlinMetadataAnnotation() {
val members = ArrayList<DeclarationDescriptor>()
for (declaration in element.declarations) {
when (declaration) {
@@ -88,15 +88,9 @@ class MultifileClassPartCodegen(
val packageProto = serializer.packagePartProto(members).build()
writeKotlinMetadata(v, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART) { av ->
AsmUtil.writeAnnotationData(av, serializer, packageProto, false)
AsmUtil.writeAnnotationData(av, serializer, packageProto)
av.visit(JvmAnnotationNames.METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassType.internalName)
}
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS_PART), true)
JvmCodegenUtil.writeAbiVersion(av)
AsmUtil.writeAnnotationData(av, serializer, packageProto, true)
av.visit(JvmAnnotationNames.MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassType.internalName)
av.visitEnd()
}
override fun generateSyntheticParts() {

View File

@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -43,9 +42,7 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
import static org.jetbrains.kotlin.codegen.AsmUtil.writeAnnotationData;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeAbiVersion;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PackagePartCodegen extends MemberCodegen<KtFile> {
@@ -109,7 +106,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
}
@Override
protected void generateKotlinAnnotation() {
protected void generateKotlinMetadataAnnotation() {
List<DeclarationDescriptor> members = new ArrayList<DeclarationDescriptor>();
for (KtDeclaration declaration : element.getDeclarations()) {
if (declaration instanceof KtNamedFunction) {
@@ -128,15 +125,10 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.FILE_FACADE, new Function1<AnnotationVisitor, Unit>() {
@Override
public Unit invoke(AnnotationVisitor av) {
writeAnnotationData(av, serializer, packageProto, false);
writeAnnotationData(av, serializer, packageProto);
return Unit.INSTANCE;
}
});
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FILE_FACADE), true);
writeAbiVersion(av);
writeAnnotationData(av, serializer, packageProto, true);
av.visitEnd();
}
@Override

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
@@ -67,6 +68,9 @@ import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJ
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PropertyCodegen {
private static Logger LOG = Logger.getInstance(PropertyCodegen.class);
private final GenerationState state;
private final ClassBuilder v;
private final FunctionCodegen functionCodegen;
@@ -94,7 +98,11 @@ public class PropertyCodegen {
public void gen(@NotNull KtProperty property) {
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, property);
assert variableDescriptor instanceof PropertyDescriptor : "Property " + property.getText() + " should have a property descriptor: " + variableDescriptor;
if (!(variableDescriptor instanceof PropertyDescriptor)) {
String problem = "Property " + property.getName() + " should have a property descriptor: " + variableDescriptor;
LOG.error(problem, PsiUtilsKt.getElementTextWithContext(property));
throw new AssertionError(problem);
}
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
gen(property, propertyDescriptor, property.getGetter(), property.getSetter());
@@ -114,7 +122,7 @@ public class PropertyCodegen {
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DEFAULT_IMPLS
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
if (CodegenContextUtil.isImplClassOwner(context)) {
if (isBackingFieldOwner(descriptor)) {
assert declaration != null : "Declaration is null for different context: " + context;
genBackingFieldAndAnnotations(declaration, descriptor, false);
@@ -128,6 +136,13 @@ public class PropertyCodegen {
}
}
private boolean isBackingFieldOwner(@NotNull PropertyDescriptor descriptor) {
if (descriptor.isConst()) {
return !(context instanceof MultifileClassPartContext);
}
return CodegenContextUtil.isImplClassOwner(context);
}
private void genBackingFieldAndAnnotations(@NotNull KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
boolean hasBackingField = hasBackingField(declaration, descriptor);
boolean hasDelegate = declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate();

View File

@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.AsmUtil.method
import org.jetbrains.kotlin.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation
import org.jetbrains.kotlin.codegen.context.ClassContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.*
@@ -158,9 +157,7 @@ class PropertyReferenceCodegen(
}
}
override fun generateKotlinAnnotation() {
writeKotlinSyntheticClassAnnotation(v, state)
override fun generateKotlinMetadataAnnotation() {
writeSyntheticClassMetadata(v)
}

View File

@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.util.OperatorNameConventions;
@@ -39,7 +40,8 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.Collections;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.NO_FLAG_PACKAGE_PRIVATE;
import static org.jetbrains.kotlin.codegen.AsmUtil.asmTypeByFqNameWithoutInnerClasses;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -94,8 +96,6 @@ public class SamWrapperCodegen {
);
cv.visitSource(file.getName(), null);
writeKotlinSyntheticClassAnnotation(cv, state);
WriteAnnotationUtilKt.writeSyntheticClassMetadata(cv);
// e.g. ASM type for Function2
@@ -166,7 +166,7 @@ public class SamWrapperCodegen {
originalInterfaceErased.getValueParameters(), originalInterfaceErased.getReturnType(),
Modality.OPEN, originalInterfaceErased.getVisibility());
descriptorForBridges.addOverriddenDescriptor(originalInterfaceErased);
DescriptorUtilsKt.setSingleOverridden(descriptorForBridges, originalInterfaceErased);
codegen.generateBridges(descriptorForBridges);
}

View File

@@ -104,7 +104,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
}
@Override
protected void generateKotlinAnnotation() {
protected void generateKotlinMetadataAnnotation() {
// TODO
}

View File

@@ -213,7 +213,7 @@ public class InlineCodegen extends CallGenerator {
}
nodeAndSMAP = InlineCodegenUtil.getMethodNode(
file.contentsToByteArray(), asmMethod.getName(), asmMethod.getDescriptor(), containingClasses.getFacadeClassId()
file.contentsToByteArray(), asmMethod.getName(), asmMethod.getDescriptor(), containerId
);
if (nodeAndSMAP == null) {
@@ -241,7 +241,7 @@ public class InlineCodegen extends CallGenerator {
SMAP smap;
if (callDefault) {
Type implementationOwner = typeMapper.mapOwner(functionDescriptor);
Type implementationOwner = typeMapper.mapImplementationOwner(functionDescriptor);
FakeMemberCodegen parentCodegen = new FakeMemberCodegen(codegen.getParentCodegen(), inliningFunction,
(FieldOwnerContext) methodContext.getParentContext(),
implementationOwner.getInternalName());
@@ -366,7 +366,7 @@ public class InlineCodegen extends CallGenerator {
new FakeMemberCodegen(codegen.getParentCodegen(), expression,
(FieldOwnerContext) context.getParentContext(),
isLambda ? codegen.getParentCodegen().getClassName()
: typeMapper.mapOwner(descriptor).getInternalName());
: typeMapper.mapImplementationOwner(descriptor).getInternalName());
FunctionGenerationStrategy strategy =
expression instanceof KtCallableReferenceExpression ?
@@ -425,7 +425,7 @@ public class InlineCodegen extends CallGenerator {
}
@Override
protected void generateKotlinAnnotation() {
protected void generateKotlinMetadataAnnotation() {
throw new IllegalStateException();
}

View File

@@ -19,12 +19,10 @@ package org.jetbrains.kotlin.codegen.inline;
import org.jetbrains.annotations.Nullable;
class InvokeCall {
private final int index;
public final LambdaInfo lambdaInfo;
public final int finallyDepthShift;
InvokeCall(int index, @Nullable LambdaInfo lambdaInfo, int finallyDepthShift) {
this.index = index;
InvokeCall(@Nullable LambdaInfo lambdaInfo, int finallyDepthShift) {
this.lambdaInfo = lambdaInfo;
this.finallyDepthShift = finallyDepthShift;
}

View File

@@ -94,8 +94,8 @@ public class LocalVarRemapper {
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index, MethodVisitor mv) {
RemapInfo info = doRemap(index);
//add entries only for shifted vars or remapped to locals
if (SHIFT == info.status || REMAPPED == info.status && info.value instanceof StackValue.Local) {
//add entries only for shifted vars
if (SHIFT == info.status) {
int newIndex = ((StackValue.Local) info.value).index;
mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
}

View File

@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.codegen.StackValue;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.optimization.MandatoryMethodTransformer;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.utils.SmartSet;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Opcodes;
@@ -427,15 +428,15 @@ public class MethodInliner {
catch (AnalyzerException e) {
throw wrapException(e, node, "couldn't inline method call");
}
AbstractInsnNode cur = node.instructions.getFirst();
int index = 0;
Set<AbstractInsnNode> toDelete = SmartSet.create();
InsnList instructions = node.instructions;
AbstractInsnNode cur = instructions.getFirst();
boolean awaitClassReification = false;
int currentFinallyDeep = 0;
while (cur != null) {
Frame<SourceValue> frame = sources[index];
Frame<SourceValue> frame = sources[instructions.indexOf(cur)];
if (frame != null) {
if (ReifiedTypeInliner.isNeedClassReificationMarker(cur)) {
@@ -458,25 +459,11 @@ public class MethodInliner {
if (isInvokeOnLambda(owner, name) /*&& methodInsnNode.owner.equals(INLINE_RUNTIME)*/) {
SourceValue sourceValue = frame.getStack(firstParameterIndex);
LambdaInfo lambdaInfo = null;
int varIndex = -1;
LambdaInfo lambdaInfo = MethodInlinerUtilKt.getLambdaIfExistsAndMarkInstructions(
this, MethodInlinerUtilKt.singleOrNullInsn(sourceValue), true, instructions, sources, toDelete
);
if (sourceValue.insns.size() == 1) {
AbstractInsnNode insnNode = sourceValue.insns.iterator().next();
AbstractInsnNode processingInstruction = insnNode;
if (insnNode.getOpcode() == Opcodes.SWAP) {
processingInstruction = InlineCodegenUtil.getPrevMeaningful(insnNode);
}
lambdaInfo = getLambdaIfExists(processingInstruction);
if (lambdaInfo != null) {
//remove inlinable access
assert processingInstruction != null;
InlineCodegenUtil.removeInterval(node, processingInstruction, insnNode);
}
}
invokeCalls.add(new InvokeCall(varIndex, lambdaInfo, currentFinallyDeep));
invokeCalls.add(new InvokeCall(lambdaInfo, currentFinallyDeep));
}
else if (isAnonymousConstructorCall(owner, name)) {
Map<Integer, LambdaInfo> lambdaMapping = new HashMap<Integer, LambdaInfo>();
@@ -484,14 +471,13 @@ public class MethodInliner {
int offset = 0;
for (int i = 0; i < paramCount; i++) {
SourceValue sourceValue = frame.getStack(firstParameterIndex + i);
if (sourceValue.insns.size() == 1) {
AbstractInsnNode insnNode = sourceValue.insns.iterator().next();
LambdaInfo lambdaInfo = getLambdaIfExists(insnNode);
if (lambdaInfo != null) {
lambdaMapping.put(offset, lambdaInfo);
node.instructions.remove(insnNode);
}
LambdaInfo lambdaInfo = MethodInlinerUtilKt.getLambdaIfExistsAndMarkInstructions(
this, MethodInlinerUtilKt.singleOrNullInsn(sourceValue), false, instructions, sources, toDelete
);
if (lambdaInfo != null) {
lambdaMapping.put(offset, lambdaInfo);
}
offset += i == 0 ? 1 : argTypes[i - 1].getSize();
}
@@ -518,7 +504,6 @@ public class MethodInliner {
}
AbstractInsnNode prevNode = cur;
cur = cur.getNext();
index++;
//given frame is <tt>null</tt> if and only if the corresponding instruction cannot be reached (dead code).
if (frame == null) {
@@ -528,11 +513,15 @@ public class MethodInliner {
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
//but as result all this labels will be merged into one (see KT-5863)
} else {
node.instructions.remove(prevNode);
toDelete.add(prevNode);
}
}
}
for (AbstractInsnNode insnNode : toDelete) {
instructions.remove(insnNode);
}
//clean dead try/catch blocks
List<TryCatchBlockNode> blocks = node.tryCatchBlocks;
for (Iterator<TryCatchBlockNode> iterator = blocks.iterator(); iterator.hasNext(); ) {
@@ -575,7 +564,7 @@ public class MethodInliner {
}
@Nullable
public LambdaInfo getLambdaIfExists(@Nullable AbstractInsnNode insnNode) {
LambdaInfo getLambdaIfExists(@Nullable AbstractInsnNode insnNode) {
if (insnNode == null) {
return null;
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2010-2016 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.codegen.inline
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.VarInsnNode
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
fun MethodInliner.getLambdaIfExistsAndMarkInstructions(
insnNode: AbstractInsnNode?,
processSwap: Boolean,
insnList: InsnList,
frames: Array<Frame<SourceValue>?>,
toDelete: MutableSet<AbstractInsnNode>
): LambdaInfo? {
if (insnNode == null) return null
getLambdaIfExists(insnNode)?.let {
//delete lambda aload instruction
toDelete.add(insnNode)
return it
}
if (insnNode is VarInsnNode && insnNode.opcode == Opcodes.ALOAD) {
val varIndex = insnNode.`var`
val localFrame = frames[insnList.indexOf(insnNode)] ?: return null
val storeIns = localFrame.getLocal(varIndex).singleOrNullInsn()
if (storeIns is VarInsnNode && storeIns.getOpcode() == Opcodes.ASTORE) {
val frame = frames[insnList.indexOf(storeIns)] ?: return null
val topOfStack = frame.top()!!.singleOrNullInsn()
getLambdaIfExistsAndMarkInstructions(topOfStack, processSwap, insnList, frames, toDelete)?.let {
//remove intermediate lambda astore, aload instruction: see 'complexStack/simple.1.kt' test
toDelete.add(storeIns)
toDelete.add(insnNode)
return it
}
}
}
else if (processSwap && insnNode.opcode == Opcodes.SWAP) {
val swapFrame = frames[insnList.indexOf(insnNode)] ?: return null
val dispatchReceiver = swapFrame.top()!!.singleOrNullInsn()
getLambdaIfExistsAndMarkInstructions(dispatchReceiver, false, insnList, frames, toDelete).let {
//remove swap instruction (dispatch receiver would be deleted on recursion call): see 'complexStack/simpleExtension.1.kt' test
toDelete.add(insnNode)
return it
}
}
return null
}
fun SourceValue.singleOrNullInsn() = insns.singleOrNull()

View File

@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment;
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
import org.jetbrains.kotlin.load.java.typeEnhancement.TypeEnhancementKt;
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass;
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement;
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement;
@@ -159,7 +160,7 @@ public class JetTypeMapper {
if (file != null) {
Visibility visibility = descriptor.getVisibility();
if (!publicFacade ||
descriptor instanceof PropertyDescriptor ||
isNonConstProperty(descriptor) ||
Visibilities.isPrivate(visibility) ||
isAccessor/*Cause of KT-9603*/
) {
@@ -181,6 +182,12 @@ public class JetTypeMapper {
" in package fragment " + descriptor.getContainingDeclaration());
}
private static boolean isNonConstProperty(@NotNull CallableMemberDescriptor descriptor) {
if (!(descriptor instanceof PropertyDescriptor)) return false;
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
return !propertyDescriptor.isConst();
}
public static class ContainingClassesInfo {
private final ClassId facadeClassId;
private final ClassId implClassId;
@@ -504,7 +511,8 @@ public class JetTypeMapper {
PrimitiveType primitiveType = KotlinBuiltIns.getPrimitiveTypeByFqName(fqName);
if (primitiveType != null) {
Type asmType = Type.getType(JvmPrimitiveType.get(primitiveType).getDesc());
return TypeUtils.isNullableType(type) ? boxType(asmType) : asmType;
boolean isNullableInJava = TypeUtils.isNullableType(type) || TypeEnhancementKt.hasEnhancedNullability(type);
return isNullableInJava ? boxType(asmType) : asmType;
}
PrimitiveType arrayElementType = KotlinBuiltIns.getPrimitiveTypeByArrayClassFqName(fqName);

View File

@@ -77,7 +77,7 @@ fun getEffectiveVariance(parameterVariance: Variance, projectionKind: Variance):
val CallableDescriptor?.isMethodWithDeclarationSiteWildcards: Boolean
get() {
if (this !is CallableMemberDescriptor) return false
return firstOverridden {
return original.firstOverridden(useOriginal = true) {
METHODS_WITH_DECLARATION_SITE_WILDCARDS.contains(it.propertyIfAccessor.fqNameOrNull())
} != null
}

View File

@@ -31,7 +31,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
import java.util.Map;
import static org.jetbrains.kotlin.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -58,8 +57,6 @@ public class MappingClassesForWhenByEnumCodegen {
generateFields(cb, mappings);
generateInitialization(cb, mappings);
writeKotlinSyntheticClassAnnotation(cb, state);
WriteAnnotationUtilKt.writeSyntheticClassMetadata(cb);
cb.done();

View File

@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
fun writeKotlinMetadata(cb: ClassBuilder, kind: KotlinClassHeader.Kind, action: (AnnotationVisitor) -> Unit) {
val av = cb.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.METADATA), true)
val av = cb.newAnnotation(JvmAnnotationNames.METADATA_DESC, true)
av.visit(JvmAnnotationNames.METADATA_VERSION_FIELD_NAME, JvmMetadataVersion.INSTANCE.toArray())
av.visit(JvmAnnotationNames.BYTECODE_VERSION_FIELD_NAME, JvmBytecodeBinaryVersion.INSTANCE.toArray())
av.visit(JvmAnnotationNames.KIND_FIELD_NAME, kind.id)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -130,16 +130,23 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
MessageCollector collector = new PrintingMessageCollector(errStream, messageRenderer, arguments.verbose);
try {
AnsiConsole.systemInstall();
if (PlainTextMessageRenderer.COLOR_ENABLED) {
AnsiConsole.systemInstall();
}
errStream.print(messageRenderer.renderPreamble());
return exec(collector, services, arguments);
}
finally {
errStream.print(messageRenderer.renderConclusion());
AnsiConsole.systemUninstall();
if (PlainTextMessageRenderer.COLOR_ENABLED) {
AnsiConsole.systemUninstall();
}
}
}
@SuppressWarnings("WeakerAccess") // Used in maven (see KotlinCompileMojoBase.java)
@NotNull
public ExitCode exec(@NotNull MessageCollector messageCollector, @NotNull Services services, @NotNull A arguments) {
printVersionIfNeeded(messageCollector, arguments);
@@ -213,7 +220,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
@NotNull Disposable rootDisposable
);
protected void printVersionIfNeeded(@NotNull MessageCollector messageCollector, @NotNull A arguments) {
private void printVersionIfNeeded(@NotNull MessageCollector messageCollector, @NotNull A arguments) {
if (!arguments.version) return;
messageCollector.report(CompilerMessageSeverity.INFO,
@@ -234,6 +241,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
}
}
@SuppressWarnings("UseOfSystemOutOrSystemErr")
@NotNull
public static ExitCode doMainNoExit(@NotNull CLICompiler compiler, @NotNull String[] args) {
try {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -30,11 +30,14 @@ import java.util.Set;
import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*;
public abstract class PlainTextMessageRenderer implements MessageRenderer {
private static final String KOTLIN_COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled";
// AnsiConsole doesn't check isatty() for stderr (see https://github.com/fusesource/jansi/pull/35).
// TODO: investigate why ANSI escape codes on Windows only work in REPL for some reason
private static final boolean COLOR_ENABLED =
public static final boolean COLOR_ENABLED =
!SystemInfo.isWindows &&
!"false".equals(System.getProperty("kotlin.colors.enabled")) &&
!"false".equals(System.getProperty(KOTLIN_COLORS_ENABLED_PROPERTY)) &&
CLibrary.isatty(CLibrary.STDERR_FILENO) != 0;
private static final String LINE_SEPARATOR = LineSeparator.getSystemLineSeparator().getSeparatorString();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -119,13 +119,13 @@ open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
configuration.put(JVMConfigurationKeys.MODULE_NAME, arguments.moduleName ?: JvmAbi.DEFAULT_MODULE_NAME)
configuration.add(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY, StandardScriptDefinition)
if (arguments.module == null && arguments.freeArgs.isEmpty() && !arguments.version) {
ReplFromTerminal.run(rootDisposable, configuration)
return ExitCode.OK
}
configuration.add(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY, StandardScriptDefinition)
if (arguments.skipMetadataVersionCheck) {
JvmMetadataVersion.skipCheck = true
}
@@ -164,6 +164,8 @@ open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
val directory = File(arguments.module).absoluteFile.parentFile
val compilerConfiguration = KotlinToJVMBytecodeCompiler.createCompilerConfiguration(configuration, moduleScript.modules, directory)
compilerConfiguration.put(JVMConfigurationKeys.MODULE_XML_FILE_PATH, arguments.module)
environment = createCoreEnvironment(rootDisposable, compilerConfiguration)
if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) return COMPILATION_ERROR

View File

@@ -76,10 +76,6 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
trace.setKotlinCodeAnalyzer(codeAnalyzer)
}
override fun getContextForPackage(files: Collection<KtFile>): LightClassConstructionContext {
return LightClassConstructionContext(bindingContext, module)
}
override fun getContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext {
//force resolve companion for light class generation
bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.cli.jvm.compiler;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
@@ -37,7 +38,9 @@ import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
import org.jetbrains.kotlin.cli.common.modules.ModuleScriptData;
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser;
import org.jetbrains.kotlin.cli.jvm.config.JVMConfigurationKeys;
import org.jetbrains.kotlin.codegen.ClassFileFactory;
import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.idea.KotlinFileType;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtFile;
@@ -54,6 +57,7 @@ import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation.N
import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR;
public class CompileEnvironmentUtil {
private static Logger LOG = Logger.getInstance(CompileEnvironmentUtil.class);
@NotNull
public static ModuleScriptData loadModuleDescriptions(String moduleDefinitionFile, MessageCollector messageCollector) {
@@ -141,8 +145,9 @@ public class CompileEnvironmentUtil {
public static List<KtFile> getKtFiles(
@NotNull final Project project,
@NotNull Collection<String> sourceRoots,
@NotNull CompilerConfiguration configuration,
@NotNull Function1<String, Unit> reportError
) {
) throws IOException {
final VirtualFileSystem localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL);
final Set<VirtualFile> processedFiles = Sets.newHashSet();
@@ -155,7 +160,17 @@ public class CompileEnvironmentUtil {
VirtualFile vFile = localFileSystem.findFileByPath(sourceRootPath);
if (vFile == null) {
reportError.invoke("Source file or directory not found: " + sourceRootPath);
String message = "Source file or directory not found: " + sourceRootPath;
String moduleFilePath = configuration.get(JVMConfigurationKeys.MODULE_XML_FILE_PATH);
if (moduleFilePath != null) {
String moduleFileContent = FileUtil.loadFile(new File(moduleFilePath));
LOG.warn(message +
"\n\nmodule file path: " + moduleFilePath +
"\ncontent:\n" + moduleFileContent);
}
reportError.invoke(message);
continue;
}
if (!vFile.isDirectory() && vFile.getFileType() != KotlinFileType.INSTANCE) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -131,7 +131,7 @@ class KotlinCoreEnvironment private constructor(
val index = JvmDependenciesIndex(javaRoots)
(fileManager as KotlinCliJavaFileManagerImpl).initIndex(index)
sourceFiles.addAll(CompileEnvironmentUtil.getKtFiles(project, getSourceRootsCheckingForDuplicates(), {
sourceFiles.addAll(CompileEnvironmentUtil.getKtFiles(project, getSourceRootsCheckingForDuplicates(), this.configuration, {
message ->
report(ERROR, message)
}))

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -115,7 +115,7 @@ object KotlinToJVMBytecodeCompiler {
for (module in chunk) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val ktFiles = CompileEnvironmentUtil.getKtFiles(
environment.project, getAbsolutePaths(directory, module)) { s -> throw IllegalStateException("Should have been checked before: " + s) }
environment.project, getAbsolutePaths(directory, module), configuration) { s -> throw IllegalStateException("Should have been checked before: " + s) }
if (!checkKotlinPackageUsage(environment, ktFiles)) return false
val moduleOutputDirectory = File(module.getOutputDirectory())
val generationState = generate(environment, result, ktFiles, module, moduleOutputDirectory,

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -44,6 +44,8 @@ public class JVMConfigurationKeys {
public static final CompilerConfigurationKey<CompilerJarLocator> COMPILER_JAR_LOCATOR =
CompilerConfigurationKey.create("Compiler jar locator");
public static final CompilerConfigurationKey<String> MODULE_XML_FILE_PATH = CompilerConfigurationKey.create("path to module.xml");
public static final CompilerConfigurationKey<List<Module>> MODULES =
CompilerConfigurationKey.create("module data");

View File

@@ -21,7 +21,7 @@ import net.rubygrapefruit.platform.ProcessLauncher
import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.io.File
import java.io.OutputStream
import java.io.PrintStream
@@ -61,9 +61,9 @@ object KotlinCompilerClient {
val flagFile = System.getProperty(COMPILE_DAEMON_CLIENT_ALIVE_PATH_PROPERTY)
?.let { it.trimQuotes() }
?.satisfying { !it.isBlank() }
?.check { !it.isBlank() }
?.let { File(it) }
?.satisfying { it.exists() }
?.check { it.exists() }
?: newFlagFile()
return connectToCompileService(compilerId, flagFile, daemonJVMOptions, daemonOptions, reportingTargets, autostart)
}
@@ -262,7 +262,7 @@ object KotlinCompilerClient {
.sortedWith(compareBy(DaemonJVMOptionsMemoryComparator().reversed(), { it.second.get() }))
val optsCopy = daemonJVMOptions.copy()
// if required options fit into fattest running daemon - return the daemon and required options with memory params set to actual ones in the daemon
return aliveWithOpts.firstOrNull()?.satisfying { daemonJVMOptions memorywiseFitsInto it.second.get() }?.let {
return aliveWithOpts.firstOrNull()?.check { daemonJVMOptions memorywiseFitsInto it.second.get() }?.let {
Pair(it.first, optsCopy.updateMemoryUpperBounds(it.second.get()))
}
// else combine all options from running daemon to get fattest option for a new daemon to run

View File

@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.io.BufferedOutputStream
import java.io.File
import java.io.PrintStream
@@ -347,7 +347,7 @@ class CompileServiceImpl(
if (fattestOpts memorywiseFitsInto daemonJVMOptions && !(daemonJVMOptions memorywiseFitsInto fattestOpts)) {
// all others are smaller that me, take overs' clients and shut them down
aliveWithOpts.forEach {
it.first.getClients().satisfying { it.isGood }?.let {
it.first.getClients().check { it.isGood }?.let {
it.get().forEach { registerClient(it) }
}
it.first.scheduleShutdown(true)
@@ -357,7 +357,7 @@ class CompileServiceImpl(
// there is at least one bigger, handover my clients to it and shutdown
scheduleShutdown(true)
aliveWithOpts.first().first.let { fattest ->
getClients().satisfying { it.isGood }?.let {
getClients().check { it.isGood }?.let {
it.get().forEach { fattest.registerClient(it) }
}
}

View File

@@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.jvm.bindingContextSlices.RUNTIME_ASSERTION_INFO
import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
@@ -74,9 +75,6 @@ class RuntimeAssertionInfo(val needNotNullAssertion: Boolean, val message: Strin
else
null
}
private fun KotlinType.hasEnhancedNullability()
= annotations.findAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION) != null
}
}

View File

@@ -17,6 +17,9 @@
package org.jetbrains.kotlin.load.java.sam;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor;
@@ -31,6 +34,30 @@ import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor;
setHasSynthesizedParameterNames(declaration.hasSynthesizedParameterNames());
}
private SamAdapterConstructorDescriptor(
@NotNull ClassDescriptor containingDeclaration,
@Nullable JavaConstructorDescriptor original,
@NotNull Annotations annotations,
boolean isPrimary,
@NotNull Kind kind,
@NotNull SourceElement source,
@NotNull JavaConstructorDescriptor declaration
) {
super(containingDeclaration, original, annotations, isPrimary, kind, source);
this.declaration = declaration;
}
@NotNull
@Override
protected JavaConstructorDescriptor createDescriptor(
@NotNull ClassDescriptor newOwner,
@Nullable JavaConstructorDescriptor original,
@NotNull Kind kind,
@NotNull SourceElement sourceElement
) {
return new SamAdapterConstructorDescriptor(newOwner, original, getAnnotations(), isPrimary, kind, sourceElement, declaration);
}
@NotNull
@Override
public JavaConstructorDescriptor getOriginForSam() {

View File

@@ -117,7 +117,7 @@ public class SamAdapterOverridabilityCondition implements ExternalOverridability
return new SamAdapterInfo(samAdapter, ownerType);
}
for (CallableMemberDescriptor overridden : samAdapter.getOverriddenDescriptors()) {
for (CallableMemberDescriptor overridden : samAdapter.getOriginal().getOverriddenDescriptors()) {
ClassDescriptor containingClass = (ClassDescriptor) overridden.getContainingDeclaration();
for (KotlinType immediateSupertype : TypeUtils.getImmediateSupertypes(ownerType)) {

View File

@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.replace
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
// If type 'samType' contains no projection, then it's non-projection parametrization is 'samType' itself
// Else each projection type argument 'out/in A_i' (but star projections) is replaced with it's bound 'A_i'
@@ -43,7 +43,7 @@ internal fun nonProjectionParametrization(samType: KotlinType): KotlinType? {
projection.projectionKind == Variance.INVARIANT -> projection
projection.isStarProjection ->
parameter.upperBounds.first().satisfying {
parameter.upperBounds.first().check {
t -> !t.contains { it.constructor.declarationDescriptor in parametersSet }
}?.asTypeProjection() ?: return@nonProjectionParametrization null

View File

@@ -49,10 +49,6 @@ object PackagePartClassUtils {
else
"_$str"
@TestOnly
@JvmStatic fun getDefaultFileClassFqName(packageFqName: FqName, file: VirtualFile): FqName =
getPackagePartFqName(packageFqName, file.name)
@TestOnly
@JvmStatic fun getDefaultPartFqName(facadeClassFqName: FqName, file: VirtualFile): FqName =
getPackagePartFqName(facadeClassFqName.parent(), file.name)

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.jvm
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
@@ -40,12 +41,14 @@ object JvmOverloadFilter : OverloadFilter {
}
for (overload in overloads) {
if (overload is ConstructorDescriptor) continue
if (overload !is DeserializedCallableMemberDescriptor) continue
val containingDeclaration = overload.containingDeclaration
if (containingDeclaration !is PackageFragmentDescriptor) {
throw AssertionError("Package member expected; got $overload with containing declaration $containingDeclaration")
}
val implClassName = JvmFileClassUtil.getImplClassName(overload) ?:
throw AssertionError("No implClassName: $overload")
val implClassFQN = containingDeclaration.fqName.child(implClassName)

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.jvm.checkers
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtProperty
@@ -28,11 +29,14 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
class JvmSyntheticApplicabilityChecker : DeclarationChecker {
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink, bindingContext: BindingContext
override fun check(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
val annotation = descriptor.findJvmSyntheticAnnotation() ?: return
if (declaration is KtProperty && declaration.hasDelegate()) {
if (declaration is KtProperty && descriptor is VariableDescriptor && declaration.hasDelegate()) {
val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(annotation) ?: return
diagnosticHolder.report(ErrorsJvm.JVM_SYNTHETIC_ON_DELEGATE.on(annotationEntry))
}

View File

@@ -99,7 +99,12 @@ class PlatformStaticAnnotationChecker : DeclarationChecker {
}
class JvmNameAnnotationChecker : DeclarationChecker {
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink, bindingContext: BindingContext) {
override fun check(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
val platformNameAnnotation = DescriptorUtils.getJvmNameAnnotation(descriptor)
if (platformNameAnnotation != null) {
checkDeclaration(descriptor, platformNameAnnotation, diagnosticHolder)

View File

@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
import org.jetbrains.kotlin.load.java.typeEnhancement.enhanceSignature
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
@@ -47,9 +46,7 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : SyntheticScope
if (!function.hasJavaOriginInHierarchy()) return null //TODO: should we go into base at all?
if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null
if (function.returnType == null) return null
//TODO: it's a temporary hack while original returns a function with platform types
val enhancedFunction = function.enhanceSignature()
return MyFunctionDescriptor.create(enhancedFunction)
return MyFunctionDescriptor.create(function)
}
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {

View File

@@ -98,7 +98,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
}
private fun doGetDescriptorForModule(moduleInfo: M): ModuleDescriptorImpl {
return descriptorByModule[moduleInfo] ?: return delegateResolver.descriptorForModule(moduleInfo) as ModuleDescriptorImpl
return descriptorByModule[moduleInfo] ?: delegateResolver.descriptorForModule(moduleInfo) as ModuleDescriptorImpl
}
}
@@ -114,7 +114,7 @@ interface ModuleInfo {
get() = false
val name: Name
fun dependencies(): List<ModuleInfo>
fun friends(): Collection<ModuleInfo> = listOf()
fun modulesWhoseInternalsAreVisible(): Collection<ModuleInfo> = listOf()
fun dependencyOnBuiltins(): DependencyOnBuiltins = DependenciesOnBuiltins.LAST
val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
get() = emptyMap()
@@ -193,8 +193,8 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
modules.forEach {
module ->
val descriptor = resolverForProject.descriptorForModule(module)
module.friends().forEach {
descriptor.addFriend(resolverForProject.descriptorForModule(it as M))
module.modulesWhoseInternalsAreVisible().forEach {
resolverForProject.descriptorForModule(it as M).addFriend(descriptor)
}
}
}
@@ -249,4 +249,4 @@ private class DelegatingPackageFragmentProvider(
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
return delegate().getSubPackagesOf(fqName, nameFilter)
}
}
}

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.cfg;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -53,7 +52,6 @@ import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.idea.MainFunctionDetector;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
@@ -65,14 +63,12 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
import java.util.*;
import static org.jetbrains.kotlin.cfg.VariableUseState.*;
import static org.jetbrains.kotlin.cfg.TailRecursionKind.*;
import static org.jetbrains.kotlin.cfg.VariableUseState.*;
import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.diagnostics.Errors.UNREACHABLE_CODE;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.types.TypeUtils.DONT_CARE;
import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
import static org.jetbrains.kotlin.types.TypeUtils.*;
public class ControlFlowInformationProvider {
@@ -360,6 +356,14 @@ public class ControlFlowInformationProvider {
}
}
private boolean isDefinitelyInitialized(@NotNull PropertyDescriptor propertyDescriptor) {
if (propertyDescriptor.isLateInit()) return true;
if (trace.get(BACKING_FIELD_REQUIRED, propertyDescriptor) == Boolean.TRUE) return false;
PsiElement property = DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor);
if (property instanceof KtProperty && ((KtProperty) property).hasDelegate()) return false;
return true;
}
private void checkIsInitialized(
@NotNull VariableInitContext ctxt,
@NotNull KtElement element,
@@ -370,11 +374,8 @@ public class ControlFlowInformationProvider {
boolean isDefinitelyInitialized = ctxt.exitInitState.definitelyInitialized();
VariableDescriptor variableDescriptor = ctxt.variableDescriptor;
if (variableDescriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
if (propertyDescriptor.isLateInit() || !trace.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
isDefinitelyInitialized = true;
}
if (!isDefinitelyInitialized && variableDescriptor instanceof PropertyDescriptor) {
isDefinitelyInitialized = isDefinitelyInitialized((PropertyDescriptor) variableDescriptor);
}
if (!isDefinitelyInitialized && !varWithUninitializedErrorGenerated.contains(variableDescriptor)) {
if (!(variableDescriptor instanceof PropertyDescriptor)) {
@@ -684,15 +685,32 @@ public class ControlFlowInformationProvider {
? ((InstructionWithValue) instruction).getOutputValue()
: null;
Pseudocode pseudocode = instruction.getOwner();
boolean isUsedAsExpression = !pseudocode.getUsages(value).isEmpty();
List<Instruction> usages = pseudocode.getUsages(value);
boolean isUsedAsExpression = !usages.isEmpty();
boolean isUsedAsResultOfLambda = isUsedAsResultOfLambda(usages);
for (KtElement element : pseudocode.getValueElements(value)) {
trace.record(BindingContext.USED_AS_EXPRESSION, element, isUsedAsExpression);
trace.record(BindingContext.USED_AS_RESULT_OF_LAMBDA, element, isUsedAsResultOfLambda);
}
}
}
);
}
private static boolean isUsedAsResultOfLambda(List<Instruction> usages) {
for (Instruction usage : usages) {
if (usage instanceof ReturnValueInstruction) {
KtElement returnElement = ((ReturnValueInstruction) usage).getElement();
PsiElement parentElement = returnElement.getParent();
if (!(returnElement instanceof KtReturnExpression ||
parentElement instanceof KtDeclaration && !(parentElement instanceof KtFunctionLiteral))) {
return true;
}
}
}
return false;
}
public void checkIfExpressions() {
PseudocodeTraverserKt.traverse(
pseudocode, TraversalOrder.FORWARD, new ControlFlowInformationProvider.FunctionVoid1<Instruction>() {
@@ -713,7 +731,7 @@ public class ControlFlowInformationProvider {
trace.report(INVALID_IF_AS_EXPRESSION.on(ifExpression));
}
else {
checkImplicitCastOnConditionalExpression(ifExpression, ImmutableList.of(thenExpression, elseExpression));
checkImplicitCastOnConditionalExpression(ifExpression);
}
}
}
@@ -722,10 +740,41 @@ public class ControlFlowInformationProvider {
);
}
private void checkImplicitCastOnConditionalExpression(
@NotNull KtExpression expression,
@NotNull Collection<KtExpression> branchExpressions
private static List<KtExpression> collectResultingExpressionsOfConditionalExpression(KtExpression expression) {
List<KtExpression> leafBranches = new ArrayList<KtExpression>();
collectResultingExpressionsOfConditionalExpressionRec(expression, leafBranches);
return leafBranches;
}
private static void collectResultingExpressionsOfConditionalExpressionRec(
@Nullable KtExpression expression,
@NotNull List<KtExpression> resultingExpressions
) {
if (expression instanceof KtIfExpression) {
KtIfExpression ifExpression = (KtIfExpression) expression;
collectResultingExpressionsOfConditionalExpressionRec(ifExpression.getThen(), resultingExpressions);
collectResultingExpressionsOfConditionalExpressionRec(ifExpression.getElse(), resultingExpressions);
}
else if (expression instanceof KtWhenExpression) {
KtWhenExpression whenExpression = (KtWhenExpression) expression;
for (KtWhenEntry whenEntry : whenExpression.getEntries()) {
collectResultingExpressionsOfConditionalExpressionRec(whenEntry.getExpression(), resultingExpressions);
}
}
else if (expression != null){
KtExpression resultingExpression = getResultingExpression(expression);
if (resultingExpression instanceof KtIfExpression || resultingExpression instanceof KtWhenExpression) {
collectResultingExpressionsOfConditionalExpressionRec(resultingExpression, resultingExpressions);
}
else {
resultingExpressions.add(resultingExpression);
}
}
}
private void checkImplicitCastOnConditionalExpression(@NotNull KtExpression expression) {
Collection<KtExpression> branchExpressions = collectResultingExpressionsOfConditionalExpression(expression);
KotlinType expectedExpressionType = trace.get(EXPECTED_EXPRESSION_TYPE, expression);
if (expectedExpressionType != null && expectedExpressionType != DONT_CARE) return;
@@ -734,10 +783,13 @@ public class ControlFlowInformationProvider {
return;
}
if (KotlinBuiltIns.isAnyOrNullableAny(expressionType)) {
boolean isUsedAsResultOfLambda = BindingContextUtilsKt.isUsedAsResultOfLambda(expression, trace.getBindingContext());
for (KtExpression branchExpression : branchExpressions) {
if (branchExpression == null) continue;
KotlinType branchType = trace.getType(branchExpression);
if (branchType == null || KotlinBuiltIns.isAnyOrNullableAny(branchType)) {
if (branchType == null
|| KotlinBuiltIns.isAnyOrNullableAny(branchType)
|| (isUsedAsResultOfLambda && KotlinBuiltIns.isUnitOrNullableUnit(branchType))) {
return;
}
}
@@ -793,11 +845,7 @@ public class ControlFlowInformationProvider {
KtWhenExpression whenExpression = (KtWhenExpression) element;
if (BindingContextUtilsKt.isUsedAsExpression(whenExpression, trace.getBindingContext())) {
List<KtExpression> branchExpressions = new ArrayList<KtExpression>(whenExpression.getEntries().size());
for (KtWhenEntry whenEntry : whenExpression.getEntries()) {
branchExpressions.add(whenEntry.getExpression());
}
checkImplicitCastOnConditionalExpression(whenExpression, branchExpressions);
checkImplicitCastOnConditionalExpression(whenExpression);
}
if (whenExpression.getElseExpression() != null) continue;

View File

@@ -947,10 +947,19 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
mark(expression)
val selectorExpression = expression.selectorExpression
val receiverExpression = expression.receiverExpression
val safe = expression is KtSafeQualifiedExpression
// todo: replace with selectorExpresion != null after parser is fixed
if (selectorExpression is KtCallExpression || selectorExpression is KtSimpleNameExpression) {
generateInstructions(selectorExpression)
if (!safe) {
generateInstructions(selectorExpression)
}
else {
val resultLabel = builder.createUnboundLabel("result of call")
builder.jumpOnFalse(resultLabel, expression, null)
generateInstructions(selectorExpression)
builder.bindLabel(resultLabel)
}
copyValue(selectorExpression, expression)
}
else {
@@ -1001,6 +1010,8 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
}
val delegate = property.delegateExpression
if (delegate != null) {
// We do not want to have getDeferredValue(delegate) here, because delegate value will be read anyway later
visitAssignment(property, getDeferredValue(null), property)
generateInstructions(delegate)
if (builder.getBoundValue(delegate) != null) {
createSyntheticValue(property, MagicKind.VALUE_CONSUMER, delegate)

View File

@@ -17,13 +17,13 @@
package org.jetbrains.kotlin.cfg.pseudocodeTraverser
import org.jetbrains.kotlin.cfg.ControlFlowInfo
import org.jetbrains.kotlin.cfg.pseudocode.*
import java.util.*
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder.FORWARD
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.SubroutineSinkInstruction
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.LocalFunctionDeclarationInstruction
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.LocalFunctionDeclarationInstruction
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.SubroutineEnterInstruction
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.SubroutineSinkInstruction
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder.FORWARD
import java.util.*
fun Pseudocode.traverse(
traversalOrder: TraversalOrder,
@@ -109,26 +109,7 @@ private fun <I : ControlFlowInfo<*>> Pseudocode.collectDataFromSubgraph(
if (!isLocal && isStart)
continue
fun getPreviousIncludingSubGraphInstructions(): Collection<Instruction> {
val previous = instruction.getPreviousInstructions(traversalOrder)
if (instruction != startInstruction || previousSubGraphInstructions.isEmpty()) {
return previous
}
val result = ArrayList(previous)
result.addAll(previousSubGraphInstructions)
return result
}
val previousInstructions = getPreviousIncludingSubGraphInstructions()
fun updateEdgeDataForInstruction(
previousValue: Edges<I>?,
newValue: Edges<I>?
) {
if (previousValue != newValue && newValue != null) {
changed[0] = true
edgesMap.put(instruction, newValue)
}
}
val previousInstructions = getPreviousIncludingSubGraphInstructions(instruction, traversalOrder, startInstruction, previousSubGraphInstructions)
if (instruction is LocalFunctionDeclarationInstruction) {
val subroutinePseudocode = instruction.body
@@ -146,7 +127,7 @@ private fun <I : ControlFlowInfo<*>> Pseudocode.collectDataFromSubgraph(
else
Edges(updateEdge(lastInstruction, instruction, newValue.incoming),
updateEdge(lastInstruction, instruction, newValue.outgoing))
updateEdgeDataForInstruction(previousValue, updatedValue)
updateEdgeDataForInstruction(instruction, previousValue, updatedValue, edgesMap, changed)
continue
}
}
@@ -162,7 +143,30 @@ private fun <I : ControlFlowInfo<*>> Pseudocode.collectDataFromSubgraph(
}
}
val mergedData = mergeEdges(instruction, incomingEdgesData)
updateEdgeDataForInstruction(previousDataValue, mergedData)
updateEdgeDataForInstruction(instruction, previousDataValue, mergedData, edgesMap, changed)
}
}
private fun getPreviousIncludingSubGraphInstructions(
instruction: Instruction,
traversalOrder: TraversalOrder,
startInstruction: Instruction,
previousSubGraphInstructions: Collection<Instruction>
): Collection<Instruction> {
val previous = instruction.getPreviousInstructions(traversalOrder)
if (instruction != startInstruction || previousSubGraphInstructions.isEmpty()) {
return previous
}
val result = ArrayList(previous)
result.addAll(previousSubGraphInstructions)
return result
}
private fun <I : ControlFlowInfo<*>> updateEdgeDataForInstruction(
instruction: Instruction, previousValue: Edges<I>?, newValue: Edges<I>?, edgesMap: MutableMap<Instruction, Edges<I>>, changed: BooleanArray) {
if (previousValue != newValue && newValue != null) {
changed[0] = true
edgesMap.put(instruction, newValue)
}
}

View File

@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.varianceChecker.VarianceChecker.VarianceConflictDiagnosticData;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeProjection;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -297,7 +296,7 @@ public interface Errors {
// Members
DiagnosticFactory2<KtDeclaration, CallableMemberDescriptor, String> CONFLICTING_OVERLOADS =
DiagnosticFactory2<KtDeclaration, CallableMemberDescriptor, DeclarationDescriptor> CONFLICTING_OVERLOADS =
DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<KtNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticFactory0.create(WARNING, modifierSetPosition(
@@ -547,6 +546,7 @@ public interface Errors {
DiagnosticFactory0<KtDestructuringDeclaration> INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION = DiagnosticFactory0.create(ERROR, DEFAULT);
DiagnosticFactory2<KtExpression, Name, KotlinType> COMPONENT_FUNCTION_MISSING = DiagnosticFactory2.create(ERROR, DEFAULT);
DiagnosticFactory1<KtExpression, Name> COMPONENT_FUNCTION_ON_NULLABLE = DiagnosticFactory1.create(ERROR, DEFAULT);
DiagnosticFactory2<KtExpression, Name, Collection<? extends ResolvedCall<?>>> COMPONENT_FUNCTION_AMBIGUITY = DiagnosticFactory2.create(ERROR, DEFAULT);
DiagnosticFactory3<KtExpression, Name, KotlinType, KotlinType> COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR, DEFAULT);
@@ -589,6 +589,7 @@ public interface Errors {
DiagnosticFactory1<KtExpression, KotlinType> NEXT_NONE_APPLICABLE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<KtExpression> ITERATOR_MISSING = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtExpression> ITERATOR_ON_NULLABLE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> ITERATOR_AMBIGUITY = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<KtExpression, String, KotlinType> DELEGATE_SPECIAL_FUNCTION_MISSING = DiagnosticFactory2.create(ERROR);
@@ -771,7 +772,8 @@ public interface Errors {
DiagnosticFactory0<KtClass> NESTED_CLASS_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
//Inline and inlinable parameters
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> NON_PUBLIC_CALL_FROM_PUBLIC_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> PRIVATE_CLASS_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
DiagnosticFactory1<KtElement, KtElement> NON_LOCAL_RETURN_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, CALL_ELEMENT);
DiagnosticFactory2<KtElement, KtNamedDeclaration, DeclarationDescriptor> NOT_YET_SUPPORTED_IN_INLINE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory1<PsiElement, DeclarationDescriptor> NOTHING_TO_INLINE = DiagnosticFactory1.create(WARNING);
@@ -787,7 +789,7 @@ public interface Errors {
ImmutableSet<? extends DiagnosticFactory<?>> UNRESOLVED_REFERENCE_DIAGNOSTICS = ImmutableSet.of(
UNRESOLVED_REFERENCE, NAMED_PARAMETER_NOT_FOUND, UNRESOLVED_REFERENCE_WRONG_RECEIVER);
ImmutableSet<? extends DiagnosticFactory<?>> INVISIBLE_REFERENCE_DIAGNOSTICS = ImmutableSet.of(
INVISIBLE_MEMBER, INVISIBLE_MEMBER_FROM_INLINE, INVISIBLE_REFERENCE, INVISIBLE_SETTER);
INVISIBLE_MEMBER, NON_PUBLIC_CALL_FROM_PUBLIC_INLINE, INVISIBLE_REFERENCE, INVISIBLE_SETTER);
ImmutableSet<? extends DiagnosticFactory<?>> UNUSED_ELEMENT_DIAGNOSTICS = ImmutableSet.of(
UNUSED_VARIABLE, UNUSED_PARAMETER, ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE, VARIABLE_WITH_REDUNDANT_INITIALIZER,
UNUSED_LAMBDA_EXPRESSION, USELESS_CAST, UNUSED_VALUE, USELESS_ELVIS);

View File

@@ -61,7 +61,9 @@ fun ResolutionContext<*>.reportTypeMismatchDueToTypeProjection(
is CallPosition.Unknown -> return false
}
val receiverType = resolvedCall.dispatchReceiver?.type ?: return false
val receiverType = resolvedCall.smartCastDispatchReceiverType
?: (resolvedCall.dispatchReceiver ?: return false).type
val callableDescriptor = resolvedCall.resultingDescriptor.original
val substitutedDescriptor =

View File

@@ -214,6 +214,7 @@ public class DefaultErrorMessages {
MAP.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration");
MAP.put(COMPONENT_FUNCTION_MISSING, "Destructuring declaration initializer of type {1} must have a ''{0}()'' function", TO_STRING, RENDER_TYPE);
MAP.put(COMPONENT_FUNCTION_ON_NULLABLE, "Not nullable value required to call ''{0}()'' function of destructuring declaration initializer", TO_STRING);
MAP.put(COMPONENT_FUNCTION_AMBIGUITY, "Function ''{0}()'' is ambiguous for this expression: {1}", TO_STRING, AMBIGUOUS_CALLS);
MAP.put(COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, "''{0}()'' function returns ''{1}'', but ''{2}'' is expected",
TO_STRING, RENDER_TYPE, RENDER_TYPE);
@@ -368,6 +369,7 @@ public class DefaultErrorMessages {
MAP.put(NEXT_NONE_APPLICABLE, "None of the next() functions is applicable for iterator() of type ''{0}''", RENDER_TYPE);
MAP.put(ITERATOR_MISSING, "For-loop range must have an iterator() method");
MAP.put(ITERATOR_ON_NULLABLE, "Not nullable value required to call an iterator() method on for-loop range");
MAP.put(ITERATOR_AMBIGUITY, "Method ''iterator()'' is ambiguous for this expression: {0}", AMBIGUOUS_CALLS);
MAP.put(DELEGATE_SPECIAL_FUNCTION_MISSING, "Missing ''{0}'' method on delegate of type ''{1}''", STRING, RENDER_TYPE);
@@ -609,7 +611,8 @@ public class DefaultErrorMessages {
MAP.put(MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, "{0} must override {1} because it inherits multiple interface methods of it",
RENDER_CLASS_OR_OBJECT, FQ_NAMES_IN_TYPES);
MAP.put(CONFLICTING_OVERLOADS, "''{0}'' is already defined in {1}", COMPACT_WITH_MODIFIERS, STRING);
MAP.put(CONFLICTING_OVERLOADS, "''{0}'' conflicts with another declaration in {1}", COMPACT_WITH_MODIFIERS,
DECLARATION_NAME_WITH_KIND);
MAP.put(FUNCTION_EXPECTED, "Expression ''{0}''{1} cannot be invoked as a function. " +
"The function '" + OperatorNameConventions.INVOKE.asString() + "()' is not found",
@@ -730,7 +733,8 @@ public class DefaultErrorMessages {
MAP.put(ARRAY_CLASS_LITERAL_REQUIRES_ARGUMENT, "kotlin.Array class literal requires a type argument, please specify one in angle brackets");
//Inline
MAP.put(INVISIBLE_MEMBER_FROM_INLINE, "Public-API inline function cannot access non-public-API ''{0}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(NON_PUBLIC_CALL_FROM_PUBLIC_INLINE, "Public-API inline function cannot access non-public-API ''{0}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(PRIVATE_CLASS_MEMBER_FROM_INLINE, "Non-private inline function cannot access members of private classes: ''{0}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(NOT_YET_SUPPORTED_IN_INLINE, "''{0}'' construction is not yet supported in inline functions", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(DECLARATION_CANT_BE_INLINED, "''inline'' modifier is not allowed on virtual members. Only private or final members can be inlined");
MAP.put(NOTHING_TO_INLINE, "Expected performance impact of inlining ''{0}'' can be insignificant. Inlining works best for functions with lambda parameters", SHORT_NAMES_IN_TYPES);

View File

@@ -76,6 +76,19 @@ object Renderers {
@JvmField val NAME: Renderer<Named> = Renderer { it.name.asString() }
@JvmField val DECLARATION_NAME_WITH_KIND: Renderer<DeclarationDescriptor> = Renderer {
val declarationKindWithSpace = when (it) {
is PackageFragmentDescriptor -> "package "
is ClassDescriptor -> "${it.renderKind()} "
is ConstructorDescriptor -> "constructor "
is PropertyGetterDescriptor -> "property getter "
is PropertySetterDescriptor -> "property setter "
is FunctionDescriptor -> "function "
else -> throw AssertionError("Unexpected declaration kind: $it")
}
"$declarationKindWithSpace'${it.name.asString()}'"
}
@JvmField val NAME_OF_PARENT_OR_FILE: Renderer<DeclarationDescriptor> = Renderer {
if (DescriptorUtils.isTopLevelDeclaration(it) && it is DeclarationDescriptorWithVisibility && it.visibility == Visibilities.PRIVATE) {
"file"

View File

@@ -26,7 +26,7 @@ import com.intellij.psi.tree.IElementType
import com.intellij.testFramework.LightVirtualFile
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.util.*
abstract class KtCodeFragment(
@@ -146,7 +146,7 @@ abstract class KtCodeFragment(
private fun initImports(imports: String?) {
if (imports != null && !imports.isEmpty()) {
this.imports.addAll(imports.split(IMPORT_SEPARATOR).map { it.satisfying { it.startsWith("import ") } ?: "import $it" })
this.imports.addAll(imports.split(IMPORT_SEPARATOR).map { it.check { it.startsWith("import ") } ?: "import $it" })
}
}

View File

@@ -18,12 +18,23 @@ package org.jetbrains.kotlin.psi.codeFragmentUtil
import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.types.KotlinType
val SUPPRESS_DIAGNOSTICS_IN_DEBUG_MODE: Key<Boolean> = Key.create<Boolean>("SUPPRESS_DIAGNOSTICS_IN_DEBUG_MODE")
fun KtElement.suppressDiagnosticsInDebugMode(): Boolean {
return if (this is KtFile) {
this.suppressDiagnosticsInDebugMode
}
else {
val file = this.containingFile
file is KtFile && file.suppressDiagnosticsInDebugMode
}
}
var KtFile.suppressDiagnosticsInDebugMode: Boolean
get() = when (this) {
is KtCodeFragment -> true

View File

@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ErrorValue
import org.jetbrains.kotlin.resolve.inline.InlineUtil
private val JVM_STATIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmStatic")
@@ -69,5 +70,8 @@ private val INLINE_ONLY_ANNOTATION_FQ_NAME = FqName("kotlin.internal.InlineOnly"
fun MemberDescriptor.isInlineOnly(): Boolean {
if (this !is FunctionDescriptor) return false
return typeParameters.any { it.isReified } || annotations.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)
return typeParameters.any { it.isReified } ||
annotations.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) && InlineUtil.isInline(this).apply {
assert(this) { "Function is not inline: ${this@isInlineOnly}"; }
}
}

View File

@@ -149,6 +149,7 @@ public interface BindingContext {
*/
WritableSlice<KtExpression, Boolean> PROCESSED = Slices.createSimpleSetSlice();
WritableSlice<KtElement, Boolean> USED_AS_EXPRESSION = Slices.createSimpleSetSlice();
WritableSlice<KtElement, Boolean> USED_AS_RESULT_OF_LAMBDA = Slices.createSimpleSetSlice();
WritableSlice<KtElement, Boolean> UNREACHABLE_CODE = Slices.createSimpleSetSlice();
WritableSlice<VariableDescriptor, CaptureKind> CAPTURED_IN_CLOSURE = new BasicWritableSlice<VariableDescriptor, CaptureKind>(DO_NOTHING);

View File

@@ -25,7 +25,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.diagnostics.Severity;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
@@ -39,8 +38,6 @@ import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
import org.jetbrains.kotlin.util.slicedMap.*;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
import static org.jetbrains.kotlin.diagnostics.Errors.AMBIGUOUS_LABEL;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
@@ -223,7 +220,7 @@ public class BindingContextUtils {
map.forEach(new Function3<WritableSlice, Object, Object, Void>() {
@Override
public Void invoke(WritableSlice slice, Object key, Object value) {
if (filter == null || filter.accept(slice, null, key)) {
if (filter == null || filter.accept(slice, key)) {
trace.record(slice, key, value);
}
@@ -234,7 +231,7 @@ public class BindingContextUtils {
if (!commitDiagnostics) return;
for (Diagnostic diagnostic : diagnostics.getOwnDiagnostics()) {
if (filter == null || filter.accept(null, diagnostic, diagnostic.getPsiElement())) {
if (filter == null || filter.accept(null, diagnostic.getPsiElement())) {
trace.report(diagnostic);
}
}

View File

@@ -55,6 +55,7 @@ fun KtReturnExpression.getTargetFunction(context: BindingContext): KtCallableDec
}
fun KtExpression.isUsedAsExpression(context: BindingContext): Boolean = context[BindingContext.USED_AS_EXPRESSION, this]!!
fun KtExpression.isUsedAsResultOfLambda(context: BindingContext): Boolean = context[BindingContext.USED_AS_RESULT_OF_LAMBDA, this]!!
fun KtExpression.isUsedAsStatement(context: BindingContext): Boolean = !isUsedAsExpression(context)

View File

@@ -727,12 +727,16 @@ class DeclarationsChecker(
}
private fun checkAccessors(property: KtProperty, propertyDescriptor: PropertyDescriptor) {
for (accessor in property.accessors) {
val propertyAccessorDescriptor = (if (accessor.isGetter) propertyDescriptor.getter else propertyDescriptor.setter)
?: throw AssertionError("No property accessor descriptor for ${property.text}")
accessor.checkTypeReferences()
modifiersChecker.checkModifiersForDeclaration(accessor, propertyAccessorDescriptor)
identifierChecker.checkDeclaration(accessor, trace)
for (accessorDescriptor in propertyDescriptor.accessors) {
val accessor = if (accessorDescriptor is PropertyGetterDescriptor) property.getter else property.setter
if (accessor != null) {
accessor.checkTypeReferences()
modifiersChecker.checkModifiersForDeclaration(accessor, accessorDescriptor)
identifierChecker.checkDeclaration(accessor, trace)
}
else {
modifiersChecker.runDeclarationCheckers(property, accessorDescriptor)
}
}
checkAccessor(propertyDescriptor, property.getter, propertyDescriptor.getter)
checkAccessor(propertyDescriptor, property.setter, propertyDescriptor.setter)

View File

@@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.diagnostics.rendering.Renderers;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
@@ -334,7 +333,7 @@ public class DelegatedPropertyResolver {
dataFlowInfo, traceToResolveDelegatedProperty);
traceToResolveDelegatedProperty.commit(new TraceEntryFilter() {
@Override
public boolean accept(@Nullable WritableSlice<?, ?> slice, @Nullable Diagnostic diagnostic, Object key) {
public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
return slice != CONSTRAINT_SYSTEM_COMPLETER;
}
}, true);

View File

@@ -228,7 +228,10 @@ public class ModifiersChecker {
}
private void runDeclarationCheckers(@NotNull KtDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
public void runDeclarationCheckers(
@NotNull KtDeclaration declaration,
@NotNull DeclarationDescriptor descriptor
) {
for (DeclarationChecker checker : declarationCheckers) {
checker.check(declaration, descriptor, trace, trace.getBindingContext());
}

View File

@@ -28,11 +28,10 @@ import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
public class OverloadResolver {
@NotNull private final BindingTrace trace;
@NotNull private final OverloadFilter overloadFilter;
@@ -50,72 +49,51 @@ public class OverloadResolver {
}
private void checkOverloads(@NotNull BodiesResolveContext c) {
MultiMap<ClassDescriptor, ConstructorDescriptor> inClasses = MultiMap.create();
MultiMap<FqNameUnsafe, ConstructorDescriptor> inPackages = MultiMap.create();
fillGroupedConstructors(c, inClasses, inPackages);
MultiMap<ClassDescriptor, ConstructorDescriptor> inClasses = findConstructorsInNestedClasses(c);
for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
checkOverloadsInAClass(entry.getValue(), entry.getKey(), inClasses.get(entry.getValue()));
checkOverloadsInAClass(entry.getValue(), inClasses.get(entry.getValue()));
}
checkOverloadsInPackages(c, inPackages);
checkOverloadsInPackages(c);
}
private static void fillGroupedConstructors(
@NotNull BodiesResolveContext c,
@NotNull MultiMap<ClassDescriptor, ConstructorDescriptor> inClasses,
@NotNull MultiMap<FqNameUnsafe, ConstructorDescriptor> inPackages
) {
private static MultiMap<ClassDescriptor, ConstructorDescriptor> findConstructorsInNestedClasses(@NotNull BodiesResolveContext c) {
MultiMap<ClassDescriptor, ConstructorDescriptor> inClasses = MultiMap.create();
for (ClassDescriptorWithResolutionScopes klass : c.getDeclaredClasses().values()) {
if (klass.getKind().isSingleton() || klass.getName().isSpecial()) {
// Constructors of singletons or anonymous object aren't callable from the code, so they shouldn't participate in overload name checking
continue;
}
DeclarationDescriptor containingDeclaration = klass.getContainingDeclaration();
if (containingDeclaration instanceof ClassDescriptor) {
if (containingDeclaration instanceof ScriptDescriptor) {
// TODO: check overload conflicts of functions with constructors in scripts
}
else if (containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
inClasses.putValues(classDescriptor, klass.getConstructors());
}
else if (containingDeclaration instanceof PackageFragmentDescriptor) {
inPackages.putValues(getFqName(klass), klass.getConstructors());
}
else if (containingDeclaration instanceof ScriptDescriptor) {
// TODO: check overload conflicts of functions with constructors in scripts
}
else if (!(containingDeclaration instanceof FunctionDescriptor || containingDeclaration instanceof PropertyDescriptor)) {
else if (!(containingDeclaration instanceof FunctionDescriptor ||
containingDeclaration instanceof PropertyDescriptor ||
containingDeclaration instanceof PackageFragmentDescriptor)) {
throw new IllegalStateException("Illegal class container: " + containingDeclaration);
}
}
return inClasses;
}
private void checkOverloadsInPackages(
@NotNull BodiesResolveContext c,
@NotNull MultiMap<FqNameUnsafe, ConstructorDescriptor> inPackages
) {
private void checkOverloadsInPackages(@NotNull BodiesResolveContext c) {
MultiMap<FqNameUnsafe, CallableMemberDescriptor> membersByName =
OverloadUtil.groupModulePackageMembersByFqName(c, inPackages, overloadFilter);
OverloadUtil.groupModulePackageMembersByFqName(c, overloadFilter);
for (Map.Entry<FqNameUnsafe, Collection<CallableMemberDescriptor>> e : membersByName.entrySet()) {
FqNameUnsafe fqName = e.getKey().parent();
checkOverloadsInPackage(e.getValue(), fqName);
checkOverloadsInPackage(e.getValue());
}
}
private static String nameForErrorMessage(ClassDescriptor classDescriptor, KtClassOrObject jetClass) {
String name = jetClass.getName();
if (name != null) {
return name;
}
if (jetClass instanceof KtObjectDeclaration) {
// must be companion object
name = classDescriptor.getContainingDeclaration().getName().asString();
return "companion object " + name;
}
// safe
return "<unknown>";
}
private void checkOverloadsInAClass(
ClassDescriptorWithResolutionScopes classDescriptor, KtClassOrObject klass,
ClassDescriptorWithResolutionScopes classDescriptor,
Collection<ConstructorDescriptor> nestedClassConstructors
) {
MultiMap<Name, CallableMemberDescriptor> functionsByName = MultiMap.create();
@@ -129,31 +107,24 @@ public class OverloadResolver {
}
for (Map.Entry<Name, Collection<CallableMemberDescriptor>> e : functionsByName.entrySet()) {
checkOverloadsInClass(e.getValue(), classDescriptor, klass);
checkOverloadsInClass(e.getValue());
}
}
private void checkOverloadsInPackage(
@NotNull Collection<CallableMemberDescriptor> members,
@NotNull FqNameUnsafe packageFQN
) {
private void checkOverloadsInPackage(@NotNull Collection<CallableMemberDescriptor> members) {
if (members.size() == 1) return;
for (Collection<? extends CallableMemberDescriptor> redeclarationGroup : OverloadUtil.getPossibleRedeclarationGroups(members)) {
Set<Pair<KtDeclaration, CallableMemberDescriptor>> redeclarations = findRedeclarations(redeclarationGroup);
// TODO: don't render FQ name here, extract this logic to somewhere
reportRedeclarations(packageFQN.isRoot() ? "root package" : packageFQN.asString(), redeclarations);
reportRedeclarations(redeclarations);
}
}
private void checkOverloadsInClass(
@NotNull Collection<CallableMemberDescriptor> members,
@NotNull ClassDescriptor classDescriptor,
@NotNull KtClassOrObject ktClass
) {
private void checkOverloadsInClass(@NotNull Collection<CallableMemberDescriptor> members) {
if (members.size() == 1) return;
reportRedeclarations(nameForErrorMessage(classDescriptor, ktClass), findRedeclarations(members));
reportRedeclarations(findRedeclarations(members));
}
@NotNull
@@ -171,9 +142,7 @@ public class OverloadResolver {
}
KtDeclaration ktDeclaration = (KtDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(member);
if (ktDeclaration != null) {
redeclarations.add(Pair.create(ktDeclaration, member));
}
redeclarations.add(Pair.create(ktDeclaration, member));
}
}
}
@@ -203,22 +172,38 @@ public class OverloadResolver {
return file == null || file2 == null || file != file2;
}
private void reportRedeclarations(@NotNull String functionContainer,
@NotNull Set<Pair<KtDeclaration, CallableMemberDescriptor>> redeclarations) {
private void reportRedeclarations(@NotNull Set<Pair<KtDeclaration, CallableMemberDescriptor>> redeclarations) {
if (redeclarations.isEmpty()) return;
Iterator<Pair<KtDeclaration, CallableMemberDescriptor>> redeclarationsIterator = redeclarations.iterator();
CallableMemberDescriptor firstRedeclarationDescriptor = redeclarationsIterator.next().getSecond();
CallableMemberDescriptor otherRedeclarationDescriptor = redeclarationsIterator.hasNext()
? redeclarationsIterator.next().getSecond()
: null;
for (Pair<KtDeclaration, CallableMemberDescriptor> redeclaration : redeclarations) {
KtDeclaration ktDeclaration = redeclaration.getFirst();
if (ktDeclaration == null) continue;
CallableMemberDescriptor memberDescriptor = redeclaration.getSecond();
KtDeclaration ktDeclaration = redeclaration.getFirst();
CallableMemberDescriptor redeclarationDescriptor;
if (otherRedeclarationDescriptor == null) {
redeclarationDescriptor = firstRedeclarationDescriptor;
}
else if (firstRedeclarationDescriptor == memberDescriptor) {
redeclarationDescriptor = otherRedeclarationDescriptor;
}
else {
redeclarationDescriptor = firstRedeclarationDescriptor;
}
if (memberDescriptor instanceof PropertyDescriptor) {
trace.report(Errors.REDECLARATION.on(ktDeclaration, memberDescriptor.getName().asString()));
}
else {
String containingClassName = ktDeclaration instanceof KtSecondaryConstructor ?
((KtSecondaryConstructor) ktDeclaration).getContainingClassOrObject().getName() : null;
trace.report(Errors.CONFLICTING_OVERLOADS.on(
ktDeclaration, memberDescriptor,
containingClassName != null ? containingClassName : functionContainer));
trace.report(Errors.CONFLICTING_OVERLOADS.on(ktDeclaration, memberDescriptor,
redeclarationDescriptor.getContainingDeclaration()));
}
}
}

View File

@@ -82,14 +82,18 @@ object OverloadUtil {
@JvmStatic fun groupModulePackageMembersByFqName(
c: BodiesResolveContext,
constructorsInPackages: MultiMap<FqNameUnsafe, ConstructorDescriptor>,
overloadFilter: OverloadFilter
): MultiMap<FqNameUnsafe, CallableMemberDescriptor> {
val packageMembersByName = MultiMap<FqNameUnsafe, CallableMemberDescriptor>()
collectModulePackageMembersWithSameName(packageMembersByName, c.functions.values, overloadFilter) {
collectModulePackageMembersWithSameName(packageMembersByName, c.functions.values + c.declaredClasses.values, overloadFilter) {
scope, name ->
scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
val functions = scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
val classifier = scope.getContributedClassifier(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
if (classifier is ClassDescriptor && !classifier.kind.isSingleton)
functions + classifier.constructors
else
functions
}
collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values, overloadFilter) {
@@ -97,15 +101,12 @@ object OverloadUtil {
scope.getContributedVariables(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS).filterIsInstance<CallableMemberDescriptor>()
}
// TODO handle constructor redeclarations in modules. See also: https://youtrack.jetbrains.com/issue/KT-3632
packageMembersByName.putAllValues(constructorsInPackages)
return packageMembersByName
}
private inline fun collectModulePackageMembersWithSameName(
packageMembersByName: MultiMap<FqNameUnsafe, CallableMemberDescriptor>,
interestingDescriptors: Collection<CallableMemberDescriptor>,
interestingDescriptors: Collection<DeclarationDescriptor>,
overloadFilter: OverloadFilter,
getMembersByName: (MemberScope, Name) -> Collection<CallableMemberDescriptor>
) {
@@ -123,20 +124,25 @@ object OverloadUtil {
}
private inline fun getModulePackageMembersWithSameName(
packageMember: CallableMemberDescriptor,
descriptor: DeclarationDescriptor,
overloadFilter: OverloadFilter,
getMembersByName: (MemberScope, Name) -> Collection<CallableMemberDescriptor>
): Collection<CallableMemberDescriptor> {
val containingPackage = packageMember.containingDeclaration
val containingPackage = descriptor.containingDeclaration
if (containingPackage !is PackageFragmentDescriptor) {
throw AssertionError("$packageMember is not a top-level package member")
throw AssertionError("$descriptor is not a top-level package member")
}
val containingModule = DescriptorUtils.getContainingModuleOrNull(packageMember) ?: return listOf(packageMember)
val containingModule = DescriptorUtils.getContainingModuleOrNull(descriptor) ?:
return when (descriptor) {
is CallableMemberDescriptor -> listOf(descriptor)
is ClassDescriptor -> descriptor.constructors
else -> throw AssertionError("Unexpected descriptor kind: $descriptor")
}
val containingPackageScope = containingModule.getPackage(containingPackage.fqName).memberScope
val possibleOverloads =
getMembersByName(containingPackageScope, packageMember.name).filter {
getMembersByName(containingPackageScope, descriptor.name).filter {
// NB memberScope for PackageViewDescriptor includes module dependencies
DescriptorUtils.getContainingModule(it) == containingModule
}

View File

@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator) {
@@ -90,7 +90,7 @@ class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator
val qualifier = resolveToPackageOrClass(
qualifierPartList.subList(0, qualifierPartList.size - 1), module,
trace, scope.ownerDescriptor, scope.satisfying { !userType.startWithPackage }, position = QualifierPosition.TYPE
trace, scope.ownerDescriptor, scope.check { !userType.startWithPackage }, position = QualifierPosition.TYPE
) ?: return TypeQualifierResolutionResult(qualifierPartList, null)
val lastPart = qualifierPartList.last()
@@ -194,7 +194,7 @@ class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator
}
val importedDescriptors = candidates.filter { isVisible(it, packageFragmentForVisibilityCheck, position = QualifierPosition.IMPORT) }.
satisfying { it.isNotEmpty() } ?: candidates
check { it.isNotEmpty() } ?: candidates
return SingleImportScope(aliasName, importedDescriptors)
}
@@ -410,14 +410,14 @@ class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator
val qualifierDescriptor = when {
receiver is PackageQualifier -> {
val childPackageFQN = receiver.packageView.fqName.child(name)
receiver.packageView.module.getPackage(childPackageFQN).satisfying { !it.isEmpty() } ?:
receiver.packageView.module.getPackage(childPackageFQN).check { !it.isEmpty() } ?:
receiver.packageView.memberScope.getContributedClassifier(name, KotlinLookupLocation(expression))
}
receiver is ClassQualifier ->
receiver.scope.getContributedClassifier(name, KotlinLookupLocation(expression))
receiver == null ->
context.scope.findClassifier(name, KotlinLookupLocation(expression)) ?:
context.scope.ownerDescriptor.module.getPackage(FqName.ROOT.child(name)).satisfying { !it.isEmpty() }
context.scope.ownerDescriptor.module.getPackage(FqName.ROOT.child(name)).check { !it.isEmpty() }
receiver is ReceiverValue ->
receiver.type.memberScope.memberScopeAsImportingScope().findClassifier(name, KotlinLookupLocation(expression))
else -> null

View File

@@ -17,9 +17,8 @@
package org.jetbrains.kotlin.resolve;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
public interface TraceEntryFilter {
boolean accept(@Nullable WritableSlice<?, ?> slice, @Nullable Diagnostic diagnostic, Object key);
boolean accept(@Nullable WritableSlice<?, ?> slice, Object key);
}

View File

@@ -18,12 +18,10 @@ package org.jetbrains.kotlin.resolve
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
import org.jetbrains.kotlin.psi.*
object UnderscoreChecker : DeclarationChecker {
@@ -44,6 +42,7 @@ object UnderscoreChecker : DeclarationChecker {
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
if (declaration is KtProperty && descriptor !is VariableDescriptor) return
if (declaration is KtCallableDeclaration) {
for (parameter in declaration.valueParameters) {
checkNamed(parameter, diagnosticHolder)

View File

@@ -19,10 +19,8 @@ package org.jetbrains.kotlin.resolve.calls
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable
@@ -285,7 +283,7 @@ class CallCompleter(
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression) ?: updatedType
}
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context.trace)
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context.statementFilter, context.trace)
// While the expected type is not known, the function literal arguments are not analyzed (to analyze function literal bodies once),
// but they should be analyzed when the expected type is known (during the call completion).
@@ -320,6 +318,7 @@ class CallCompleter(
updatedType: KotlinType?,
recordedType: KotlinType?,
argumentExpression: KtExpression,
statementFilter: StatementFilter,
trace: BindingTrace
): KotlinType? {
//workaround for KT-8218
@@ -329,6 +328,11 @@ class CallCompleter(
val deparenthesized = KtPsiUtil.deparenthesizeOnce(expression)
if (deparenthesized != expression) return deparenthesized
// see KtPsiUtil.getLastElementDeparenthesized
if (expression is KtBlockExpression) {
return statementFilter.getLastStatementInABlock(expression)
}
return (expression as? KtQualifiedExpression)?.selectorExpression
}

View File

@@ -78,7 +78,9 @@ class CandidateResolver(
return
}
checkVisibility()
if (!context.isDebuggerContext) {
checkVisibility()
}
when (checkArguments) {
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS ->
@@ -436,7 +438,7 @@ class CandidateResolver(
}
private fun <D : CallableDescriptor> CallCandidateResolutionContext<D>.checkReceiver(
candidateCall: ResolvedCall<D>,
candidateCall: MutableResolvedCall<D>,
receiverParameter: ReceiverParameterDescriptor?,
receiverArgument: ReceiverValue?,
isExplicitReceiver: Boolean,
@@ -497,9 +499,12 @@ class CandidateResolver(
if (smartCastResult == null) {
reportUnsafeCall = true
}
else if (!smartCastResult.isCorrect) {
// Error about unstable smart cast reported within checkAndRecordPossibleCast
return OTHER_ERROR
else {
candidateCall.setSmartCastDispatchReceiverType(smartCastResult.resultType)
if (!smartCastResult.isCorrect) {
// Error about unstable smart cast reported within checkAndRecordPossibleCast
return OTHER_ERROR
}
}
}

View File

@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.*
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getExplicitReceiverValue
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR
@@ -154,28 +155,35 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
val resolutionResults = getResolutionResultsCachedData(argumentExpression, context)?.resolutionResults
if (resolutionResults == null || !resolutionResults.isSingleResult) return false
val resultingCall = resolutionResults.resultingCall
if (resultingCall.isCompleted) return false
val nestedCall = resolutionResults.resultingCall
if (nestedCall.isCompleted) return false
val argumentConstraintSystem = resultingCall.constraintSystem ?: return false
val nestedConstraintSystem = nestedCall.constraintSystem ?: return false
val candidateDescriptor = resultingCall.candidateDescriptor
val candidateDescriptor = nestedCall.candidateDescriptor
val returnType = candidateDescriptor.returnType ?: return false
val nestedTypeVariables = argumentConstraintSystem.getNestedTypeVariables(returnType)
val nestedTypeVariables = nestedConstraintSystem.getNestedTypeVariables(returnType)
// we add an additional type variable only if no information is inferred for it.
// otherwise we add currently inferred return type as before
if (nestedTypeVariables.any { argumentConstraintSystem.getTypeBounds(it).bounds.isNotEmpty() }) return false
if (nestedTypeVariables.any { nestedConstraintSystem.getTypeBounds(it).bounds.isNotEmpty() }) return false
val candidateWithFreshVariables = FunctionDescriptorUtil.alphaConvertTypeParameters(candidateDescriptor)
val conversion = candidateDescriptor.typeParameters.zip(candidateWithFreshVariables.typeParameters).toMap()
val freshVariables = returnType.getNestedTypeParameters().mapNotNull { conversion[it] }
builder.registerTypeVariables(resultingCall.call.toHandle(), freshVariables, external = true)
builder.registerTypeVariables(nestedCall.call.toHandle(), freshVariables, external = true)
// Looks not too nice, but safe call result must be nullable if receiver is nullable
val argumentExpressionType = candidateWithFreshVariables.returnType?.let {
if (nestedCall.isSafeCall && nestedCall.getExplicitReceiverValue()?.type?.let {TypeUtils.isNullableType(it) } ?: true ) {
TypeUtils.makeNullable(it)
}
else it
}
builder.addSubtypeConstraint(
candidateWithFreshVariables.returnType,
argumentExpressionType,
builder.compositeSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT),
constraintPosition
)

View File

@@ -93,7 +93,7 @@ class InlineChecker implements CallChecker {
}
}
checkVisibility(targetDescriptor, expression, context);
checkVisibilityAndAccess(targetDescriptor, expression, context);
checkRecursion(context, targetDescriptor, expression);
}
@@ -238,10 +238,25 @@ class InlineChecker implements CallChecker {
return isInvoke || InlineUtil.isInline(descriptor);
}
private void checkVisibility(@NotNull CallableDescriptor declarationDescriptor, @NotNull KtElement expression, @NotNull BasicCallResolutionContext context){
private void checkVisibilityAndAccess(@NotNull CallableDescriptor declarationDescriptor, @NotNull KtElement expression, @NotNull BasicCallResolutionContext context){
boolean declarationDescriptorIsPublicApi = DescriptorUtilsKt.isEffectivelyPublicApi(declarationDescriptor) || isDefinedInInlineFunction(declarationDescriptor);
if (isEffectivelyPublicApiFunction && !declarationDescriptorIsPublicApi && declarationDescriptor.getVisibility() != Visibilities.LOCAL) {
context.trace.report(Errors.INVISIBLE_MEMBER_FROM_INLINE.on(expression, declarationDescriptor, descriptor));
context.trace.report(Errors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE.on(expression, declarationDescriptor, descriptor));
}
else {
checkPrivateClassMemberAccess(declarationDescriptor, expression, context);
}
}
private void checkPrivateClassMemberAccess(
@NotNull DeclarationDescriptor declarationDescriptor,
@NotNull KtElement expression,
@NotNull BasicCallResolutionContext context
) {
if (!Visibilities.isPrivate(descriptor.getVisibility())) {
if (DescriptorUtilsKt.isInsidePrivateClass(declarationDescriptor)) {
context.trace.report(Errors.PRIVATE_CLASS_MEMBER_FROM_INLINE.on(expression, declarationDescriptor, descriptor));
}
}
}

View File

@@ -42,11 +42,12 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
@NotNull
@@ -63,7 +64,7 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
) {
return new BasicCallResolutionContext(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments,
new ResolutionResultsCacheImpl(), null,
callChecker, StatementFilter.NONE, isAnnotationContext, false,
callChecker, StatementFilter.NONE, isAnnotationContext, false, false,
CallPosition.Unknown.INSTANCE);
}
@@ -76,7 +77,7 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
context.trace, context.scope, call, context.expectedType, context.dataFlowInfo, context.contextDependency, checkArguments,
context.resolutionResultsCache, dataFlowInfoForArguments,
context.callChecker,
context.statementFilter, context.isAnnotationContext, context.collectAllCandidates, context.callPosition);
context.statementFilter, context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates, context.callPosition);
}
@NotNull
@@ -100,14 +101,14 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
) {
return new BasicCallResolutionContext(
trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
@NotNull
public BasicCallResolutionContext replaceCall(@NotNull Call newCall) {
return new BasicCallResolutionContext(
trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
public void performContextDependentCallChecks(@NotNull ResolvedCall<?> resolvedCall) {

View File

@@ -58,11 +58,12 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
@Nullable Receiver explicitExtensionReceiverForInvoke,
@NotNull CandidateResolveMode candidateResolveMode,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext,
collectAllCandidates, callPosition);
this.candidateCall = candidateCall;
this.tracing = tracing;
@@ -80,7 +81,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
context.dataFlowInfo, context.contextDependency, context.checkArguments,
context.resolutionResultsCache, context.dataFlowInfoForArguments,
context.callChecker, context.statementFilter, explicitExtensionReceiverForInvoke,
candidateResolveMode, context.isAnnotationContext, context.collectAllCandidates, context.callPosition);
candidateResolveMode, context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates, context.callPosition);
}
@NotNull
@@ -91,7 +92,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
candidateCall, tracing, context.trace, context.scope, context.call, context.expectedType,
context.dataFlowInfo, context.contextDependency, context.checkArguments, context.resolutionResultsCache,
context.dataFlowInfoForArguments, context.callChecker, context.statementFilter,
null, CandidateResolveMode.FULLY, context.isAnnotationContext, context.collectAllCandidates,
null, CandidateResolveMode.FULLY, context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates,
context.callPosition);
}
@@ -110,6 +111,6 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
return new CallCandidateResolutionContext<D>(
candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments,
resolutionResultsCache, dataFlowInfoForArguments, callChecker, statementFilter,
explicitExtensionReceiverForInvoke, candidateResolveMode, isAnnotationContext, collectAllCandidates, callPosition);
explicitExtensionReceiverForInvoke, candidateResolveMode, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
}

View File

@@ -50,11 +50,12 @@ public abstract class CallResolutionContext<Context extends CallResolutionContex
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, expectedType, dataFlowInfo, contextDependency, resolutionResultsCache, callChecker,
statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
this.call = call;
this.checkArguments = checkArguments;
if (dataFlowInfoForArguments != null) {

View File

@@ -52,6 +52,8 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
public final boolean isAnnotationContext;
public final boolean isDebuggerContext;
public final boolean collectAllCandidates;
@NotNull
@@ -67,6 +69,7 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
@@ -79,6 +82,7 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
this.callChecker = callChecker;
this.statementFilter = statementFilter;
this.isAnnotationContext = isAnnotationContext;
this.isDebuggerContext = isDebuggerContext;
this.collectAllCandidates = collectAllCandidates;
this.callPosition = callPosition;
}

View File

@@ -87,12 +87,6 @@ public abstract class DelegatingResolvedCall<D extends CallableDescriptor> imple
return resolvedCall.getValueArguments();
}
@NotNull
@Override
public Map<ValueParameterDescriptor, ResolvedValueArgument> getUnsubstitutedValueArguments() {
return resolvedCall.getUnsubstitutedValueArguments();
}
@NotNull
@Override
public ArgumentMapping getArgumentMapping(@NotNull ValueArgument valueArgument) {
@@ -121,4 +115,10 @@ public abstract class DelegatingResolvedCall<D extends CallableDescriptor> imple
public boolean isSafeCall() {
return resolvedCall.isSafeCall();
}
@Nullable
@Override
public KotlinType getSmartCastDispatchReceiverType() {
return resolvedCall.getSmartCastDispatchReceiverType();
}
}

View File

@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.DelegatingBindingTrace;
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus;
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeSubstitutor;
public interface MutableResolvedCall<D extends CallableDescriptor> extends ResolvedCall<D> {
@@ -64,4 +65,6 @@ public interface MutableResolvedCall<D extends CallableDescriptor> extends Resol
//todo remove: use value to parameter map status
boolean hasInferredReturnType();
void setSmartCastDispatchReceiverType(@NotNull KotlinType smartCastDispatchReceiverType);
}

View File

@@ -64,10 +64,6 @@ public interface ResolvedCall<D extends CallableDescriptor> {
@NotNull
Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments();
/** Values (arguments) for value parameters, no type parameter substitution */
@NotNull
Map<ValueParameterDescriptor, ResolvedValueArgument> getUnsubstitutedValueArguments();
/** Values (arguments) for value parameters indexed by parameter index */
@Nullable
List<ResolvedValueArgument> getValueArgumentsByIndex();
@@ -85,4 +81,7 @@ public interface ResolvedCall<D extends CallableDescriptor> {
DataFlowInfoForArguments getDataFlowInfoForArguments();
boolean isSafeCall();
@Nullable
KotlinType getSmartCastDispatchReceiverType();
}

View File

@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.model;
import com.google.common.collect.Maps;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.Function;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
@@ -40,9 +41,7 @@ import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeProjection;
import org.jetbrains.kotlin.types.TypeSubstitutor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import static org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE;
import static org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.UNKNOWN_STATUS;
@@ -84,7 +83,6 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
private final Map<TypeParameterDescriptor, KotlinType> typeArguments = Maps.newLinkedHashMap();
private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newLinkedHashMap();
private Map<ValueParameterDescriptor, ResolvedValueArgument> valueArgumentsBeforeSubstitution;
private final MutableDataFlowInfoForArguments dataFlowInfoForArguments;
private final Map<ValueArgument, ArgumentMatchImpl> argumentToParameterMap = Maps.newHashMap();
@@ -94,6 +92,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
private ConstraintSystem constraintSystem = null;
private Boolean hasInferredReturnType = null;
private boolean completed = false;
private KotlinType smartCastDispatchReceiverType = null;
private ResolvedCallImpl(
@NotNull ResolutionCandidate<D> candidate,
@@ -195,25 +194,27 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
}
}
Map<ValueParameterDescriptor, ValueParameterDescriptor> substitutedParametersMap = Maps.newHashMap();
for (ValueParameterDescriptor valueParameterDescriptor : resultingDescriptor.getValueParameters()) {
substitutedParametersMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
}
List<ValueParameterDescriptor> substitutedParameters = resultingDescriptor.getValueParameters();
Collection<Map.Entry<ValueParameterDescriptor, ResolvedValueArgument>> valueArgumentsBeforeSubstitution =
new SmartList<Map.Entry<ValueParameterDescriptor, ResolvedValueArgument>>(valueArguments.entrySet());
valueArgumentsBeforeSubstitution = Maps.newLinkedHashMap(valueArguments);
valueArguments.clear();
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : valueArgumentsBeforeSubstitution.entrySet()) {
ValueParameterDescriptor substitutedVersion = substitutedParametersMap.get(entry.getKey().getOriginal());
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : valueArgumentsBeforeSubstitution) {
ValueParameterDescriptor substitutedVersion = substitutedParameters.get(entry.getKey().getIndex());
assert substitutedVersion != null : entry.getKey();
valueArguments.put(substitutedVersion, entry.getValue());
}
Map<ValueArgument, ArgumentMatchImpl> originalArgumentToParameterMap = Maps.newLinkedHashMap(argumentToParameterMap);
Collection<Map.Entry<ValueArgument, ArgumentMatchImpl>> unsubstitutedArgumentMappings =
new SmartList<Map.Entry<ValueArgument, ArgumentMatchImpl>>(argumentToParameterMap.entrySet());
argumentToParameterMap.clear();
for (Map.Entry<ValueArgument, ArgumentMatchImpl> entry : originalArgumentToParameterMap.entrySet()) {
for (Map.Entry<ValueArgument, ArgumentMatchImpl> entry : unsubstitutedArgumentMappings) {
ArgumentMatchImpl argumentMatch = entry.getValue();
ValueParameterDescriptor valueParameterDescriptor = argumentMatch.getValueParameter();
ValueParameterDescriptor substitutedVersion = substitutedParametersMap.get(valueParameterDescriptor.getOriginal());
ValueParameterDescriptor substitutedVersion = substitutedParameters.get(valueParameterDescriptor.getIndex());
assert substitutedVersion != null : valueParameterDescriptor;
argumentToParameterMap.put(entry.getKey(), argumentMatch.replaceValueParameter(substitutedVersion));
}
@@ -264,14 +265,6 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
return valueArguments;
}
@Override
@NotNull
public Map<ValueParameterDescriptor, ResolvedValueArgument> getUnsubstitutedValueArguments() {
// TODO We need unsubstituted value arguments to compare signatures for specificity when explicit type arguments are provided.
// Current implementation is questionable (mostly due to lack of well-defined contract for MutableResolvedCall).
return valueArgumentsBeforeSubstitution != null ? valueArgumentsBeforeSubstitution : valueArguments;
}
@Nullable
@Override
public List<ResolvedValueArgument> getValueArgumentsByIndex() {
@@ -370,4 +363,15 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
public TypeSubstitutor getKnownTypeParametersSubstitutor() {
return knownTypeParametersSubstitutor;
}
@Override
public void setSmartCastDispatchReceiverType(@NotNull KotlinType smartCastDispatchReceiverType) {
this.smartCastDispatchReceiverType = smartCastDispatchReceiverType;
}
@Override
@Nullable
public KotlinType getSmartCastDispatchReceiverType() {
return smartCastDispatchReceiverType;
}
}

View File

@@ -69,14 +69,18 @@ class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constr
val argumentsToParameters = hashMapOf<K, ValueParameterDescriptor>()
var parametersWithDefaultValuesCount = 0
for ((valueParameterDescriptor, resolvedValueArgument) in call.unsubstitutedValueArguments.entries) {
val unsubstitutedValueParameters = call.candidateDescriptor.original.valueParameters
for ((valueParameterDescriptor, resolvedValueArgument) in call.valueArguments.entries) {
if (resolvedValueArgument is DefaultValueArgument) {
parametersWithDefaultValuesCount++
}
else {
val keys = resolvedArgumentToKeys(resolvedValueArgument)
for (argumentKey in keys) {
argumentsToParameters[argumentKey] = valueParameterDescriptor.original
// TODO fix 'original' for value parameters of Java generic descriptors.
// Should be able to use just 'valueParameterDescriptor' below.
// Doesn't work for Java generic descriptors. See also KT-10939.
argumentsToParameters[argumentKey] = unsubstitutedValueParameters[valueParameterDescriptor.index]
}
}
}

View File

@@ -19,15 +19,13 @@ package org.jetbrains.kotlin.resolve.calls.results
import gnu.trove.THashSet
import gnu.trove.TObjectHashingStrategy
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION
import org.jetbrains.kotlin.resolve.calls.inference.toHandle
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
@@ -35,14 +33,15 @@ import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionMutableResolve
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
fun <D : CallableDescriptor> findMaximallySpecific(
candidates: Set<MutableResolvedCall<D>>,
checkArgumentsMode: CheckArgumentTypesMode,
discriminateGenerics: Boolean
discriminateGenerics: Boolean,
isDebuggerContext: Boolean
): MutableResolvedCall<D>? =
if (candidates.size <= 1)
candidates.firstOrNull()
@@ -56,7 +55,7 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
}.singleOrNull()
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS ->
findMaximallySpecificCall(candidates, discriminateGenerics)
findMaximallySpecificCall(candidates, discriminateGenerics, isDebuggerContext)
}
fun <D : CallableDescriptor> findMaximallySpecificVariableAsFunctionCalls(candidates: Set<MutableResolvedCall<D>>): Set<MutableResolvedCall<D>> {
@@ -67,7 +66,7 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
throw AssertionError("Regular call among variable-as-function calls: $it")
}
val maxSpecificVariableCall = findMaximallySpecificCall(variableCalls, false) ?: return emptySet()
val maxSpecificVariableCall = findMaximallySpecificCall(variableCalls, false, false) ?: return emptySet()
return candidates.filterTo(newResolvedCallSet<MutableResolvedCall<D>>(2)) {
it.resultingVariableDescriptor == maxSpecificVariableCall.resultingDescriptor
@@ -76,7 +75,8 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
private fun <D : CallableDescriptor> findMaximallySpecificCall(
candidates: Set<MutableResolvedCall<D>>,
discriminateGenerics: Boolean
discriminateGenerics: Boolean,
isDebuggerContext: Boolean
): MutableResolvedCall<D>? {
val filteredCandidates = uniquifyCandidatesSet(candidates)
@@ -89,7 +89,7 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
val bestCandidatesByParameterTypes = conflictingCandidates.mapNotNull {
candidate ->
candidate.satisfying {
candidate.check {
isMostSpecific(candidate, conflictingCandidates) {
call1, call2 ->
isNotLessSpecificCallWithArgumentMapping(call1, call2, discriminateGenerics)
@@ -97,7 +97,10 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
}
}
return bestCandidatesByParameterTypes.exactMaxWith { call1, call2 -> isOfNotLessSpecificShape(call1, call2) }?.resolvedCall
return bestCandidatesByParameterTypes.exactMaxWith {
call1, call2 ->
isOfNotLessSpecificShape(call1, call2) && isOfNotLessSpecificVisibilityForDebugger(call1, call2, isDebuggerContext)
}?.resolvedCall
}
private inline fun <C : Any> Collection<C>.exactMaxWith(isNotWorse: (C, C) -> Boolean): C? {
@@ -231,6 +234,22 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
return true
}
private fun <D: CallableDescriptor, K> isOfNotLessSpecificVisibilityForDebugger(
call1: CandidateCallWithArgumentMapping<D, K>,
call2: CandidateCallWithArgumentMapping<D, K>,
isDebuggerContext: Boolean
): Boolean {
if (isDebuggerContext) {
val isMoreVisible1 = Visibilities.compare(
call1.resolvedCall.resultingDescriptor.visibility,
call2.resolvedCall.resultingDescriptor.visibility
)
if (isMoreVisible1 != null && isMoreVisible1 < 0) return false
}
return true
}
/**
* Returns `true` if `d1` is definitely not less specific than `d2`,
* `false` if `d1` is definitely less specific than `d2`,
@@ -307,9 +326,6 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
private fun getVarargElementTypeOrType(parameterDescriptor: ValueParameterDescriptor): KotlinType =
parameterDescriptor.varargElementType ?: parameterDescriptor.type
private val CallableDescriptor.hasVarargs: Boolean get() =
this.valueParameters.any { it.varargElementType != null }
private fun typeNotLessSpecific(specific: KotlinType, general: KotlinType): Boolean {
val isSubtype = KotlinTypeChecker.DEFAULT.isSubtypeOf(specific, general) || numericTypeMoreSpecific(specific, general)

View File

@@ -96,7 +96,8 @@ public class ResolutionResultsHandler {
Set<MutableResolvedCall<D>> successfulAndIncomplete = Sets.newLinkedHashSet();
successfulAndIncomplete.addAll(successfulCandidates);
successfulAndIncomplete.addAll(incompleteCandidates);
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(successfulAndIncomplete, true, checkArgumentsMode);
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(
successfulAndIncomplete, true, context.isDebuggerContext, checkArgumentsMode);
if (results.isSingleResult()) {
MutableResolvedCall<D> resultingCall = results.getResultingCall();
resultingCall.getTrace().moveAllMyDataTo(context.trace);
@@ -147,7 +148,7 @@ public class ResolutionResultsHandler {
if (severityLevel.contains(ARGUMENTS_MAPPING_ERROR)) {
return recordFailedInfo(tracing, trace, thisLevel);
}
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false, checkArgumentsMode);
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false, false, checkArgumentsMode);
return recordFailedInfo(tracing, trace, results.getResultingCalls());
}
}
@@ -188,6 +189,7 @@ public class ResolutionResultsHandler {
public <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(
@NotNull Set<MutableResolvedCall<D>> candidates,
boolean discriminateGenerics,
boolean isDebuggerContext,
@NotNull CheckArgumentTypesMode checkArgumentsMode
) {
if (candidates.size() == 1) {
@@ -203,14 +205,14 @@ public class ResolutionResultsHandler {
return OverloadResolutionResultsImpl.success(noOverrides.iterator().next());
}
MutableResolvedCall<D> maximallySpecific = overloadingConflictResolver.findMaximallySpecific(noOverrides, checkArgumentsMode, false);
MutableResolvedCall<D> maximallySpecific = overloadingConflictResolver.findMaximallySpecific(noOverrides, checkArgumentsMode, false, isDebuggerContext);
if (maximallySpecific != null) {
return OverloadResolutionResultsImpl.success(maximallySpecific);
}
if (discriminateGenerics) {
MutableResolvedCall<D> maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(
noOverrides, checkArgumentsMode, true);
noOverrides, checkArgumentsMode, true, isDebuggerContext);
if (maximallySpecificGenericsDiscriminated != null) {
return OverloadResolutionResultsImpl.success(maximallySpecificGenericsDiscriminated);
}

View File

@@ -58,11 +58,12 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
@NotNull StatementFilter statementFilter,
@NotNull Collection<MutableResolvedCall<F>> resolvedCalls,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
this.lazyCandidates = lazyCandidates;
this.resolvedCalls = resolvedCalls;
this.tracing = tracing;
@@ -79,7 +80,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
context.resolutionResultsCache, context.dataFlowInfoForArguments,
context.callChecker,
context.statementFilter, new SmartList<MutableResolvedCall<F>>(),
context.isAnnotationContext, context.collectAllCandidates, context.callPosition);
context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates, context.callPosition);
}
@NotNull
@@ -113,7 +114,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
resolutionResultsCache, dataFlowInfoForArguments,
callChecker,
statementFilter, resolvedCalls,
isAnnotationContext, collectAllCandidates, callPosition);
isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
@Override

View File

@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.util.*
@@ -46,9 +47,9 @@ fun createSynthesizedInvokes(functions: Collection<FunctionDescriptor>): Collect
synthesizedSuperFun.modality,
synthesizedSuperFun.visibility,
CallableMemberDescriptor.Kind.FAKE_OVERRIDE,
true
/* copyOverrides = */ false
)
fakeOverride.addOverriddenDescriptor(synthesizedSuperFun)
fakeOverride.setSingleOverridden(synthesizedSuperFun)
fakeOverride
}

View File

@@ -50,7 +50,7 @@ import org.jetbrains.kotlin.types.DeferredType
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
import org.jetbrains.kotlin.utils.sure
class NewResolveOldInference(
@@ -290,7 +290,7 @@ class NewResolveOldInference(
tracing.bindReference(variable.resolvedCall.trace, variable.resolvedCall)
// todo hacks
val functionCall = CallTransformer.CallForImplicitInvoke(
basicCallContext.call.explicitReceiver?.satisfying { useExplicitReceiver },
basicCallContext.call.explicitReceiver?.check { useExplicitReceiver },
variableReceiver, basicCallContext.call)
val tracingForInvoke = TracingStrategyForInvoke(calleeExpression, functionCall, variableReceiver.type)
val basicCallResolutionContext = basicCallContext.replaceBindingTrace(variable.resolvedCall.trace)

View File

@@ -21,16 +21,14 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.containsError
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.util.*
@@ -50,7 +48,9 @@ internal class ScopeTowerImpl(
override val lexicalScope: LexicalScope = resolutionContext.scope
override val implicitReceivers = resolutionContext.scope.getImplicitReceiversHierarchy().
mapNotNull { it.value.satisfying { !it.type.containsError() } }
mapNotNull { it.value.check { !it.type.containsError() } }
val isDebuggerContext = resolutionContext.isDebuggerContext
}
private class DataFlowDecoratorImpl(private val resolutionContext: ResolutionContext<*>): DataFlowDecorator {

View File

@@ -22,14 +22,14 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
internal class KnownResultProcessor<C>(
val result: Collection<C>
): ScopeTowerProcessor<C> {
override fun process(data: TowerData)
= if (data == TowerData.Empty) listOfNotNull(result.satisfying { it.isNotEmpty() }) else emptyList()
= if (data == TowerData.Empty) listOfNotNull(result.check { it.isNotEmpty() }) else emptyList()
}
internal class CompositeScopeTowerProcessor<C>(
@@ -45,7 +45,7 @@ internal abstract class AbstractSimpleScopeTowerProcessor<C>(
protected abstract fun simpleProcess(data: TowerData): Collection<C>
override fun process(data: TowerData): List<Collection<C>> = listOfNotNull(simpleProcess(data).satisfying { it.isNotEmpty() })
override fun process(data: TowerData): List<Collection<C>> = listOfNotNull(simpleProcess(data).check { it.isNotEmpty() })
}
internal class ExplicitReceiverScopeTowerProcessor<C>(

View File

@@ -62,10 +62,13 @@ internal abstract class AbstractScopeTowerLevel(
if (descriptor.isSynthesized) diagnostics.add(SynthesizedDescriptorDiagnostic)
if (dispatchReceiverSmartCastType != null) diagnostics.add(UsedSmartCastForDispatchReceiver(dispatchReceiverSmartCastType))
Visibilities.findInvisibleMember(
dispatchReceiver, descriptor,
scopeTower.lexicalScope.ownerDescriptor
)?.let { diagnostics.add(VisibilityError(it)) }
val shouldSkipVisibilityCheck = scopeTower is ScopeTowerImpl && scopeTower.isDebuggerContext
if (!shouldSkipVisibilityCheck) {
Visibilities.findInvisibleMember(
dispatchReceiver, descriptor,
scopeTower.lexicalScope.ownerDescriptor
)?.let { diagnostics.add(VisibilityError(it)) }
}
}
return CandidateWithBoundDispatchReceiverImpl(dispatchReceiver, descriptor, diagnostics)
}

View File

@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.util.*
interface TowerContext<C> {
@@ -221,13 +221,13 @@ class TowerResolver {
override fun getSuccessfulCandidates(): Collection<C>? = getResolved() ?: getResolvedSynthetic()
fun getResolved() = currentCandidates.satisfying { currentLevel == ResolutionCandidateApplicability.RESOLVED }
fun getResolved() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED }
fun getResolvedSynthetic() = currentCandidates.satisfying { currentLevel == ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED }
fun getResolvedSynthetic() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED }
fun getResolvedLowPriority() = currentCandidates.satisfying { currentLevel == ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY }
fun getResolvedLowPriority() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY }
fun getErrors() = currentCandidates.satisfying {
fun getErrors() = currentCandidates.check {
currentLevel == null || currentLevel!! > ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY
}

View File

@@ -99,7 +99,7 @@ private fun deprecationByOverridden(root: CallableMemberDescriptor): Deprecation
visited.add(node)
val deprecatedAnnotation = node.getDeprecationByAnnotation()
val overriddenDescriptors = node.overriddenDescriptors
val overriddenDescriptors = node.original.overriddenDescriptors
when {
deprecatedAnnotation != null -> {
deprecations.add(deprecatedAnnotation)

View File

@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addToStdlib.satisfying
import org.jetbrains.kotlin.utils.addToStdlib.check
open class FileScopeProviderImpl(
private val topLevelDescriptorProvider: TopLevelDescriptorProvider,
@@ -159,7 +159,7 @@ open class FileScopeProviderImpl(
if (name in excludedNames) return null
val classifier = scope.getContributedClassifier(name, location) ?: return null
val visible = Visibilities.isVisibleWithIrrelevantReceiver(classifier as ClassDescriptor, fromDescriptor)
return classifier.satisfying { filteringKind == if (visible) FilteringKind.VISIBLE_CLASSES else FilteringKind.INVISIBLE_CLASSES }
return classifier.check { filteringKind == if (visible) FilteringKind.VISIBLE_CLASSES else FilteringKind.INVISIBLE_CLASSES }
}
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> {

View File

@@ -262,6 +262,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
}
List<KtTypeParameter> typeParameters = typeParameterList.getParameters();
if (typeParameters.isEmpty()) return Collections.emptyList();
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>(typeParameters.size());

View File

@@ -108,7 +108,7 @@ open class LazyClassMemberScope(
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(fromCurrent) as? KtDeclaration ?: error("fromCurrent can not be a fake override")
trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().asString()))
trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromSuper.containingDeclaration))
}
})
OverrideResolver.resolveUnknownVisibilities(result, trace)

View File

@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.types.expressions;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
@@ -32,7 +31,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtilsKt;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.KtKeywordToken;
import org.jetbrains.kotlin.lexer.KtTokens;
@@ -1181,7 +1179,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
@Override
public boolean accept(@Nullable WritableSlice<?, ?> slice, @Nullable Diagnostic diagnostic, Object key) {
public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
// the type of the right (and sometimes left) expression isn't 'Any?' actually
if ((key == right || key == left) && slice == EXPRESSION_TYPE_INFO) return false;

View File

@@ -571,8 +571,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
parentDeclaration = PsiTreeUtil.getParentOfType(parentDeclaration, KtDeclaration.class);
}
assert parentDeclaration != null : "Can't find parent declaration for " + expression.getText();
// Parent declaration can be null in code fragments or in some bad error expressions
DeclarationDescriptor declarationDescriptor = context.trace.get(DECLARATION_TO_DESCRIPTOR, parentDeclaration);
Pair<FunctionDescriptor, PsiElement> containingFunInfo =
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(declarationDescriptor, false);
FunctionDescriptor containingFunctionDescriptor = containingFunInfo.getFirst();

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.types.expressions
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
import org.jetbrains.kotlin.psi.KtExpression
@@ -41,38 +42,14 @@ class DestructuringDeclarationResolver(
fun defineLocalVariablesFromMultiDeclaration(
writableScope: LexicalWritableScope,
destructuringDeclaration: KtDestructuringDeclaration,
receiver: ReceiverValue,
reportErrorsOn: KtExpression,
receiver: ReceiverValue?,
initializer: KtExpression?,
context: ExpressionTypingContext
) {
for ((componentIndex, entry) in destructuringDeclaration.entries.withIndex()) {
val componentName = createComponentName(componentIndex + 1)
val expectedType = getExpectedTypeForComponent(context, entry)
val results = fakeCallResolver.resolveFakeCall(context.replaceExpectedType(expectedType), receiver, componentName,
entry, reportErrorsOn, FakeCallKind.COMPONENT)
var componentType: KotlinType? = null
if (results.isSuccess) {
context.trace.record(BindingContext.COMPONENT_RESOLVED_CALL, entry, results.resultingCall)
val functionDescriptor = results.resultingDescriptor
symbolUsageValidator.validateCall(null, functionDescriptor, context.trace, entry)
componentType = functionDescriptor.returnType
if (componentType != null && !TypeUtils.noExpectedType(expectedType) && !KotlinTypeChecker.DEFAULT.isSubtypeOf(componentType, expectedType)) {
context.trace.report(Errors.COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.on(reportErrorsOn, componentName, componentType, expectedType))
}
}
else if (results.isAmbiguity) {
context.trace.report(Errors.COMPONENT_FUNCTION_AMBIGUITY.on(reportErrorsOn, componentName, results.getResultingCalls()))
}
else {
context.trace.report(Errors.COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, componentName, receiver.getType()))
}
if (componentType == null) {
componentType = ErrorUtils.createErrorType("$componentName() return type")
}
val componentType = resolveComponentFunctionAndGetType(componentName, context, entry, receiver, initializer)
val variableDescriptor = localVariableResolver.resolveLocalVariableDescriptorWithType(writableScope, entry, componentType, context.trace)
ExpressionTypingUtils.checkVariableShadowing(writableScope, context.trace, variableDescriptor)
@@ -81,6 +58,40 @@ class DestructuringDeclarationResolver(
}
}
private fun resolveComponentFunctionAndGetType(
componentName: Name,
context: ExpressionTypingContext,
entry: KtDestructuringDeclarationEntry,
receiver: ReceiverValue?,
initializer: KtExpression?
): KotlinType {
fun errorType() = ErrorUtils.createErrorType("$componentName() return type")
if (receiver == null || initializer == null) return errorType()
val expectedType = getExpectedTypeForComponent(context, entry)
val results = fakeCallResolver.resolveFakeCall(
context.replaceExpectedType(expectedType), receiver, componentName,
entry, initializer, FakeCallKind.COMPONENT
)
if (!results.isSuccess) {
return errorType()
}
context.trace.record(BindingContext.COMPONENT_RESOLVED_CALL, entry, results.resultingCall)
val functionDescriptor = results.resultingDescriptor
symbolUsageValidator.validateCall(null, functionDescriptor, context.trace, entry)
val functionReturnType = functionDescriptor.returnType
if (functionReturnType != null && !TypeUtils.noExpectedType(expectedType)
&& !KotlinTypeChecker.DEFAULT.isSubtypeOf(functionReturnType, expectedType) ) {
context.trace.report(Errors.COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.on(initializer, componentName, functionReturnType, expectedType))
}
return functionReturnType ?: errorType()
}
private fun getExpectedTypeForComponent(context: ExpressionTypingContext, entry: KtDestructuringDeclarationEntry): KotlinType {
val entryTypeRef = entry.typeReference ?: return TypeUtils.NO_EXPECTED_TYPE
return typeResolver.resolveType(context.scope, entryTypeRef, context.trace, true)

View File

@@ -58,7 +58,18 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
context.contextDependency, context.resolutionResultsCache,
context.callChecker,
context.statementFilter,
context.isAnnotationContext, context.collectAllCandidates,
context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates,
context.callPosition);
}
@NotNull
public static ExpressionTypingContext newContext(@NotNull ResolutionContext context, boolean isDebuggerContext) {
return new ExpressionTypingContext(
context.trace, context.scope, context.dataFlowInfo, context.expectedType,
context.contextDependency, context.resolutionResultsCache,
context.callChecker,
context.statementFilter,
context.isAnnotationContext, isDebuggerContext, context.collectAllCandidates,
context.callPosition);
}
@@ -76,7 +87,7 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
) {
return new ExpressionTypingContext(
trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, callChecker,
statementFilter, isAnnotationContext, false, CallPosition.Unknown.INSTANCE);
statementFilter, isAnnotationContext, false, false, CallPosition.Unknown.INSTANCE);
}
private ExpressionTypingContext(
@@ -89,12 +100,13 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, expectedType, dataFlowInfo, contextDependency, resolutionResultsCache,
callChecker,
statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
@Override
@@ -112,6 +124,6 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
return new ExpressionTypingContext(trace, scope, dataFlowInfo,
expectedType, contextDependency, resolutionResultsCache,
callChecker,
statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
}

View File

@@ -25,7 +25,11 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.incremental.components.LookupTracker;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.psi.codeFragmentUtil.CodeFragmentUtilKt;
import org.jetbrains.kotlin.resolve.AnnotationChecker;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.DeclarationsCheckerBuilder;
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
import org.jetbrains.kotlin.resolve.calls.context.CallPosition;
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
@@ -144,8 +148,12 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
@Override
@NotNull
public final KotlinTypeInfo getTypeInfo(@NotNull KtExpression expression, ExpressionTypingContext context, boolean isStatement) {
if (!isStatement) return getTypeInfo(expression, context);
return getTypeInfo(expression, context, getStatementVisitor(context));
ExpressionTypingContext newContext = context;
if (CodeFragmentUtilKt.suppressDiagnosticsInDebugMode(expression)) {
newContext = ExpressionTypingContext.newContext(context, true);
}
if (!isStatement) return getTypeInfo(expression, newContext);
return getTypeInfo(expression, newContext, getStatementVisitor(newContext));
}
protected ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) {

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