Compare commits

...

129 Commits

Author SHA1 Message Date
Alexander Udalov
8ba465f3a8 Ant task: don't pass kotlin-runtime.jar to javac on "-no-stdlib" 2015-06-05 16:38:08 +03:00
Alexander Udalov
0f7cf8bd41 Minor, delete useless test
'withKotlinNoJavaSources' tests exactly the same
2015-06-05 16:38:06 +03:00
Alexander Udalov
a4dc23535c Ant task: support "compilerarg" element in withKotlin as in kotlinc 2015-06-05 16:38:04 +03:00
Alexander Udalov
18668b8409 Rewrite integration tests to JUnit3, make Ant JVM task tests generated 2015-06-05 16:37:18 +03:00
Alexander Udalov
6ae3a5806e Don't always run code in Ant task tests
But when running code, do it via <java> task, not via custom testing code. Most
of the time the compiled code need not be runned, because it's irrelevant to
the Ant task itself
2015-06-05 16:26:21 +03:00
Alexander Udalov
96f0c1c215 Don't check exit code in Ant tests
It's already checked in the build log in each test
2015-06-05 16:25:44 +03:00
Alexander Udalov
e3df2d0056 Ant task: pass kotlin-runtime to javac's classpath; simplify tests
'kotlinCompiler' test is deleted because it's a very roundabout way to compile
Kotlin and Java sources, and there's no point in testing it.

'javacCompiler' test is deleted for similar reasons: using javac's "compiler"
option is not an advertised way to use Kotlin Ant task, and anyway it will work
with any CompilerAdapter instance, so it's hard to break it (apart from
deleting "withKotlin" adapter).

There are tests which check compilation/running of the same code but with the
recommended method. The pretext for deletion of these tests is to make Ant
tests generated, and that would be easier if they wouldn't depend on any outer
variables
2015-06-05 16:25:37 +03:00
Alexander Udalov
7e24413e9b Minor, move and rename CompilerClassLoaderHolder -> KotlinAntTaskUtil 2015-06-05 16:25:35 +03:00
Alexander Udalov
f2caacd57f Ant task: warn when Ant version < 1.8.2 2015-06-05 16:25:34 +03:00
Alexander Udalov
b6c84cf584 Ant task: support 'failOnError' attribute in kotlinc and withKotlin 2015-06-05 16:25:32 +03:00
Alexander Udalov
c1707058f2 Always run kotlinc in <withKotlin/> Ant task
This change requires withKotlin to be run with Ant of version at least 1.8.2.

Some test data changed because now compileList contains both Java and Kotlin
sources

 #KT-7870 Fixed
2015-06-05 16:25:30 +03:00
Alexander Udalov
18c3a7651e Drop ant-1.7 from project, advance Ant to 1.8.2
Ant 1.8.2 has the API (namely,
CompilerAdapterExtension#getSupportedFileExtensions) which will allow to fix a
critical bug in <withKotlin/> task (see KT-7870)
2015-06-05 16:25:29 +03:00
Alexander Udalov
68f1d402b3 Fix withKotlin Ant task when no classpath is given
#KT-6492 Fixed
2015-06-05 16:25:27 +03:00
Nikolay Krasko
1f1234aa73 Use same classloader for loading JS and JVM compilers 2015-06-05 14:50:19 +03:00
Denis Zharkov
b60798f8d0 Introduce KotlinNamesValidator
It's needed to prohibit invalid kotlin identifiers in refactorings

 #EA-69048 Fixed
 #EA-69063 Fixed
2015-06-05 12:02:43 +03:00
Alexander Udalov
ed7b69cce0 Fix type argument substitution bug in KFunction construction
For example,

KMemberFunction2<T, P1, P2, R> : KMemberFunction<T, R>

So for this inheritance the heuristic that was present ("take the last K type
parameters of the subclass, and substitute for K parameters of the superclass")
was wrong. The new heuristic for this case is: take type parameters with the
same names.

Also don't store "parameters" in a lazy value, since it's easy to compute and
it's computed practically every time anyway
2015-06-04 23:12:07 +03:00
Alexander Udalov
90cf9d6f6f Refactor fictitious function class kinds, reuse in J<->K map 2015-06-04 23:12:06 +03:00
Alexander Udalov
c0b0076c70 Minor, set XML indentation to 4 spaces
Was accidentally changed to 2 in 181af17
2015-06-04 23:11:56 +03:00
Alexander Udalov
5f831c3855 Minor, swap order of parameters for clarity 2015-06-04 23:11:50 +03:00
Valentin Kipyatkov
617f8da9d4 Corrected imports 2015-06-04 23:05:49 +03:00
Valentin Kipyatkov
064b285145 Probably fixed EA-69004
(cherry picked from commit 200c644)
2015-06-04 23:05:49 +03:00
Valentin Kipyatkov
56a8142116 Fixed EA-69042
(cherry picked from commit f05789e)
2015-06-04 23:05:49 +03:00
Valentin Kipyatkov
06ad3a35ae KT-7815 Smart completion after "as" inserts fq-name for type parameter
#KT-7815 Fixed
(cherry picked from commit e597532)
2015-06-04 23:05:49 +03:00
Valentin Kipyatkov
cd7bc58904 Deprecated symbols made less priority than named parameters
(cherry picked from commit d3e4b34)
2015-06-04 23:05:49 +03:00
Valentin Kipyatkov
024fb4a54a DeprecatedSymbolUsageFix: keeping explicit type arguments in original form
(cherry picked from commit 6751a1d)
2015-06-04 23:05:48 +03:00
Valentin Kipyatkov
02cc792b3c Extracted methods
(cherry picked from commit 9f1fbe2)
2015-06-04 23:05:48 +03:00
Valentin Kipyatkov
5b1375d427 KT-7895 Auto replace for deprecated (ReplaceWith) loses generic type
#KT-7895 Fixed
(cherry picked from commit a26c62a)
2015-06-04 23:05:48 +03:00
Valentin Kipyatkov
7b1782111b Reordered methods
(cherry picked from commit 4927a58)
2015-06-04 23:05:48 +03:00
Valentin Kipyatkov
45884c436d Added TODO
(cherry picked from commit 609ac21)
2015-06-04 23:05:48 +03:00
Valentin Kipyatkov
3bf15229ca Moved methods working with calls into appropriate place
(cherry picked from commit df0fc51)
2015-06-04 23:05:48 +03:00
Valentin Kipyatkov
5018be1b86 Moved method to psiUtils.kt
(cherry picked from commit ac7e6bd)
2015-06-04 23:05:47 +03:00
Valentin Kipyatkov
2f53c2cd4f Moved methods for package-directory relation into IDEA
(cherry picked from commit 85d9855)
2015-06-04 23:05:47 +03:00
Valentin Kipyatkov
3362c967e7 Moving more PSI modification methods to psiModificationUtils.kt
(cherry picked from commit cbc0a60)
2015-06-04 23:05:47 +03:00
Valentin Kipyatkov
291ace122f Getting rid of confusing methods on PsiElement's
(cherry picked from commit 006c02b)
2015-06-04 23:05:47 +03:00
Valentin Kipyatkov
169067be6b Moving methods modifying PSI to psiModificationUtils.kt
(cherry picked from commit e99b343)
2015-06-04 23:05:47 +03:00
Valentin Kipyatkov
ac1b5bba22 More simple implementation
(cherry picked from commit c1e0469)
2015-06-04 23:05:47 +03:00
Valentin Kipyatkov
729c171013 Refactored PsiElement.parents() into 2 properties
(cherry picked from commit 494d96b)
2015-06-04 23:05:46 +03:00
Valentin Kipyatkov
a86e263cfe Dropped unused methods
(cherry picked from commit 55f70d7)
2015-06-04 23:05:46 +03:00
Valentin Kipyatkov
6a0eb98734 Moved language independent methods from jetPsiUtil.kt to psiUtils.kt + reordered and gropped them
(cherry picked from commit 0e8a43f)
2015-06-04 23:05:46 +03:00
Valentin Kipyatkov
9405f76875 KT-5482 Redundant type arguments are not detected in some cases
#KT-5482 Fixed
(cherry picked from commit f146153)
2015-06-04 23:05:46 +03:00
Valentin Kipyatkov
ad13fbb119 KT-7695 Java to Kotlin converter incorrectly generates a cast to non-nullable type
#KT-7695 Fixed
(cherry picked from commit 6e7fd19)
2015-06-04 23:05:46 +03:00
Valentin Kipyatkov
48db830501 Fixed EA-60042
(cherry picked from commit 1fa777f)
2015-06-04 23:05:46 +03:00
Valentin Kipyatkov
2c8d32fa84 Fixed EA-65709
(cherry picked from commit 142ee0c)
2015-06-04 23:05:45 +03:00
Ilya Gorbunov
3190df86a5 Change KotlinCleanupInspection display name and description to mention deprecated symbols
(cherry picked from commit 0c1a8ab8ff)
2015-06-04 20:10:51 +03:00
Ilya Gorbunov
7176f8c116 Make proposed split replacement equivalent in behavior with additional dropLastWhile call.
#KT-7887

(cherry picked from commit 9f85fa9720)
2015-06-04 20:10:48 +03:00
Ilya Gorbunov
14c116d2d5 Provide dropLastWhile for Arrays, Lists and Strings.
(cherry picked from commit 9b17220baa)
2015-06-04 20:10:46 +03:00
Ilya Gorbunov
a272b48be4 Provide replacement for methods deprecated in favor of SAM-constructors.
Provide replacement for isNotEmpty on nullable receiver.
JS: Provide SAM-like constructor for Runnable.

(cherry picked from commit 705c9089f0)
2015-06-04 20:10:44 +03:00
Ilya Gorbunov
7283bf39dd Provide lineSequence() extension method instead of BufferedReader.lines() in order not to conflict with JDK8 instance method with the same name.
(cherry picked from commit 13c89b7ae9)
2015-06-04 20:10:42 +03:00
Ilya Gorbunov
4bf306b754 Do not call mkdirs when destination file of copyTo doesn't have any parent directory.
#KT-7888 Fixed

(cherry picked from commit 0302dd06f7)
2015-06-04 20:10:40 +03:00
Natalia Ukhorskaya
512d671ea0 Rewrite KotlinOutputParser for Android plugin to make it works with Android Studio 1.3
#KT-7862 Fixed
(cherry picked from commit b4190fb)
2015-06-04 19:26:24 +03:00
Natalia Ukhorskaya
51b2d9a15e Workaround for bug in Android Plugin: it generates LightFields for files starting from '.' (ex. .DS_Store file)
#KT-6625 Fixed
(cherry picked from commit 7b63dd9)
2015-06-04 17:19:29 +03:00
Natalia Ukhorskaya
c5e47d9ebf Fix EA-63657
(cherry picked from commit 094119e)
2015-06-04 17:19:11 +03:00
Natalia Ukhorskaya
50028b203c Support com.android.tools.build.gradle 1.3.0-beta1
#KT-7884 Fixed
(cherry picked from commit 1334f03)
2015-06-04 17:18:26 +03:00
Natalia Ukhorskaya
d945388d88 Fix navigation to file from "breakpoint reached at" info
(cherry picked from commit 31db945)
2015-06-04 17:18:15 +03:00
Denis Zharkov
ffd367613c Remove variables with empty ranges from local vars table
As their ranges may intersect after dead code elimination that leads to VerifyError
2015-06-04 16:16:37 +03:00
Denis Zharkov
af98c00558 Minor, Rename InsnStream -> InsnSequence 2015-06-04 16:16:37 +03:00
Denis Zharkov
d893fe7655 EA-53937: Drop failing assertion about no-name val in annotation 2015-06-04 16:16:37 +03:00
Denis Zharkov
a15a5d7b74 Introduce UNKNOWN visibility as default in FunctionDescriptor
It's needed to prevent NPE when requesting non-nullable visibility of descriptor
before `initialize` has been called.
Currently it happens because of indirect calls of `DescriptorUtils.isLocal`
between descriptor creation and it's initialization.
2015-06-04 16:16:37 +03:00
Denis Zharkov
37f6009fdd Fix DescriptorUtils.isLocal semantics
Non-member descriptors, e.g. type parameters, value parameters that defined in local function should be local too
Otherwise a lot of exceptions happens when resolving references within anonymous objects
2015-06-04 16:16:37 +03:00
Nikolay Krasko
299d429407 Remove getting stacktrace in internal mode 2015-06-04 15:37:46 +03:00
Valentin Kipyatkov
ca11ef3968 Minor code improvements + more correct code
(cherry picked from commit a3a33ce)
2015-06-04 01:16:11 +03:00
Valentin Kipyatkov
5094d74496 Replace "||" with "&&" (and the opposite) made more clever about negating expressions
(cherry picked from commit 9c0d607)
2015-06-04 01:16:01 +03:00
Valentin Kipyatkov
74464f2fef KT-7454 Replace "||" with "&&" adds unnecessary parethesis
#KT-7454 Fixed
(cherry picked from commit ac6ef6b)
2015-06-04 01:15:54 +03:00
Valentin Kipyatkov
73f178185c Maybe it will fix EA-67317
(cherry picked from commit 1a0f8a5)
2015-06-04 01:15:46 +03:00
Valentin Kipyatkov
6f1f82e5cb Fixed EA-66035
(cherry picked from commit b73ebad)
2015-06-04 01:15:36 +03:00
Valentin Kipyatkov
edf030d1b7 Fixed EA-66835
(cherry picked from commit fd4a634)
2015-06-04 01:15:22 +03:00
Valentin Kipyatkov
12eaf709e8 Added diagnostic for EA-68663
(cherry picked from commit cd68cef)
2015-06-04 01:14:43 +03:00
Valentin Kipyatkov
dd6f1a24e6 Fixed EA-68869
(cherry picked from commit 7be59f9)
2015-06-04 01:14:36 +03:00
Valentin Kipyatkov
322d7b2e43 Never invoke intention action when it's not available
(cherry picked from commit 662cc32)
2015-06-04 01:14:29 +03:00
Valentin Kipyatkov
7500181abb Fixed EA-68922
(cherry picked from commit 9b32bb8)
2015-06-04 01:14:22 +03:00
Valentin Kipyatkov
4f69f658be Fixed EA-68937
(cherry picked from commit 6010876)
2015-06-04 01:14:14 +03:00
Valentin Kipyatkov
5915863a40 DeprecatedSymbolUsageFix: fixed for string template
(cherry picked from commit e60c3f5)
2015-06-04 01:14:04 +03:00
Valentin Kipyatkov
85ab17841e Converted JetExpressionImpl to Kotlin, got rid of code duplication
(cherry picked from commit a5cb1e8)
2015-06-04 01:13:54 +03:00
Valentin Kipyatkov
6532613aa0 DeprecatedCallableAddReplaceWithIntention: fixed for string templates in expression
(cherry picked from commit b012f22)
2015-06-04 01:13:36 +03:00
Valentin Kipyatkov
d2bba0c8b9 DeprecatedSymbolUsageFix: refactored code for easier handling of optional arguments
(cherry picked from commit 07cb0a0)
2015-06-04 01:13:26 +03:00
Valentin Kipyatkov
21d102e667 Edited TODOs
(cherry picked from commit 1fdb442)
2015-06-04 01:13:15 +03:00
Valentin Kipyatkov
258e8300ea DeprecatedSymbolUsageFix: fixed for incorrect annotation arguments
(cherry picked from commit 134621c)
2015-06-04 01:13:06 +03:00
Valentin Kipyatkov
40f8b5a025 Removed code duplication for getting annotation argument
(cherry picked from commit f1d8838)
2015-06-04 01:12:16 +03:00
Valentin Kipyatkov
29398f2150 ConvertFunctionToPropertyIntention and ConvertPropertyToFunctionIntention made low priority
(cherry picked from commit ad624d6)
2015-06-04 01:11:40 +03:00
Valentin Kipyatkov
d7e40fb06c Rewritten ChangeVariableMutabilityFix
#KT-7877 Fixed
(cherry picked from commit 034b74d)
2015-06-04 01:11:14 +03:00
Valentin Kipyatkov
becb75dcc7 Fixed incorrect method
(cherry picked from commit 65383cf)
2015-06-04 01:09:17 +03:00
Zalim Bashorov
88091ff555 Minor in JS backend tests: use checkFooBoxIsOk instead of fooBoxIsValue
(cherry picked from commit bfeaad9)
2015-06-03 19:54:26 +03:00
Zalim Bashorov
e3f7f9402f JS backend: fix equality check for nullable types
* Generate simple check when compare with `null` literal.
* Use Kotlin.equals if type of receiver or argument is nullable.
* Don't call equals method if any of receiver or argument is null (at runtime, not only literal). For more information see KT-4356.

 #KT-7530 fixed
 #KT-7916 fixed
(cherry picked from commit 3006d97)
2015-06-03 19:54:17 +03:00
Zalim Bashorov
754f82296c JS backend: compare enum entries strictly
#KT-7840 fixed
(cherry picked from commit cbea907)
2015-06-03 19:48:24 +03:00
Zalim Bashorov
41b9d10782 JS backend: fix tests after move testTrue and testFalse to common place
(cherry picked from commit c2f6783)
2015-06-03 19:48:16 +03:00
Zalim Bashorov
abce9e0304 Minor in JS backend: move testFalse and testTrue to common place
(cherry picked from commit 324861e)
2015-06-03 19:48:08 +03:00
Zalim Bashorov
3c78547b67 JS backend: fix compiler crash on for with empty body
(cherry picked from commit 993a1eb)
2015-06-03 19:47:35 +03:00
Zalim Bashorov
b5f8f55cf4 JS backend: fix compiler crash on empty then if block
#EA-68941 fixed
(cherry picked from commit 1534676)
2015-06-03 19:47:24 +03:00
Zalim Bashorov
18848afe2c JS backend: support secondary constructors in native classes
(cherry picked from commit 53ff350)
2015-06-03 19:47:02 +03:00
Alexander Udalov
0252137b0b Fix heavy integer parsing in FunctionN class factory
#KT-7924 Fixed
2015-06-03 15:39:17 +03:00
Alexey Sedunov
53945d88e7 Call Hierachy: Fix NPE
#EA-67995 Fixed
2015-06-03 12:56:44 +03:00
Alexey Sedunov
e1ff588f6c Light Elements: Filter out nulls when converting Kotlin declarations to corresponding light elements
#EA-64403 Fixed
2015-06-03 12:56:37 +03:00
Alexey Sedunov
b972aac300 Find Usages: Fix NPE
#EA-64275 Fixed
2015-06-03 12:56:30 +03:00
Alexey Sedunov
5c346effe8 Call Hierarchy: Forbid PsiClass at the hierarchy root
#EA-64406 Fixed
2015-06-03 12:56:22 +03:00
Alexander Udalov
590e2cceea Support annotations as annotation arguments in reflection, add test
A follow-up to 281acb8 where this was supported in the compiler
2015-06-02 17:33:25 +03:00
Alexander Udalov
539458c596 Make parameter names of fictitious function classes non-stable
To be able to change them when overriding invoke in subclasses without a
warning
2015-06-02 17:33:11 +03:00
Alexander Udalov
7f0a5d4fe2 Fix NoSuchMethodError on FunctionReference#init 2015-06-02 17:31:53 +03:00
Denis Zharkov
b6789e03f4 Fix wrong assumptions in quickfix
Diagnostic is always reported on overriden property

 #EA-64407 Fixed
2015-06-02 14:15:47 +03:00
Denis Zharkov
9bac98e906 Drop wrong assertion about duplicating properties in data class
#EA-64269 Fixed
2015-06-02 14:15:47 +03:00
Denis Zharkov
e978221c5e Resolve constructors declared in traits and objects
It prevents exceptions and produces less red code

 #EA-68667 Fixed
2015-06-02 14:15:47 +03:00
Denis Zharkov
ced1f6662c Refine diagnostics reported on primary constructors 2015-06-02 14:15:47 +03:00
Denis Zharkov
8f1176413c Parsing: allow primary ctor in object syntactically
It's needed for better recovering for cases of changes like 'class' -> 'object'

The only sensible case when it's may be bad:
class A {
   object B
   constructor() : super()
}

But it seems to be rare, and ';' can be used to separate object from secondary ctor
2015-06-02 14:15:47 +03:00
Denis Zharkov
400fae3053 Do not report diagnostic "ctr in trait" in delegation specifier
Constructor declaration in interfaces is prohibited anyway
2015-06-02 14:15:47 +03:00
Denis Zharkov
032a9a20cd Do not wrap primary ctor of object into ErrorElement
It helps to resolve them as for classes
Diagnostic with same content will be reported instead
2015-06-02 14:15:47 +03:00
Denis Zharkov
60356ba15d Get rid of assumption that primary ctr is a child of JetClass
As it can be contained within JetObjectDeclaration
2015-06-02 14:15:46 +03:00
Denis Zharkov
517ae669e9 Prettify JetClass and JetObjectDeclaration 2015-06-02 14:13:10 +03:00
Denis Zharkov
df48447009 Pull constructor-related methods from JetClass to JetClassOrObject 2015-06-02 14:13:10 +03:00
Denis Zharkov
7b46abd43f Make JetClassOrObject an abstract class implementing common methods 2015-06-02 14:13:09 +03:00
Denis Zharkov
b8f80f21b2 Convert JetClassOrObject and inheritors: J2K 2015-06-02 14:13:09 +03:00
Denis Zharkov
3c95349019 Convert JetClassOrObject and inheritors: .java -> .kt 2015-06-02 14:13:09 +03:00
Alexander Udalov
4898cd0419 Do not report irrelevant diagnostics on unresolved supertypes
Previously the confusing "trait with superclass" was reported when an
unresolved classifier appeared in interface supertypes
2015-06-02 12:34:50 +03:00
Alexander Udalov
8470ad48dc Minor, drop unused properties in libraries/pom.xml
Also regroup for clarity
2015-06-02 12:34:49 +03:00
Alexander Udalov
11c988dabc Copy kotlin-reflect.jar from dist to publish to Maven
Also build sources jar in build.xml to publish as kotlin-reflect's sources, and
create an empty javadoc
2015-06-02 12:34:47 +03:00
Alexander Udalov
c7f28d30c0 Minor, update URL and fix typo in maven project description 2015-06-02 12:34:46 +03:00
Alexander Udalov
f87e2cd2c5 Add kotlin-reflect.jar to targets in build.xml 2015-06-02 12:34:44 +03:00
Alexander Udalov
35ae6b4941 Report 'free function called as extension' on Function subclasses
You can't make a value of some type invokable as an extension by adding
'extension' annotation to the type
2015-06-01 19:26:09 +03:00
Alexander Udalov
846cfe4531 Fix abstract method error: implement arity in function references 2015-06-01 19:26:04 +03:00
Alexander Udalov
c7669d31dd Minor, move compiler.pro out of project root 2015-06-01 19:25:58 +03:00
Alexander Udalov
01c6ced2f8 Do not generate annotations of method parameters on its $default synthetic method
#KT-7892 Fixed
2015-06-01 19:25:50 +03:00
Alexander Udalov
54f76c8d3e Minor, move constant to the proper place 2015-06-01 19:25:45 +03:00
Alexander Udalov
9377e6b914 Fix initialization order of enum entries and companion
#KT-5761 Fixed
2015-06-01 19:25:41 +03:00
Alexander Udalov
78847a961e Check compileJavaAgainstKotlin tests with .txt files 2015-06-01 19:25:22 +03:00
Zalim Bashorov
f996476000 JS backend: fix missed variable declarations for tmps in class primary/default constructor
#KT-7864 Fixed
(cherry picked from commit baf7406)
2015-05-29 17:55:58 +03:00
Alexander Udalov
9bcc9fbddc Fix ISE when caret is on parameter of function type
EA-68570
2015-05-28 21:29:29 +03:00
Valentin Kipyatkov
3de3c0fb88 DeprecatedSymbolUsageFix to not be available for functions with optional parameters and no sources 2015-05-28 19:55:44 +03:00
Valentin Kipyatkov
e40fa4da95 Corrected test data 2015-05-28 19:55:44 +03:00
Valentin Kipyatkov
7b04b939aa DeprecatedSymbolUsageFix: changed from descriptors to import back to fq-names as it's more safe 2015-05-28 19:55:44 +03:00
Valentin Kipyatkov
992a174dea Fixed DeprecatedSymbolUsageInWholeProjectFix 2015-05-28 19:55:44 +03:00
Valentin Kipyatkov
50aae7b49e Fixed AbstractQuickFixMultiFileTest badly broken sometime ago 2015-05-28 19:55:43 +03:00
501 changed files with 6679 additions and 3615 deletions

View File

@@ -270,7 +270,6 @@
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
</indentOptions>

14
.idea/libraries/ant.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="ant">
<ANNOTATIONS>
<root url="file://$PROJECT_DIR$/annotations" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$PROJECT_DIR$/dependencies/ant-1.8/lib/ant.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/apache-ant-1.8.2-src.zip!/apache-ant-1.8.2/src/main" />
</SOURCES>
</library>
</component>

View File

@@ -1,21 +0,0 @@
<component name="libraryTable">
<library name="ant-1.7">
<ANNOTATIONS>
<root url="file://$PROJECT_DIR$/annotations" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$PROJECT_DIR$/dependencies/ant-1.7/lib/ant.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/apache-ant-1.7.0-src.zip!/apache-ant-1.7.0/src/etc/testcases/core/loaderref/src" />
<root url="jar://$PROJECT_DIR$/dependencies/apache-ant-1.7.0-src.zip!/apache-ant-1.7.0/src/etc/testcases/core/containersrc" />
<root url="jar://$PROJECT_DIR$/dependencies/apache-ant-1.7.0-src.zip!/apache-ant-1.7.0/src/etc/testcases/types/assertions" />
<root url="jar://$PROJECT_DIR$/dependencies/apache-ant-1.7.0-src.zip!/apache-ant-1.7.0/src/etc/testcases/taskdefs/apt" />
<root url="jar://$PROJECT_DIR$/dependencies/apache-ant-1.7.0-src.zip!/apache-ant-1.7.0/src/etc/testcases/taskdefs/rmic/src" />
<root url="jar://$PROJECT_DIR$/dependencies/apache-ant-1.7.0-src.zip!/apache-ant-1.7.0/src/etc/testcases/taskdefs/fixcrlf/input" />
<root url="jar://$PROJECT_DIR$/dependencies/apache-ant-1.7.0-src.zip!/apache-ant-1.7.0/src/etc/testcases/taskdefs/fixcrlf/expected" />
<root url="jar://$PROJECT_DIR$/dependencies/apache-ant-1.7.0-src.zip!/apache-ant-1.7.0/src/main" />
</SOURCES>
</library>
</component>

View File

@@ -7,7 +7,7 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="ant-1.7" level="project" />
<orderEntry type="library" name="ant" level="project" />
<orderEntry type="library" name="kotlin-runtime" level="project" />
<orderEntry type="module" module-name="preloader" />
</component>

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ant
import org.apache.tools.ant.AntClassLoader
import org.jetbrains.kotlin.preloading.ClassPreloadingUtils
import java.io.File
import java.lang.ref.SoftReference
import java.net.JarURLConnection
import kotlin.properties.Delegates
object KotlinAntTaskUtil {
private var classLoaderRef = SoftReference<ClassLoader?>(null)
private val libPath: File by Delegates.lazy {
// Find path of kotlin-ant.jar in the filesystem and find kotlin-compiler.jar in the same directory
val resourcePath = "/" + javaClass.getName().replace('.', '/') + ".class"
val jarConnection = javaClass.getResource(resourcePath).openConnection() as? JarURLConnection
?: throw UnsupportedOperationException("Kotlin compiler Ant task should be loaded from the JAR file")
val antTaskJarPath = File(jarConnection.getJarFileURL().toURI())
antTaskJarPath.getParentFile()
}
val compilerJar: File by Delegates.lazy {
File(libPath, "kotlin-compiler.jar").assertExists()
}
val runtimeJar: File by Delegates.lazy {
File(libPath, "kotlin-runtime.jar").assertExists()
}
private fun File.assertExists(): File {
if (!this.exists()) {
throw IllegalStateException("${getName()} is not found in the directory of Kotlin Ant task")
}
return this
}
synchronized fun getOrCreateClassLoader(): ClassLoader {
val cached = classLoaderRef.get()
if (cached != null) return cached
val myLoader = javaClass.getClassLoader()
if (myLoader !is AntClassLoader) return myLoader
val classLoader = ClassPreloadingUtils.preloadClasses(listOf(compilerJar), 4096, myLoader, null)
classLoaderRef = SoftReference(classLoader)
return classLoader
}
}

View File

@@ -16,14 +16,29 @@
package org.jetbrains.kotlin.ant;
import kotlin.KotlinPackage;
import kotlin.jvm.functions.Function1;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.MagicNames;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter;
import org.apache.tools.ant.taskdefs.compilers.Javac13;
import org.apache.tools.ant.taskdefs.condition.AntVersion;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.apache.tools.ant.Project.MSG_WARN;
public class KotlinCompilerAdapter extends Javac13 {
private static final List<String> KOTLIN_EXTENSIONS = Arrays.asList("kt", "kts");
public class KotlinCompilerAdapter extends DefaultCompilerAdapter {
private Path externalAnnotations;
public List<Commandline.Argument> additionalArguments = new ArrayList<Commandline.Argument>(0);
public void setExternalAnnotations(Path externalAnnotations) {
this.externalAnnotations = externalAnnotations;
@@ -36,22 +51,93 @@ public class KotlinCompilerAdapter extends DefaultCompilerAdapter {
return externalAnnotations.createPath();
}
public Commandline.Argument createCompilerArg() {
Commandline.Argument argument = new Commandline.Argument();
additionalArguments.add(argument);
return argument;
}
@Override
public String[] getSupportedFileExtensions() {
List<String> result = KotlinPackage.plus(Arrays.asList(super.getSupportedFileExtensions()), KOTLIN_EXTENSIONS);
//noinspection SSBasedInspection
return result.toArray(new String[result.size()]);
}
@Override
public boolean execute() throws BuildException {
Javac javac = getJavac();
Kotlin2JvmTask kotlinTask = new Kotlin2JvmTask();
kotlinTask.setOutput(javac.getDestdir());
kotlinTask.setClasspath(javac.getClasspath());
kotlinTask.setSrc(javac.getSrcdir());
kotlinTask.setExternalAnnotations(externalAnnotations);
checkAntVersion();
kotlinTask.execute();
Kotlin2JvmTask kotlinc = new Kotlin2JvmTask();
kotlinc.setFailOnError(javac.getFailonerror());
kotlinc.setOutput(javac.getDestdir());
Path classpath = javac.getClasspath();
if (classpath != null) {
kotlinc.setClasspath(classpath);
}
// We use the provided src dir instead of compileList, because the latter is insane:
// it is constructed only of sources which are newer than classes with the same name
kotlinc.setSrc(javac.getSrcdir());
kotlinc.setExternalAnnotations(externalAnnotations);
kotlinc.getAdditionalArguments().addAll(additionalArguments);
kotlinc.execute();
if (!Integer.valueOf(0).equals(kotlinc.getExitCode())) {
// Don't run javac if failOnError = false and there were errors on Kotlin sources
return false;
}
javac.log("Running javac...");
Javac13 javac13 = new Javac13();
javac13.setJavac(javac);
return javac13.execute();
// Javac13#execute passes everything in compileList to javac, which doesn't recognize .kt files
compileList = filterOutKotlinSources(compileList);
addRuntimeToJavacClasspath(kotlinc);
return compileList.length == 0 || super.execute();
}
private void addRuntimeToJavacClasspath(@NotNull Kotlin2JvmTask kotlinc) {
for (String arg : kotlinc.getArgs()) {
// If "-no-stdlib" was specified explicitly, probably the user also wanted the javac classpath to not have it
if ("-no-stdlib".equals(arg)) return;
}
if (compileClasspath == null) {
compileClasspath = new Path(getProject());
}
compileClasspath.add(new Path(getProject(), KotlinAntTaskUtil.INSTANCE$.getRuntimeJar().getAbsolutePath()));
}
private void checkAntVersion() {
AntVersion checkVersion = new AntVersion();
checkVersion.setAtLeast("1.8.2");
if (!checkVersion.eval()) {
getJavac().log("<withKotlin> task requires Ant of version at least 1.8.2 to operate reliably. " +
"Please upgrade or, as a workaround, make sure you have at least one Java source and " +
"the output directory is clean before running this task. " +
"You have: " + getProject().getProperty(MagicNames.ANT_VERSION), MSG_WARN);
}
}
@NotNull
private static File[] filterOutKotlinSources(@NotNull File[] files) {
List<File> nonKotlinSources = KotlinPackage.filterNot(files, new Function1<File, Boolean>() {
@Override
public Boolean invoke(File file) {
for (String extension : KOTLIN_EXTENSIONS) {
if (file.getPath().endsWith("." + extension)) return true;
}
return false;
}
});
return nonKotlinSources.toArray(new File[nonKotlinSources.size()]);
}
}

View File

@@ -16,45 +16,13 @@
package org.jetbrains.kotlin.ant
import org.apache.tools.ant.BuildException
import org.apache.tools.ant.Task
import org.apache.tools.ant.types.Commandline
import org.apache.tools.ant.types.Path
import org.apache.tools.ant.types.Reference
import java.io.File
import org.apache.tools.ant.BuildException
import org.apache.tools.ant.types.Commandline
import java.io.PrintStream
import org.apache.tools.ant.AntClassLoader
import java.lang.ref.SoftReference
import org.jetbrains.kotlin.preloading.ClassPreloadingUtils
import java.net.JarURLConnection
object CompilerClassLoaderHolder {
private var classLoaderRef = SoftReference<ClassLoader?>(null)
synchronized fun getOrCreateClassLoader(): ClassLoader {
val cached = classLoaderRef.get()
if (cached != null) return cached
val myLoader = javaClass.getClassLoader()
if (myLoader !is AntClassLoader) return myLoader
// Find path of kotlin-ant.jar in the filesystem and find kotlin-compiler.jar in the same directory
val resourcePath = "/" + javaClass.getName().replace('.', '/') + ".class"
val jarConnection = javaClass.getResource(resourcePath).openConnection() as? JarURLConnection
?: throw UnsupportedOperationException("Kotlin compiler Ant task should be loaded from the JAR file")
val antTaskJarPath = File(jarConnection.getJarFileURL().toURI())
val compilerJarPath = File(antTaskJarPath.getParent(), "kotlin-compiler.jar")
if (!compilerJarPath.exists()) {
throw IllegalStateException("kotlin-compiler.jar is not found in the directory of Kotlin Ant task")
}
val classLoader = ClassPreloadingUtils.preloadClasses(listOf(compilerJarPath), 4096, myLoader, null)
classLoaderRef = SoftReference(classLoader)
return classLoader
}
}
public abstract class KotlinCompilerBaseTask : Task() {
protected abstract val compilerFqName: String
@@ -66,11 +34,14 @@ public abstract class KotlinCompilerBaseTask : Task() {
public var nowarn: Boolean = false
public var verbose: Boolean = false
public var printVersion: Boolean = false
public var failOnError: Boolean = false
public var noStdlib: Boolean = false
public val additionalArguments: MutableList<Commandline.Argument> = arrayListOf()
internal var exitCode: Int? = null
public fun createSrc(): Path {
val srcPath = src
if (srcPath == null) {
@@ -112,16 +83,16 @@ public abstract class KotlinCompilerBaseTask : Task() {
final override fun execute() {
fillArguments()
val compilerClass = CompilerClassLoaderHolder.getOrCreateClassLoader().loadClass(compilerFqName)
val compilerClass = KotlinAntTaskUtil.getOrCreateClassLoader().loadClass(compilerFqName)
val compiler = compilerClass.newInstance()
val exec = compilerClass.getMethod("execFullPathsInMessages", javaClass<PrintStream>(), javaClass<Array<String>>())
log("Compiling ${src!!.list().toList()} => [${output!!.canonicalPath}]");
val exitCode = exec(compiler, System.err, args.copyToArray())
val result = exec(compiler, System.err, args.toTypedArray())
exitCode = (result as Enum<*>).ordinal()
// TODO: support failOnError attribute of javac
if ((exitCode as Enum<*>).ordinal() != 0) {
if (failOnError && exitCode != 0) {
throw BuildException("Compile failed; see the compiler error output for details.")
}
}

View File

@@ -10,7 +10,7 @@
<property name="max.heap.size.for.forked.jvm" value="1024m"/>
<property name="bootstrap.home" value="dependencies/bootstrap-compiler"/>
<property name="bootstrap.home" value="${basedir}/dependencies/bootstrap-compiler"/>
<property name="bootstrap.compiler.home" value="${bootstrap.home}/Kotlin/kotlinc"/>
<property name="bootstrap.runtime" value="${bootstrap.compiler.home}/lib/kotlin-runtime.jar"/>
<property name="bootstrap.reflect" value="${bootstrap.compiler.home}/lib/kotlin-reflect.jar"/>
@@ -56,6 +56,7 @@
<path id="classpath">
<file file="${bootstrap.runtime}"/>
<file file="${bootstrap.reflect}"/>
<fileset dir="${idea.sdk}" includes="core/*.jar"/>
<pathelement location="${protobuf.jar}"/>
@@ -517,7 +518,7 @@
<available property="jssejar" value="${java.home}/lib/jsse.jar" file="${java.home}/lib/jsse.jar"/>
<available property="jssejar" value="${java.home}/../Classes/jsse.jar" file="${java.home}/../Classes/jsse.jar"/>
<proguard configuration="compiler.pro"/>
<proguard configuration="${basedir}/compiler/compiler.pro"/>
</else>
</if>
@@ -525,6 +526,7 @@
<!-- TODO: don't include both to the jar: it's impossible to test changes to core in the local maven build without bootstrap -->
<zipfileset src="${kotlin-home}/lib/kotlin-compiler.jar" includes="**"/>
<zipfileset src="${bootstrap.runtime}" includes="**" excludes="META-INF/**"/>
<zipfileset src="${bootstrap.reflect}" includes="**" excludes="META-INF/**"/>
<manifest>
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
@@ -549,6 +551,7 @@
<pathelement path="${idea.sdk}/core/intellij-core.jar"/>
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
<pathelement path="${bootstrap.runtime}"/>
<pathelement path="${bootstrap.reflect}"/>
</classpath>
</kotlinc>
@@ -573,7 +576,8 @@
<compilerarg value="-Xlint:all"/>
<classpath>
<file file="${bootstrap.runtime}"/>
<pathelement location="${dependencies.dir}/ant-1.7/lib/ant.jar"/>
<file file="${bootstrap.reflect}"/>
<pathelement location="${dependencies.dir}/ant-1.8/lib/ant.jar"/>
<pathelement location="${kotlin-home}/lib/kotlin-preloader.jar"/>
</classpath>
</javac2>
@@ -823,6 +827,14 @@
<fileset dir="${output}/core.src" includes="**/*"/>
</jar-content>
</pack-runtime-jar>
<pack-runtime-jar jar-dir="${output}" jar-name="kotlin-reflect-sources-for-maven.jar"
implementation-title="${manifest.impl.title.kotlin.jvm.reflect.sources}">
<jar-content>
<fileset dir="${basedir}/core/reflection.jvm/src" includes="**/*"/>
<fileset dir="${output}/core.src" includes="**/*"/>
</jar-content>
</pack-runtime-jar>
</target>
<target name="runtime"

View File

@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.psi.JetElement;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
@@ -337,8 +336,11 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
iv.load(0, superClassAsmType);
if (superClassAsmType.equals(AsmTypes.LAMBDA)) {
iv.iconst(funDescriptor.getValueParameters().size());
if (superClassAsmType.equals(LAMBDA) || superClassAsmType.equals(FUNCTION_REFERENCE)) {
int arity = funDescriptor.getValueParameters().size();
if (funDescriptor.getExtensionReceiverParameter() != null) arity++;
if (funDescriptor.getDispatchReceiverParameter() != null) arity++;
iv.iconst(arity);
iv.invokespecial(superClassAsmType.getInternalName(), "<init>", "(I)V", false);
}
else {

View File

@@ -168,7 +168,8 @@ public class FunctionCodegen {
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
}
generateAnnotationsForMethod(functionDescriptor, asmMethod, mv, true);
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, asmMethod.getReturnType());
generateParameterAnnotations(functionDescriptor, mv, typeMapper.mapSignature(functionDescriptor));
if (state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES) {
generateJetValueParameterAnnotations(mv, functionDescriptor, jvmSignature);
@@ -215,21 +216,10 @@ public class FunctionCodegen {
methodContext.recordSyntheticAccessorIfNeeded(functionDescriptor, bindingContext);
}
private void generateAnnotationsForMethod(
@NotNull FunctionDescriptor functionDescriptor,
Method asmMethod,
MethodVisitor mv,
boolean recordParametersIndices
) {
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, asmMethod.getReturnType());
generateParameterAnnotations(functionDescriptor, mv, typeMapper.mapSignature(functionDescriptor), recordParametersIndices);
}
private void generateParameterAnnotations(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull MethodVisitor mv,
@NotNull JvmMethodSignature jvmSignature,
boolean recordParametersIndices
@NotNull JvmMethodSignature jvmSignature
) {
Iterator<ValueParameterDescriptor> iterator = functionDescriptor.getValueParameters().iterator();
List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getValueParameters();
@@ -244,9 +234,7 @@ public class FunctionCodegen {
if (kind == JvmMethodParameterKind.VALUE) {
ValueParameterDescriptor parameter = iterator.next();
if (recordParametersIndices) {
v.getSerializationBindings().put(INDEX_FOR_VALUE_PARAMETER, parameter, i);
}
v.getSerializationBindings().put(INDEX_FOR_VALUE_PARAMETER, parameter, i);
AnnotationCodegen.forParameter(i, mv, typeMapper).genAnnotations(parameter, parameterSignature.getAsmType());
}
}
@@ -613,7 +601,9 @@ public class FunctionCodegen {
getThrownExceptions(functionDescriptor, typeMapper)
);
generateAnnotationsForMethod(functionDescriptor, defaultMethod, mv, false);
// Only method annotations are copied to the $default method. Parameter annotations are not copied until there are valid use cases;
// enum constructors have two additional synthetic parameters which somewhat complicate this task
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType());
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
if (this.owner instanceof PackageFacadeContext) {

View File

@@ -81,6 +81,7 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getResolvedCall;
@@ -225,6 +226,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor, null);
generateReflectionObjectFieldIfNeeded();
generateEnumEntries();
}
@Override
@@ -360,7 +363,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateSyntheticAccessors();
generateEnumMethodsAndConstInitializers();
generateEnumMethods();
generateFunctionsForDataClasses();
@@ -764,11 +767,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
return constructor;
}
private void generateEnumMethodsAndConstInitializers() {
private void generateEnumMethods() {
if (isEnumClass(descriptor)) {
generateEnumValuesMethod();
generateEnumValueOfMethod();
initializeEnumConstants();
}
}
@@ -1065,6 +1067,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
private void generateSecondaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
if (!canHaveDeclaredConstructors(descriptor)) return;
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
functionCodegen.generateMethod(OtherOrigin(descriptorToDeclaration(constructorDescriptor), constructorDescriptor),
@@ -1615,24 +1619,22 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
@Override
protected void generateDeclaration(JetDeclaration declaration) {
if (declaration instanceof JetEnumEntry) {
String name = declaration.getName();
assert name != null : "Enum entry has no name: " + declaration.getText();
ClassDescriptor entryDescriptor = bindingContext.get(BindingContext.CLASS, declaration);
FieldVisitor fv = v.newField(OtherOrigin(declaration, entryDescriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL,
name, classAsmType.getDescriptor(), null, null);
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(entryDescriptor, null);
myEnumConstants.add((JetEnumEntry) declaration);
private void generateEnumEntries() {
if (descriptor.getKind() != ClassKind.ENUM_CLASS) return;
List<JetEnumEntry> enumEntries = KotlinPackage.filterIsInstance(element.getDeclarations(), JetEnumEntry.class);
for (JetEnumEntry enumEntry : enumEntries) {
ClassDescriptor descriptor = getNotNull(bindingContext, BindingContext.CLASS, enumEntry);
FieldVisitor fv = v.newField(OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL,
descriptor.getName().asString(), classAsmType.getDescriptor(), null, null);
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(descriptor, null);
}
super.generateDeclaration(declaration);
initializeEnumConstants(enumEntries);
}
private final List<JetEnumEntry> myEnumConstants = new ArrayList<JetEnumEntry>();
private void initializeEnumConstants() {
private void initializeEnumConstants(@NotNull List<JetEnumEntry> enumEntries) {
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
ExpressionCodegen codegen = createOrGetClInitCodegen();
@@ -1642,48 +1644,39 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
v.newField(OtherOrigin(myClass), ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, ENUM_VALUES_FIELD_NAME,
arrayAsmType.getDescriptor(), null, null);
iv.iconst(myEnumConstants.size());
iv.iconst(enumEntries.size());
iv.newarray(classAsmType);
if (!myEnumConstants.isEmpty()) {
if (!enumEntries.isEmpty()) {
iv.dup();
for (int ordinal = 0, size = myEnumConstants.size(); ordinal < size; ordinal++) {
initializeEnumConstant(codegen, ordinal);
for (int ordinal = 0, size = enumEntries.size(); ordinal < size; ordinal++) {
initializeEnumConstant(enumEntries, ordinal);
}
}
iv.putstatic(classAsmType.getInternalName(), ENUM_VALUES_FIELD_NAME, arrayAsmType.getDescriptor());
}
private void initializeEnumConstant(@NotNull ExpressionCodegen codegen, int ordinal) {
private void initializeEnumConstant(@NotNull List<JetEnumEntry> enumEntries, int ordinal) {
ExpressionCodegen codegen = createOrGetClInitCodegen();
InstructionAdapter iv = codegen.v;
JetEnumEntry enumConstant = myEnumConstants.get(ordinal);
JetEnumEntry enumEntry = enumEntries.get(ordinal);
iv.dup();
iv.iconst(ordinal);
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, enumConstant);
assert classDescriptor != null;
ClassDescriptor classDescriptor = getNotNull(bindingContext, BindingContext.CLASS, enumEntry);
Type implClass = typeMapper.mapClass(classDescriptor);
List<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers();
if (delegationSpecifiers.size() > 1) {
throw new UnsupportedOperationException("multiple delegation specifiers for enum constant not supported");
}
iv.anew(implClass);
iv.dup();
iv.aconst(enumConstant.getName());
iv.aconst(enumEntry.getName());
iv.iconst(ordinal);
if (delegationSpecifiers.size() == 1 && !enumEntryNeedSubclass(bindingContext, enumConstant)) {
JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
if (!(specifier instanceof JetDelegatorToSuperCall)) {
throw new UnsupportedOperationException("unsupported type of enum constant initializer: " + specifier);
}
ResolvedCall<?> resolvedCall = CallUtilPackage.getResolvedCallWithAssert(specifier, bindingContext);
List<JetDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
if (delegationSpecifiers.size() == 1 && !enumEntryNeedSubclass(bindingContext, enumEntry)) {
ResolvedCall<?> resolvedCall = CallUtilPackage.getResolvedCallWithAssert(delegationSpecifiers.get(0), bindingContext);
CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) resolvedCall.getResultingDescriptor());
@@ -1694,7 +1687,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
iv.dup();
iv.putstatic(classAsmType.getInternalName(), enumConstant.getName(), classAsmType.getDescriptor());
iv.putstatic(classAsmType.getInternalName(), enumEntry.getName(), classAsmType.getDescriptor());
iv.astore(OBJECT_TYPE);
}

View File

@@ -170,7 +170,7 @@ public class PropertyCodegen {
public void generateConstructorPropertyAsMethodForAnnotationClass(JetParameter p, PropertyDescriptor descriptor) {
JvmMethodSignature signature = typeMapper.mapAnnotationParameterSignature(descriptor);
String name = p.getName();
assert name != null : "Annotation parameter has no name: " + p.getText();
if (name == null) return;
MethodVisitor mv = v.newMethod(
OtherOrigin(p, descriptor), ACC_PUBLIC | ACC_ABSTRACT, name,
signature.getAsmMethod().getDescriptor(),

View File

@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.kotlin.codegen.optimization.common.InsnStream
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.org.objectweb.asm.tree.LineNumberNode
import org.jetbrains.org.objectweb.asm.Label
import kotlin.properties.Delegates
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.codegen.SourceInfo
class SMAPAndMethodNode(val node: MethodNode, val classSMAP: SMAP) {
val lineNumbers =
InsnStream(node.instructions.getFirst(), null).stream().filterIsInstance<LineNumberNode>().map {
InsnSequence(node.instructions.getFirst(), null).stream().filterIsInstance<LineNumberNode>().map {
val index = Collections.binarySearch(classSMAP.intervals, RangeMapping(it.line, it.line, 1)) {
value, key ->
if (value.contains(key.dest)) 0 else RangeMapping.Comparator.compare(value, key)

View File

@@ -28,7 +28,7 @@ val AbstractInsnNode.isMeaningful : Boolean get() =
else -> true
}
class InsnStream(val from: AbstractInsnNode, val to: AbstractInsnNode?) : Stream<AbstractInsnNode> {
class InsnSequence(val from: AbstractInsnNode, val to: AbstractInsnNode?) : Sequence<AbstractInsnNode> {
override fun iterator(): Iterator<AbstractInsnNode> {
return object : Iterator<AbstractInsnNode> {
var current: AbstractInsnNode? = from
@@ -44,14 +44,14 @@ class InsnStream(val from: AbstractInsnNode, val to: AbstractInsnNode?) : Stream
fun MethodNode.prepareForEmitting() {
tryCatchBlocks = tryCatchBlocks.filter { tcb ->
InsnStream(tcb.start, tcb.end).any { insn ->
InsnSequence(tcb.start, tcb.end).any { insn ->
insn.isMeaningful
}
}
// local variables with live ranges starting after last meaningful instruction lead to VerifyError
localVariables = localVariables.filter { lv ->
InsnStream(lv.start, instructions.getLast()).any { insn ->
InsnSequence(lv.start, lv.end).any { insn ->
insn.isMeaningful
}
}

View File

@@ -77,10 +77,10 @@ import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationCons
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class JetTypeMapper {
private static final String DEFAULT_CONSTRUCTOR_MARKER_INTERNAL_CLASS_NAME = "kotlin/jvm/internal/DefaultConstructorMarker";
private final BindingContext bindingContext;
private final ClassBuilderMode classBuilderMode;
@@ -780,7 +780,7 @@ public class JetTypeMapper {
int maskArgumentsCount = (argumentsCount + Integer.SIZE - 1) / Integer.SIZE;
String additionalArgs = StringUtil.repeat(Type.INT_TYPE.getDescriptor(), maskArgumentsCount);
if (isConstructor(method)) {
additionalArgs += Type.getObjectType(DEFAULT_CONSTRUCTOR_MARKER_INTERNAL_CLASS_NAME).getDescriptor();
additionalArgs += DEFAULT_CONSTRUCTOR_MARKER.getDescriptor();
}
String result = descriptor.replace(")", additionalArgs + ")");
if (dispatchReceiverDescriptor != null && !isConstructor(method)) {

View File

@@ -109,7 +109,14 @@ public class JavaClassImpl extends JavaClassifierImpl<PsiClass> implements JavaC
@Override
@NotNull
public Collection<JavaField> getFields() {
return fields(getPsi().getFields());
// ex. Android plugin generates LightFields for resources started from '.' (.DS_Store file etc)
return fields(KotlinPackage.filter(getPsi().getFields(), new Function1<PsiField, Boolean>() {
@Override
public Boolean invoke(PsiField field) {
String name = field.getName();
return name != null && Name.isValidIdentifier(name);
}
}));
}
@Override

View File

@@ -183,7 +183,7 @@ public class JavaElementCollectionFromPsiArrayUtil {
}
@NotNull
public static Collection<JavaField> fields(@NotNull PsiField[] fields) {
public static Collection<JavaField> fields(@NotNull Iterable<PsiField> fields) {
return convert(fields, Factories.FIELDS);
}

View File

@@ -59,6 +59,8 @@ public class AsmTypes {
public static final String REF_TYPE_PREFIX = "kotlin/jvm/internal/Ref$";
public static final Type OBJECT_REF_TYPE = Type.getObjectType(REF_TYPE_PREFIX + "ObjectRef");
public static final Type DEFAULT_CONSTRUCTOR_MARKER = Type.getObjectType("kotlin/jvm/internal/DefaultConstructorMarker");
@NotNull
private static Type reflect(@NotNull String className) {
return Type.getObjectType("kotlin/reflect/" + className);

View File

@@ -674,7 +674,7 @@ public class JetFlowInformationProvider {
}
else if (owner instanceof JetPrimaryConstructor) {
if (!((JetParameter) element).hasValOrVarNode() &&
!((JetPrimaryConstructor) owner).getContainingClass().isAnnotation()) {
!((JetPrimaryConstructor) owner).getContainingClassOrObject().isAnnotation()) {
report(Errors.UNUSED_PARAMETER.on((JetParameter) element, variableDescriptor), ctxt);
}
}

View File

@@ -16,15 +16,14 @@
package org.jetbrains.kotlin.cfg.pseudocode
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import com.intellij.util.SmartFMap
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.JetTypeChecker
public trait TypePredicate: (JetType) -> Boolean {
[suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")]
override fun invoke(typeToCheck: JetType): Boolean
}

View File

@@ -192,7 +192,7 @@ public fun JetElement.getContainingPseudocode(context: BindingContext): Pseudoco
?: return null
val enclosingPseudocodeDeclaration = (pseudocodeDeclaration as? JetFunctionLiteral)?.let {
it.parents(withItself = false).firstOrNull { it is JetDeclaration && it !is JetFunctionLiteral } as? JetDeclaration
it.parents.firstOrNull { it is JetDeclaration && it !is JetFunctionLiteral } as? JetDeclaration
} ?: pseudocodeDeclaration
val enclosingPseudocode = PseudocodeUtil.generatePseudocode(enclosingPseudocodeDeclaration, context)

View File

@@ -165,7 +165,7 @@ public interface Errors {
DiagnosticFactory0<JetConstructorDelegationReferenceExpression> CYCLIC_CONSTRUCTOR_DELEGATION_CALL = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetSecondaryConstructor> SECONDARY_CONSTRUCTOR_IN_OBJECT = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetDeclaration> CONSTRUCTOR_IN_OBJECT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<JetDelegatorToSuperCall> SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetConstructorDelegationCall> PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED =
@@ -188,7 +188,7 @@ public interface Errors {
.create(WARNING, modifierSetPosition(JetTokens.OPEN_KEYWORD));
DiagnosticFactory0<JetModifierListOwner> TRAIT_CAN_NOT_BE_FINAL = DiagnosticFactory0.create(ERROR, FINAL_MODIFIER);
DiagnosticFactory0<PsiElement> CONSTRUCTOR_IN_TRAIT = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetDeclaration> CONSTRUCTOR_IN_TRAIT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<PsiElement> SUPERTYPE_INITIALIZED_IN_TRAIT = DiagnosticFactory0.create(ERROR);
@@ -397,7 +397,12 @@ public interface Errors {
DiagnosticFactory0<JetReferenceExpression> ARGUMENT_PASSED_TWICE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<JetReferenceExpression, JetReferenceExpression> NAMED_PARAMETER_NOT_FOUND =
DiagnosticFactory1.create(ERROR, FOR_UNRESOLVED_REFERENCE);
DiagnosticFactory0<PsiElement> NAMED_ARGUMENTS_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, BadNamedArgumentsTarget> NAMED_ARGUMENTS_NOT_ALLOWED = DiagnosticFactory1.create(ERROR);
enum BadNamedArgumentsTarget {
NON_KOTLIN_FUNCTION,
INVOKE_ON_FUNCTION_TYPE
}
DiagnosticFactory0<JetExpression> VARARG_OUTSIDE_PARENTHESES = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<LeafPsiElement> NON_VARARG_SPREAD = DiagnosticFactory0.create(ERROR);

View File

@@ -156,6 +156,11 @@ public object PositioningStrategies {
is JetObjectDeclaration -> {
return DECLARATION_NAME.mark(element)
}
is JetPrimaryConstructor -> {
val begin = element.getConstructorKeyword() ?: element.getValueParameterList() ?: return markElement(element)
val end = element.getValueParameterList() ?: element.getConstructorKeyword()
return markRange(begin, end)
}
is JetSecondaryConstructor -> {
return markRange(element.getConstructorKeyword(), element.getValueParameterList() ?: element.getConstructorKeyword())
}

View File

@@ -155,7 +155,21 @@ public class DefaultErrorMessages {
MAP.put(MIXING_NAMED_AND_POSITIONED_ARGUMENTS, "Mixing named and positioned arguments is not allowed");
MAP.put(ARGUMENT_PASSED_TWICE, "An argument is already passed for this parameter");
MAP.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", ELEMENT_TEXT);
MAP.put(NAMED_ARGUMENTS_NOT_ALLOWED, "Named arguments are not allowed for non-Kotlin functions");
MAP.put(NAMED_ARGUMENTS_NOT_ALLOWED, "Named arguments are not allowed for {0}", new Renderer<BadNamedArgumentsTarget>() {
@NotNull
@Override
public String render(@NotNull BadNamedArgumentsTarget target) {
switch (target) {
case NON_KOTLIN_FUNCTION:
return "non-Kotlin functions";
case INVOKE_ON_FUNCTION_TYPE:
return "function types";
default:
throw new AssertionError(target);
}
}
});
MAP.put(VARARG_OUTSIDE_PARENTHESES, "Passing value as a vararg is only allowed inside a parenthesized argument list");
MAP.put(NON_VARARG_SPREAD, "The spread operator (*foo) may only be applied in a vararg position");
@@ -402,7 +416,7 @@ public class DefaultErrorMessages {
MAP.put(SINGLETON_IN_SUPERTYPE, "Cannot inherit from a singleton");
MAP.put(CYCLIC_CONSTRUCTOR_DELEGATION_CALL, "There's a cycle in the delegation calls chain");
MAP.put(SECONDARY_CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects");
MAP.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects");
MAP.put(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR, "Supertype initialization is impossible without primary constructor");
MAP.put(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED, "Primary constructor call expected");
MAP.put(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR, "Call to super is not allowed in enum constructor");

View File

@@ -705,14 +705,18 @@ public class JetParsing extends AbstractJetParsing {
* class
* : modifiers ("class" | "interface") SimpleName
* typeParameters?
* modifiers ("(" primaryConstructorParameter{","} ")")?
* primaryConstructor?
* (":" annotations delegationSpecifier{","})?
* typeConstraints
* (classBody? | enumClassBody)
* ;
*
* primaryConstructor
* : (modifiers "constructor")? ("(" functionParameter{","} ")")
* ;
*
* object
* : "object" SimpleName? ":" delegationSpecifier{","}? classBody?
* : "object" SimpleName? primaryConstructor? ":" delegationSpecifier{","}? classBody?
* ;
*/
IElementType parseClassOrObject(
@@ -754,7 +758,6 @@ public class JetParsing extends AbstractJetParsing {
boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
typeParamsMarker.error("Type parameters are not allowed for objects");
OptionalMarker constructorModifiersMarker = new OptionalMarker(object);
PsiBuilder.Marker beforeConstructorModifiers = mark();
PsiBuilder.Marker primaryConstructorMarker = mark();
boolean hasConstructorModifiers = parseModifierList(
@@ -762,9 +765,8 @@ public class JetParsing extends AbstractJetParsing {
);
// Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
if ((object && at(CONSTRUCTOR_KEYWORD)) || (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON, CONSTRUCTOR_KEYWORD))) {
if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON, CONSTRUCTOR_KEYWORD)) {
beforeConstructorModifiers.rollbackTo();
constructorModifiersMarker.drop();
return object ? OBJECT_DECLARATION : CLASS;
}
@@ -796,7 +798,6 @@ public class JetParsing extends AbstractJetParsing {
else {
primaryConstructorMarker.drop();
}
constructorModifiersMarker.error("Constructors are not allowed for objects");
if (at(COLON)) {
advance(); // COLON

View File

@@ -1,259 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.JetNodeTypes;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.stubs.KotlinClassStub;
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class JetClass extends JetTypeParameterListOwnerStub<KotlinClassStub> implements JetClassOrObject {
public JetClass(@NotNull ASTNode node) {
super(node);
}
public JetClass(@NotNull KotlinClassStub stub) {
super(stub, JetStubElementTypes.CLASS);
}
@NotNull
@Override
public List<JetDeclaration> getDeclarations() {
JetClassBody body = getBody();
if (body == null) return Collections.emptyList();
return body.getDeclarations();
}
@Override
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitClass(this, data);
}
@Nullable
public JetPrimaryConstructor getPrimaryConstructor() {
return getStubOrPsiChild(JetStubElementTypes.PRIMARY_CONSTRUCTOR);
}
@Nullable
public JetParameterList getPrimaryConstructorParameterList() {
JetPrimaryConstructor primaryConstructor = getPrimaryConstructor();
return primaryConstructor != null ? primaryConstructor.getValueParameterList() : null;
}
@NotNull
public List<JetParameter> getPrimaryConstructorParameters() {
JetParameterList list = getPrimaryConstructorParameterList();
if (list == null) return Collections.emptyList();
return list.getParameters();
}
@NotNull
public JetPrimaryConstructor createPrimaryConstructorIfAbsent() {
JetPrimaryConstructor constructor = getPrimaryConstructor();
if (constructor != null) return constructor;
PsiElement anchor = getTypeParameterList();
if (anchor == null) anchor = getNameIdentifier();
if (anchor == null) anchor = getLastChild();
return (JetPrimaryConstructor) addAfter(new JetPsiFactory(getProject()).createPrimaryConstructor(), anchor);
}
@NotNull
public JetParameterList createPrimaryConstructorParameterListIfAbsent() {
JetPrimaryConstructor constructor = createPrimaryConstructorIfAbsent();
JetParameterList parameterList = constructor.getValueParameterList();
if (parameterList != null) return parameterList;
return (JetParameterList) constructor.add(new JetPsiFactory(getProject()).createParameterList("()"));
}
@Override
@Nullable
public JetDelegationSpecifierList getDelegationSpecifierList() {
return getStubOrPsiChild(JetStubElementTypes.DELEGATION_SPECIFIER_LIST);
}
@Override
@NotNull
public List<JetDelegationSpecifier> getDelegationSpecifiers() {
JetDelegationSpecifierList list = getDelegationSpecifierList();
return list != null ? list.getDelegationSpecifiers() : Collections.<JetDelegationSpecifier>emptyList();
}
@Nullable
public JetModifierList getPrimaryConstructorModifierList() {
JetPrimaryConstructor primaryConstructor = getPrimaryConstructor();
return primaryConstructor != null ? primaryConstructor.getModifierList() : null;
}
@Override
@NotNull
public List<JetClassInitializer> getAnonymousInitializers() {
JetClassBody body = getBody();
if (body == null) return Collections.emptyList();
return body.getAnonymousInitializers();
}
public boolean hasExplicitPrimaryConstructor() {
return getPrimaryConstructor() != null;
}
@Override
public JetObjectDeclarationName getNameAsDeclaration() {
return (JetObjectDeclarationName) findChildByType(JetNodeTypes.OBJECT_DECLARATION_NAME);
}
@Override
public JetClassBody getBody() {
return getStubOrPsiChild(JetStubElementTypes.CLASS_BODY);
}
@Nullable
public PsiElement getColon() {
return findChildByType(JetTokens.COLON);
}
public List<JetProperty> getProperties() {
JetClassBody body = getBody();
if (body == null) return Collections.emptyList();
return body.getProperties();
}
public boolean isInterface() {
KotlinClassStub stub = getStub();
if (stub != null) {
return stub.isInterface();
}
return findChildByType(JetTokens.TRAIT_KEYWORD) != null ||
findChildByType(JetTokens.INTERFACE_KEYWORD) != null;
}
public boolean isEnum() {
return hasModifier(JetTokens.ENUM_KEYWORD);
}
public boolean isAnnotation() {
return hasModifier(JetTokens.ANNOTATION_KEYWORD);
}
public boolean isInner() {
return hasModifier(JetTokens.INNER_KEYWORD);
}
@Override
public boolean isEquivalentTo(PsiElement another) {
if (super.isEquivalentTo(another)) {
return true;
}
if (another instanceof JetClass) {
String fq1 = getQualifiedName();
String fq2 = ((JetClass) another).getQualifiedName();
return fq1 != null && fq2 != null && fq1.equals(fq2);
}
return false;
}
@Nullable
private String getQualifiedName() {
KotlinClassStub stub = getStub();
if (stub != null) {
FqName fqName = stub.getFqName();
return fqName == null ? null : fqName.asString();
}
List<String> parts = new ArrayList<String>();
JetClassOrObject current = this;
while (current != null) {
parts.add(current.getName());
current = PsiTreeUtil.getParentOfType(current, JetClassOrObject.class);
}
PsiFile file = getContainingFile();
if (!(file instanceof JetFile)) return null;
String fileQualifiedName = ((JetFile) file).getPackageFqName().asString();
if (!fileQualifiedName.isEmpty()) {
parts.add(fileQualifiedName);
}
Collections.reverse(parts);
return StringUtil.join(parts, ".");
}
@Override
public ItemPresentation getPresentation() {
return ItemPresentationProviders.getItemPresentation(this);
}
@Override
public boolean isTopLevel() {
return getContainingFile() == getParent();
}
@Override
public boolean isLocal() {
KotlinClassStub stub = getStub();
if (stub != null) {
return stub.isLocal();
}
return JetPsiUtil.isLocal(this);
}
@NotNull
public List<JetObjectDeclaration> getCompanionObjects() {
JetClassBody body = getBody();
if (body == null) {
return Collections.emptyList();
}
return body.getAllCompanionObjects();
}
public boolean hasPrimaryConstructor() {
return hasExplicitPrimaryConstructor() || !hasSecondaryConstructors();
}
private boolean hasSecondaryConstructors() {
return !getSecondaryConstructors().isEmpty();
}
@NotNull
public List<JetSecondaryConstructor> getSecondaryConstructors() {
JetClassBody body = getBody();
return body != null ? body.getSecondaryConstructors() : Collections.<JetSecondaryConstructor>emptyList();
}
@Nullable
public PsiElement getClassOrInterfaceKeyword() {
return findChildByType(TokenSet.create(JetTokens.CLASS_KEYWORD, JetTokens.INTERFACE_KEYWORD));
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi
import com.intellij.lang.ASTNode
import com.intellij.navigation.ItemPresentation
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.tree.TokenSet
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.stubs.KotlinClassStub
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes
import java.util.ArrayList
import java.util.Collections
public open class JetClass : JetClassOrObject {
public constructor(node: ASTNode) : super(node)
public constructor(stub: KotlinClassStub) : super(stub, JetStubElementTypes.CLASS)
override fun getStub(): KotlinClassStub? = super.getStub() as? KotlinClassStub
override fun <R, D> accept(visitor: JetVisitor<R, D>, data: D): R {
return visitor.visitClass(this, data)
}
public fun createPrimaryConstructorIfAbsent(): JetPrimaryConstructor {
val constructor = getPrimaryConstructor()
if (constructor != null) return constructor
var anchor: PsiElement? = getTypeParameterList()
if (anchor == null) anchor = getNameIdentifier()
if (anchor == null) anchor = getLastChild()
return addAfter(JetPsiFactory(getProject()).createPrimaryConstructor(), anchor) as JetPrimaryConstructor
}
public fun createPrimaryConstructorParameterListIfAbsent(): JetParameterList {
val constructor = createPrimaryConstructorIfAbsent()
val parameterList = constructor.getValueParameterList()
if (parameterList != null) return parameterList
return constructor.add(JetPsiFactory(getProject()).createParameterList("()")) as JetParameterList
}
public fun getColon(): PsiElement? = findChildByType(JetTokens.COLON)
public fun getProperties(): List<JetProperty> = getBody()?.getProperties().orEmpty()
public fun isInterface(): Boolean =
getStub()?.isInterface()
?: (findChildByType<PsiElement>(JetTokens.TRAIT_KEYWORD) != null || findChildByType<PsiElement>(JetTokens.INTERFACE_KEYWORD) != null)
public fun isEnum(): Boolean = hasModifier(JetTokens.ENUM_KEYWORD)
public fun isInner(): Boolean = hasModifier(JetTokens.INNER_KEYWORD)
override fun isEquivalentTo(another: PsiElement?): Boolean {
if (super.isEquivalentTo(another)) {
return true
}
if (another is JetClass) {
val fq1 = getQualifiedName()
val fq2 = another.getQualifiedName()
return fq1 != null && fq2 != null && fq1 == fq2
}
return false
}
private fun getQualifiedName(): String? {
val stub = getStub()
if (stub != null) {
val fqName = stub.getFqName()
return fqName?.asString()
}
val parts = ArrayList<String>()
var current: JetClassOrObject? = this
while (current != null) {
parts.add(current.getName())
current = PsiTreeUtil.getParentOfType<JetClassOrObject>(current, javaClass<JetClassOrObject>())
}
val file = getContainingFile()
if (file !is JetFile) return null
val fileQualifiedName = file.getPackageFqName().asString()
if (!fileQualifiedName.isEmpty()) {
parts.add(fileQualifiedName)
}
Collections.reverse(parts)
return StringUtil.join(parts, ".")
}
public fun getCompanionObjects(): List<JetObjectDeclaration> = getBody()?.getAllCompanionObjects().orEmpty()
public fun getClassOrInterfaceKeyword(): PsiElement? = findChildByType(TokenSet.create(JetTokens.CLASS_KEYWORD, JetTokens.INTERFACE_KEYWORD))
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi;
import com.intellij.psi.PsiNameIdentifierOwner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.name.Name;
import java.util.List;
public interface JetClassOrObject extends PsiNameIdentifierOwner, JetDeclarationContainer, JetElement, JetModifierListOwner, JetNamedDeclaration {
@Nullable
JetDelegationSpecifierList getDelegationSpecifierList();
@NotNull
List<JetDelegationSpecifier> getDelegationSpecifiers();
@NotNull
List<JetClassInitializer> getAnonymousInitializers();
@Override
@Nullable
Name getNameAsName();
@Override
@Nullable
JetModifierList getModifierList();
@Nullable
JetObjectDeclarationName getNameAsDeclaration();
@Nullable
JetClassBody getBody();
boolean isTopLevel();
boolean isLocal();
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi
import com.intellij.lang.ASTNode
import com.intellij.navigation.ItemPresentation
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.psi.PsiElement
import com.intellij.psi.stubs.IStubElementType
import org.jetbrains.kotlin.JetNodeTypes
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes
abstract public class JetClassOrObject : JetTypeParameterListOwnerStub<KotlinClassOrObjectStub<out JetClassOrObject>>, JetDeclarationContainer, JetNamedDeclaration {
public constructor(node: ASTNode) : super(node)
public constructor(stub: KotlinClassOrObjectStub<out JetClassOrObject>, nodeType: IStubElementType<*, *>) : super(stub, nodeType)
public fun getDelegationSpecifierList(): JetDelegationSpecifierList? = getStubOrPsiChild(JetStubElementTypes.DELEGATION_SPECIFIER_LIST)
open public fun getDelegationSpecifiers(): List<JetDelegationSpecifier> = getDelegationSpecifierList()?.getDelegationSpecifiers().orEmpty()
public fun getAnonymousInitializers(): List<JetClassInitializer> = getBody()?.getAnonymousInitializers().orEmpty()
public fun getNameAsDeclaration(): JetObjectDeclarationName? =
findChildByType<PsiElement>(JetNodeTypes.OBJECT_DECLARATION_NAME) as JetObjectDeclarationName?
public fun getBody(): JetClassBody? = getStubOrPsiChild(JetStubElementTypes.CLASS_BODY)
public fun isTopLevel(): Boolean = getStub()?.isTopLevel() ?: (getParent() is JetFile)
public fun isLocal(): Boolean = getStub()?.isLocal() ?: JetPsiUtil.isLocal(this)
override fun getDeclarations() = getBody()?.getDeclarations().orEmpty()
override fun getPresentation(): ItemPresentation? = ItemPresentationProviders.getItemPresentation(this)
public fun getPrimaryConstructor(): JetPrimaryConstructor? = getStubOrPsiChild(JetStubElementTypes.PRIMARY_CONSTRUCTOR)
public fun getPrimaryConstructorModifierList(): JetModifierList? = getPrimaryConstructor()?.getModifierList()
public fun getPrimaryConstructorParameterList(): JetParameterList? = getPrimaryConstructor()?.getValueParameterList()
public fun getPrimaryConstructorParameters(): List<JetParameter> = getPrimaryConstructorParameterList()?.getParameters().orEmpty()
public fun hasExplicitPrimaryConstructor(): Boolean = getPrimaryConstructor() != null
public fun hasPrimaryConstructor(): Boolean = hasExplicitPrimaryConstructor() || !hasSecondaryConstructors()
private fun hasSecondaryConstructors(): Boolean = !getSecondaryConstructors().isEmpty()
public fun getSecondaryConstructors(): List<JetSecondaryConstructor> = getBody()?.getSecondaryConstructors().orEmpty()
public fun isAnnotation(): Boolean = hasModifier(JetTokens.ANNOTATION_KEYWORD)
}

View File

@@ -1,56 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.JetNodeType;
import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory;
import static org.jetbrains.kotlin.psi.PsiPackage.createExpressionByPattern;
public abstract class JetExpressionImpl extends JetElementImpl implements JetExpression {
public JetExpressionImpl(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitExpression(this, data);
}
protected JetExpression findExpressionUnder(JetNodeType type) {
JetContainerNode containerNode = (JetContainerNode) findChildByType(type);
if (containerNode == null) return null;
return containerNode.findChildByClass(JetExpression.class);
}
//NOTE: duplicate with JetExpressionImplStub
@NotNull
@Override
public PsiElement replace(@NotNull PsiElement newElement) throws IncorrectOperationException {
PsiElement parent = getParent();
if (parent instanceof JetExpression && newElement instanceof JetExpression &&
JetPsiUtil.areParenthesesNecessary((JetExpression) newElement, this, (JetExpression) parent)) {
return super.replace(createExpressionByPattern(JetPsiFactory(this), "($0)", newElement));
}
return super.replace(newElement);
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi
import com.intellij.lang.ASTNode
import com.intellij.psi.PsiElement
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.JetNodeType
public abstract class JetExpressionImpl(node: ASTNode) : JetElementImpl(node), JetExpression {
override fun <R, D> accept(visitor: JetVisitor<R, D>, data: D) = visitor.visitExpression(this, data)
protected fun findExpressionUnder(type: JetNodeType): JetExpression? {
val containerNode = findChildByType<JetContainerNode>(type) ?: return null
return containerNode.findChildByClass<JetExpression>(javaClass())
}
override fun replace(newElement: PsiElement): PsiElement {
return replaceExpression(this, newElement, { super<JetElementImpl>.replace(it) })
}
companion object {
fun replaceExpression(expression: JetExpression, newElement: PsiElement, rawReplaceHandler: (PsiElement) -> PsiElement): PsiElement {
val parent = expression.getParent()
if (newElement is JetExpression) {
when (parent) {
is JetExpression -> {
if (JetPsiUtil.areParenthesesNecessary(newElement, expression, parent)) {
return rawReplaceHandler(JetPsiFactory(expression).createExpressionByPattern("($0)", newElement))
}
}
is JetSimpleNameStringTemplateEntry -> {
if (newElement !is JetSimpleNameExpression) {
val newEntry = parent.replace(JetPsiFactory(expression).createBlockStringTemplateEntry(newElement)) as JetBlockStringTemplateEntry
return newEntry.getExpression()!!
}
}
}
}
return rawReplaceHandler(newElement)
}
}
}

View File

@@ -21,11 +21,9 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.IncorrectOperationException;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory;
import static org.jetbrains.kotlin.psi.PsiPackage.createExpressionByPattern;
public abstract class JetExpressionImplStub<T extends StubElement> extends JetElementImplStub<T> implements JetExpression {
public JetExpressionImplStub(@NotNull T stub, @NotNull IStubElementType nodeType) {
super(stub, nodeType);
@@ -40,15 +38,19 @@ public abstract class JetExpressionImplStub<T extends StubElement> extends JetEl
return visitor.visitExpression(this, data);
}
//NOTE: duplicate with JetExpressionImpl
@NotNull
@Override
public PsiElement replace(@NotNull PsiElement newElement) throws IncorrectOperationException {
PsiElement parent = getParent();
if (parent instanceof JetExpression && newElement instanceof JetExpression &&
JetPsiUtil.areParenthesesNecessary((JetExpression) newElement, this, (JetExpression) parent)) {
return super.replace(createExpressionByPattern(JetPsiFactory(this), "($0)", newElement));
}
return JetExpressionImpl.Companion.replaceExpression(this, newElement, new Function1<PsiElement, PsiElement>() {
@Override
public PsiElement invoke(PsiElement element) {
return rawReplace(element);
}
});
}
@NotNull
private PsiElement rawReplace(@NotNull PsiElement newElement) {
return super.replace(newElement);
}
}

View File

@@ -63,7 +63,7 @@ public final class JetNamedDeclarationUtil {
return getFQName((JetNamedDeclaration) parent);
}
else if (namedDeclaration instanceof JetParameter) {
JetClass constructorClass = JetPsiUtil.getClassIfParameterIsProperty((JetParameter) namedDeclaration);
JetClassOrObject constructorClass = JetPsiUtil.getClassIfParameterIsProperty((JetParameter) namedDeclaration);
if (constructorClass != null) {
return getFQName(constructorClass);
}

View File

@@ -1,189 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.JetNodeTypes;
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.psi.stubs.KotlinObjectStub;
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes;
import java.util.Collections;
import java.util.List;
public class JetObjectDeclaration extends JetNamedDeclarationStub<KotlinObjectStub> implements JetClassOrObject {
public JetObjectDeclaration(@NotNull ASTNode node) {
super(node);
}
public JetObjectDeclaration(@NotNull KotlinObjectStub stub) {
super(stub, JetStubElementTypes.OBJECT_DECLARATION);
}
@Override
public String getName() {
KotlinObjectStub stub = getStub();
if (stub != null) {
return stub.getName();
}
JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
if (nameAsDeclaration == null && isCompanion()) {
//NOTE: a hack in PSI that simplifies writing frontend code
return SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.toString();
}
return nameAsDeclaration == null ? null : nameAsDeclaration.getName();
}
@Override
public boolean isTopLevel() {
KotlinObjectStub stub = getStub();
if (stub != null) {
return stub.isTopLevel();
}
return getParent() instanceof JetFile;
}
@Override
public PsiElement getNameIdentifier() {
JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
return nameAsDeclaration == null ? null : nameAsDeclaration.getNameIdentifier();
}
@Override
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
JetObjectDeclarationName declarationName = getNameAsDeclaration();
if (declarationName == null) {
JetPsiFactory psiFactory = new JetPsiFactory(getProject());
PsiElement result = addAfter(psiFactory.createObjectDeclarationName(name), getObjectKeyword());
addAfter(psiFactory.createWhiteSpace(), getObjectKeyword());
return result;
} else {
return declarationName.setName(name);
}
}
@Override
@Nullable
public JetObjectDeclarationName getNameAsDeclaration() {
return (JetObjectDeclarationName) findChildByType(JetNodeTypes.OBJECT_DECLARATION_NAME);
}
public boolean isCompanion() {
KotlinObjectStub stub = getStub();
if (stub != null) {
return stub.isCompanion();
}
return hasModifier(JetTokens.COMPANION_KEYWORD);
}
@Override
public boolean hasModifier(@NotNull JetModifierKeywordToken modifier) {
JetModifierList modifierList = getModifierList();
return modifierList != null && modifierList.hasModifier(modifier);
}
@Override
@Nullable
public JetDelegationSpecifierList getDelegationSpecifierList() {
return getStubOrPsiChild(JetStubElementTypes.DELEGATION_SPECIFIER_LIST);
}
@Override
@NotNull
public List<JetDelegationSpecifier> getDelegationSpecifiers() {
JetDelegationSpecifierList list = getDelegationSpecifierList();
return list != null ? list.getDelegationSpecifiers() : Collections.<JetDelegationSpecifier>emptyList();
}
@Override
@NotNull
public List<JetClassInitializer> getAnonymousInitializers() {
JetClassBody body = getBody();
if (body == null) return Collections.emptyList();
return body.getAnonymousInitializers();
}
@Override
public JetClassBody getBody() {
return getStubOrPsiChild(JetStubElementTypes.CLASS_BODY);
}
@Override
public boolean isLocal() {
KotlinObjectStub stub = getStub();
if (stub != null) {
return stub.isLocal();
}
return JetPsiUtil.isLocal(this);
}
@Override
public int getTextOffset() {
PsiElement nameIdentifier = getNameIdentifier();
if (nameIdentifier != null) {
return nameIdentifier.getTextRange().getStartOffset();
}
else {
return getObjectKeyword().getTextRange().getStartOffset();
}
}
@Override
@NotNull
public List<JetDeclaration> getDeclarations() {
JetClassBody body = getBody();
if (body == null) return Collections.emptyList();
return body.getDeclarations();
}
@Override
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitObjectDeclaration(this, data);
}
public boolean isObjectLiteral() {
KotlinObjectStub stub = getStub();
if (stub != null) {
return stub.isObjectLiteral();
}
return getParent() instanceof JetObjectLiteralExpression;
}
@NotNull
public PsiElement getObjectKeyword() {
return findChildByType(JetTokens.OBJECT_KEYWORD);
}
@Override
public ItemPresentation getPresentation() {
return ItemPresentationProviders.getItemPresentation(this);
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi
import com.intellij.lang.ASTNode
import com.intellij.navigation.ItemPresentation
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.psi.PsiElement
import com.intellij.util.IncorrectOperationException
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.stubs.KotlinObjectStub
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes
public class JetObjectDeclaration : JetClassOrObject {
public constructor(node: ASTNode) : super(node)
public constructor(stub: KotlinObjectStub) : super(stub, JetStubElementTypes.OBJECT_DECLARATION)
override fun getStub(): KotlinObjectStub? = super.getStub() as? KotlinObjectStub
override fun getName(): String? {
val stub = getStub()
if (stub != null) {
return stub.getName()
}
val nameAsDeclaration = getNameAsDeclaration()
if (nameAsDeclaration == null && isCompanion()) {
//NOTE: a hack in PSI that simplifies writing frontend code
return SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.toString()
}
return nameAsDeclaration?.getName()
}
override fun getNameIdentifier(): PsiElement? = getNameAsDeclaration()?.getNameIdentifier()
override fun setName(NonNls name: String): PsiElement {
val declarationName = getNameAsDeclaration()
if (declarationName == null) {
val psiFactory = JetPsiFactory(getProject())
val result = addAfter(psiFactory.createObjectDeclarationName(name), getObjectKeyword())
addAfter(psiFactory.createWhiteSpace(), getObjectKeyword())
return result
}
else {
return declarationName.setName(name)
}
}
public fun isCompanion(): Boolean = getStub()?.isCompanion() ?: hasModifier(JetTokens.COMPANION_KEYWORD)
override fun getTextOffset(): Int = getNameIdentifier()?.getTextRange()?.getStartOffset()
?: getObjectKeyword().getTextRange().getStartOffset()
override fun <R, D> accept(visitor: JetVisitor<R, D>, data: D): R {
return visitor.visitObjectDeclaration(this, data)
}
public fun isObjectLiteral(): Boolean = getStub()?.isObjectLiteral() ?: (getParent() is JetObjectLiteralExpression)
public fun getObjectKeyword(): PsiElement = findChildByType(JetTokens.OBJECT_KEYWORD)
}

View File

@@ -71,17 +71,9 @@ public class JetPrimaryConstructor extends JetDeclarationStub<KotlinPlaceHolderS
}
}
@Nullable
public JetClass getContainingClassOrNull() {
JetClassOrObject classOrObject = (JetClassOrObject) getParent();
return classOrObject instanceof JetClass ? (JetClass) classOrObject : null;
}
@NotNull
public JetClass getContainingClass() {
JetClass classOrNull = getContainingClassOrNull();
assert classOrNull != null : "This method should be called when parent is JetClass";
return classOrNull;
public JetClassOrObject getContainingClassOrObject() {
return (JetClassOrObject) getParent();
}
public boolean hasConstructorKeyword() {

View File

@@ -151,17 +151,9 @@ public class JetPsiFactory(private val project: Project) {
public fun createFile(fileName: String, text: String): JetFile {
val file = doCreateFile(fileName, text)
//TODO: KotlinInternalMode should be used here
if (ApplicationManager.getApplication()!!.isInternal()) {
val sw = StringWriter()
Exception().printStackTrace(PrintWriter(sw))
file.doNotAnalyze = "This file was created by JetPsiFactory and should not be analyzed. It was created at:\n" + sw.toString()
}
else {
file.doNotAnalyze = "This file was created by JetPsiFactory and should not be analyzed\n" +
"Enable kotlin internal mode get more info for debugging\n" +
"Use createAnalyzableFile to create file that can be analyzed\n"
}
file.doNotAnalyze = "This file was created by JetPsiFactory and should not be analyzed\n" +
"Use createAnalyzableFile to create file that can be analyzed\n"
return file
}

View File

@@ -447,11 +447,11 @@ public class JetPsiUtil {
}
@Nullable
public static JetClass getClassIfParameterIsProperty(@NotNull JetParameter jetParameter) {
public static JetClassOrObject getClassIfParameterIsProperty(@NotNull JetParameter jetParameter) {
if (jetParameter.hasValOrVarNode()) {
PsiElement grandParent = jetParameter.getParent().getParent();
if (grandParent instanceof JetPrimaryConstructor) {
return ((JetPrimaryConstructor) grandParent).getContainingClassOrNull();
return ((JetPrimaryConstructor) grandParent).getContainingClassOrObject();
}
}

View File

@@ -26,10 +26,7 @@ import com.intellij.psi.impl.source.codeStyle.CodeEditUtil
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.renderName
import org.jetbrains.kotlin.psi.psiUtil.PsiChildRange
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi.psiUtil.*
import java.util.ArrayList
import java.util.HashMap
import java.util.LinkedHashMap
@@ -124,7 +121,7 @@ public fun <TElement : JetElement> createByPattern(pattern: String, vararg args:
for ((range, text) in placeholders) {
val token = resultElement.findElementAt(range.getStartOffset())!!
for (element in token.parents()) {
for (element in token.parentsWithSelf) {
val elementRange = element.getTextRange().shiftRight(-start)
if (elementRange == range && expectedElementType.isInstance(element)) {
val pointer = pointerManager.createSmartPsiElementPointer(element)

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi.psiUtil
import com.intellij.psi.PsiElement
public data class PsiChildRange(public val first: PsiElement?, public val last: PsiElement?) : Sequence<PsiElement> {
init {
if (first == null) {
assert(last == null)
}
else {
assert(first.getParent() == last!!.getParent())
}
}
public val isEmpty: Boolean
get() = first == null
override fun iterator(): Iterator<PsiElement> {
val sequence = if (first == null) {
emptySequence<PsiElement>()
}
else {
val afterLast = last!!.getNextSibling()
first.siblings().takeWhile { it != afterLast }
}
return sequence.iterator()
}
companion object {
public val EMPTY: PsiChildRange = PsiChildRange(null, null)
public fun singleElement(element: PsiElement): PsiChildRange = PsiChildRange(element, element)
}
}

View File

@@ -17,26 +17,27 @@
package org.jetbrains.kotlin.psi.psiUtil
import com.intellij.extapi.psi.StubBasedPsiElementBase
import com.intellij.lang.ASTNode
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.search.PsiSearchScopeUtil
import com.intellij.psi.search.SearchScope
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiParameter
import com.intellij.psi.PsiParameterList
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.JetNodeTypes
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.resolve.calls.CallTransformer.CallForImplicitInvoke
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
import java.util.ArrayList
import java.util.Collections
import kotlin.test.assertTrue
// NOTE: in this file we collect only Kotlin-specific methods working with PSI and not modifying it
// ----------- Calls and qualified expressions ---------------------------------------------------------------------------------------------
public fun JetCallElement.getCallNameExpression(): JetSimpleNameExpression? {
val calleeExpression = getCalleeExpression() ?: return null
@@ -47,92 +48,105 @@ public fun JetCallElement.getCallNameExpression(): JetSimpleNameExpression? {
}
}
public fun PsiElement.getParentOfTypesAndPredicate<T: PsiElement>(
strict : Boolean = false, vararg parentClasses : Class<T>, predicate: (T) -> Boolean
) : T? {
var element = if (strict) getParent() else this
while (element != null) {
@suppress("UNCHECKED_CAST")
when {
(parentClasses.isEmpty() || parentClasses.any {parentClass -> parentClass.isInstance(element)}) && predicate(element!! as T) ->
return element as T
element is PsiFile ->
return null
else ->
element = element!!.getParent()
/**
* Returns enclosing qualifying element for given [[JetSimpleNameExpression]]
* ([[JetQualifiedExpression]] or [[JetUserType]] or original expression)
*/
public fun JetSimpleNameExpression.getQualifiedElement(): JetElement {
val baseExpression: JetElement = (getParent() as? JetCallExpression) ?: this
val parent = baseExpression.getParent()
return when (parent) {
is JetQualifiedExpression -> if (parent.getSelectorExpression().isAncestor(baseExpression)) parent else baseExpression
is JetUserType -> if (parent.getReferenceExpression().isAncestor(baseExpression)) parent else baseExpression
else -> baseExpression
}
}
public fun JetSimpleNameExpression.getTopmostParentQualifiedExpressionForSelector(): JetQualifiedExpression? {
return sequence<JetExpression>(this) {
val parentQualified = it.getParent() as? JetQualifiedExpression
if (parentQualified?.getSelectorExpression() == it) parentQualified else null
}.last() as? JetQualifiedExpression
}
/**
* Returns rightmost selector of the qualified element (null if there is no such selector)
*/
public fun JetElement.getQualifiedElementSelector(): JetElement? {
return when (this) {
is JetSimpleNameExpression -> this
is JetCallExpression -> getCalleeExpression()
is JetQualifiedExpression -> {
val selector = getSelectorExpression()
if (selector is JetCallExpression) selector.getCalleeExpression() else selector
}
is JetUserType -> getReferenceExpression()
else -> null
}
}
public fun JetSimpleNameExpression.getReceiverExpression(): JetExpression? {
val parent = getParent()
when {
parent is JetQualifiedExpression && !isImportDirectiveExpression() -> {
val receiverExpression = parent.getReceiverExpression()
// Name expression can't be receiver for itself
if (receiverExpression != this) {
return receiverExpression
}
}
parent is JetCallExpression -> {
//This is in case `a().b()`
val callExpression = parent
val grandParent = callExpression.getParent()
if (grandParent is JetQualifiedExpression) {
val parentsReceiver = grandParent.getReceiverExpression()
if (parentsReceiver != callExpression) {
return parentsReceiver
}
}
}
parent is JetBinaryExpression && parent.getOperationReference() == this -> {
return if (parent.getOperationToken() in OperatorConventions.IN_OPERATIONS) parent.getRight() else parent.getLeft()
}
parent is JetUnaryExpression && parent.getOperationReference() == this -> {
return parent.getBaseExpression()!!
}
parent is JetUserType -> {
val qualifier = parent.getQualifier()
if (qualifier != null) {
return qualifier.getReferenceExpression()!!
}
}
}
return null
}
public fun PsiElement.getNonStrictParentOfType<T: PsiElement>(parentClass : Class<T>) : T? {
return PsiTreeUtil.getParentOfType(this, parentClass, false)
public fun JetElement.getQualifiedExpressionForSelector(): JetQualifiedExpression? {
val parent = getParent()
return if (parent is JetQualifiedExpression && parent.getSelectorExpression() == this) parent else null
}
inline public fun PsiElement.getParentOfType<reified T: PsiElement>(strict: Boolean): T? {
return PsiTreeUtil.getParentOfType(this, javaClass<T>(), strict)
public fun JetElement.getQualifiedExpressionForSelectorOrThis(): JetElement {
return getQualifiedExpressionForSelector() ?: this
}
inline public fun PsiElement.getStrictParentOfType<reified T: PsiElement>(): T? {
return PsiTreeUtil.getParentOfType(this, javaClass<T>(), true)
public fun JetExpression.isDotReceiver(): Boolean =
(getParent() as? JetDotQualifiedExpression)?.getReceiverExpression() == this
public fun JetElement.getCalleeHighlightingRange(): TextRange {
val annotationEntry: JetAnnotationEntry =
PsiTreeUtil.getParentOfType<JetAnnotationEntry>(
this, javaClass<JetAnnotationEntry>(), /* strict = */false, javaClass<JetValueArgumentList>()
) ?: return getTextRange()
val startOffset = annotationEntry.getAtSymbol()?.getTextRange()?.getStartOffset()
?: annotationEntry.getCalleeExpression().startOffset
return TextRange(startOffset, annotationEntry.getCalleeExpression().endOffset)
}
inline public fun PsiElement.getNonStrictParentOfType<reified T: PsiElement>(): T? {
return PsiTreeUtil.getParentOfType(this, javaClass<T>(), false)
}
inline public fun PsiElement.getChildOfType<reified T: PsiElement>(): T? {
return PsiTreeUtil.getChildOfType(this, javaClass<T>())
}
inline public fun PsiElement.getChildrenOfType<reified T: PsiElement>(): Array<T> {
return PsiTreeUtil.getChildrenOfType(this, javaClass<T>()) ?: arrayOf()
}
public fun PsiElement.getNextSiblingIgnoringWhitespaceAndComments(): PsiElement? {
var current = this
do {
current = current.getNextSibling()
if (current == null) return null
}
while (current is PsiComment || current is PsiWhiteSpace)
return current
}
public fun PsiElement?.isAncestor(element: PsiElement, strict: Boolean = false): Boolean {
return PsiTreeUtil.isAncestor(this, element, strict)
}
public fun <T: PsiElement> T.getIfChildIsInBranch(element: PsiElement, branch: T.() -> PsiElement?): T? {
return if (branch().isAncestor(element)) this else null
}
inline public fun PsiElement.getParentOfTypeAndBranch<reified T: PsiElement>(strict: Boolean = false, noinline branch: T.() -> PsiElement?) : T? {
return getParentOfType<T>(strict)?.getIfChildIsInBranch(this, branch)
}
public fun JetClassOrObject.effectiveDeclarations(): List<JetDeclaration> =
when(this) {
is JetClass ->
getDeclarations() + getPrimaryConstructorParameters().filter { p -> p.hasValOrVarNode() }
else ->
getDeclarations()
}
public fun JetClass.isAbstract(): Boolean = isInterface() || hasModifier(JetTokens.ABSTRACT_KEYWORD)
@suppress("UNCHECKED_CAST")
public inline fun <reified T: PsiElement> PsiElement.replaced(newElement: T): T {
val result = replace(newElement)
return if (result is T)
result
else
(result as JetParenthesizedExpression).getExpression() as T
}
@suppress("UNCHECKED_CAST")
public fun <T: PsiElement> T.copied(): T = copy() as T
// ---------- Block expression -------------------------------------------------------------------------------------------------------------
public fun JetElement.blockExpressionsOrSingle(): Sequence<JetElement> =
if (this is JetBlockExpression) getStatements().asSequence() else sequenceOf(this)
@@ -140,31 +154,46 @@ public fun JetElement.blockExpressionsOrSingle(): Sequence<JetElement> =
public fun JetExpression.lastBlockStatementOrThis(): JetExpression
= (this as? JetBlockExpression)?.getStatements()?.lastIsInstanceOrNull<JetExpression>() ?: this
public fun JetBlockExpression.appendElement(element: JetElement): JetElement {
public fun JetBlockExpression.contentRange(): PsiChildRange {
val first = (getLBrace()?.getNextSibling() ?: getFirstChild())
?.siblings(withItself = false)
?.firstOrNull { it !is PsiWhiteSpace }
val rBrace = getRBrace()
val anchor = if (rBrace == null) {
val lastChild = getLastChild()
if (lastChild !is PsiWhiteSpace) addAfter(JetPsiFactory(this).createNewLine(), lastChild)!! else lastChild
}
else {
rBrace.getPrevSibling()!!
}
return addAfter(element, anchor)!! as JetElement
if (first == rBrace) return PsiChildRange.EMPTY
val last = rBrace!!
.siblings(forward = false, withItself = false)
.first { it !is PsiWhiteSpace }
return PsiChildRange(first, last)
}
public fun JetElement.wrapInBlock(): JetBlockExpression {
val block = JetPsiFactory(this).createEmptyBody()
block.appendElement(this)
return block
// ----------- Inheritance -----------------------------------------------------------------------------------------------------------------
public fun JetClass.isInheritable(): Boolean {
return isInterface() || hasModifier(JetTokens.OPEN_KEYWORD) || hasModifier(JetTokens.ABSTRACT_KEYWORD)
}
public fun JetDeclaration.isOverridable(): Boolean {
val parent = getParent()
if (!(parent is JetClassBody || parent is JetParameterList)) return false
val klass = parent.getParent()
if (!(klass is JetClass && klass.isInheritable())) return false
if (hasModifier(JetTokens.FINAL_KEYWORD) || hasModifier(JetTokens.PRIVATE_KEYWORD)) return false
return klass.isInterface() ||
hasModifier(JetTokens.ABSTRACT_KEYWORD) || hasModifier(JetTokens.OPEN_KEYWORD) || hasModifier(JetTokens.OVERRIDE_KEYWORD)
}
public fun JetClass.isAbstract(): Boolean = isInterface() || hasModifier(JetTokens.ABSTRACT_KEYWORD)
/**
* Returns the list of unqualified names that are indexed as the superclass names of this class. For the names that might be imported
* via an aliased import, includes both the original and the aliased name (reference resolution during inheritor search will sort this out).
*
* @return the list of possible superclass names
*/
public fun <T: JetClassOrObject> StubBasedPsiElementBase<out KotlinClassOrObjectStub<T>>.getSuperNames(): List<String> {
public fun StubBasedPsiElementBase<out KotlinClassOrObjectStub<out JetClassOrObject>>.getSuperNames(): List<String> {
fun addSuperName(result: MutableList<String>, referencedName: String): Unit {
result.add(referencedName)
@@ -207,342 +236,47 @@ public fun <T: JetClassOrObject> StubBasedPsiElementBase<out KotlinClassOrObject
return result
}
public fun SearchScope.contains(element: PsiElement): Boolean = PsiSearchScopeUtil.isInScope(this, element)
// ------------ Annotations ----------------------------------------------------------------------------------------------------------------
public fun JetClass.isInheritable(): Boolean {
return isInterface() || hasModifier(JetTokens.OPEN_KEYWORD) || hasModifier(JetTokens.ABSTRACT_KEYWORD)
}
public fun JetDeclaration.isOverridable(): Boolean {
val parent = getParent()
if (!(parent is JetClassBody || parent is JetParameterList)) return false
val klass = parent.getParent()
if (!(klass is JetClass && klass.isInheritable())) return false
if (hasModifier(JetTokens.FINAL_KEYWORD) || hasModifier(JetTokens.PRIVATE_KEYWORD)) return false
return klass.isInterface() ||
hasModifier(JetTokens.ABSTRACT_KEYWORD) || hasModifier(JetTokens.OPEN_KEYWORD) || hasModifier(JetTokens.OVERRIDE_KEYWORD)
}
public fun PsiElement.isExtensionDeclaration(): Boolean {
val callable: JetCallableDeclaration? = when (this) {
is JetNamedFunction, is JetProperty -> this as JetCallableDeclaration
is JetPropertyAccessor -> getNonStrictParentOfType<JetProperty>()
else -> null
}
return callable?.getReceiverTypeReference() != null
}
public fun PsiElement.isObjectLiteral(): Boolean = this is JetObjectDeclaration && isObjectLiteral()
//TODO: git rid of this method
public fun PsiElement.deleteElementAndCleanParent() {
val parent = getParent()
deleteElementWithDelimiters(this)
deleteChildlessElement(parent, this.javaClass)
}
// Delete element if it doesn't contain children of a given type
private fun <T : PsiElement> deleteChildlessElement(element: PsiElement, childClass: Class<T>) {
if (PsiTreeUtil.getChildrenOfType<T>(element, childClass) == null) {
element.delete()
}
}
// Delete given element and all the elements separating it from the neighboring elements of the same class
private fun deleteElementWithDelimiters(element: PsiElement) {
val paramBefore = PsiTreeUtil.getPrevSiblingOfType<PsiElement>(element, element.javaClass)
val from: PsiElement
val to: PsiElement
if (paramBefore != null) {
from = paramBefore.getNextSibling()
to = element
}
else {
val paramAfter = PsiTreeUtil.getNextSiblingOfType<PsiElement>(element, element.javaClass)
from = element
to = if (paramAfter != null) paramAfter.getPrevSibling() else element
}
val parent = element.getParent()
parent.deleteChildRange(from, to)
}
public fun PsiElement.parameterIndex(): Int {
val parent = getParent()
return when {
this is JetParameter && parent is JetParameterList -> parent.getParameters().indexOf(this)
this is PsiParameter && parent is PsiParameterList -> parent.getParameterIndex(this)
else -> -1
}
}
/**
* Returns enclosing qualifying element for given [[JetSimpleNameExpression]]
* ([[JetQualifiedExpression]] or [[JetUserType]] or original expression)
*/
public fun JetSimpleNameExpression.getQualifiedElement(): JetElement {
val baseExpression: JetElement = (getParent() as? JetCallExpression) ?: this
val parent = baseExpression.getParent()
return when (parent) {
is JetQualifiedExpression -> if (parent.getSelectorExpression().isAncestor(baseExpression)) parent else baseExpression
is JetUserType -> if (parent.getReferenceExpression().isAncestor(baseExpression)) parent else baseExpression
else -> baseExpression
}
}
public fun JetSimpleNameExpression.getTopmostParentQualifiedExpressionForSelector(): JetQualifiedExpression? {
return sequence<JetExpression>(this) {
val parentQualified = it.getParent() as? JetQualifiedExpression
if (parentQualified?.getSelectorExpression() == it) parentQualified else null
}.last() as? JetQualifiedExpression
}
/**
* Returns rightmost selector of the qualified element (null if there is no such selector)
*/
public fun JetElement.getQualifiedElementSelector(): JetElement? {
return when (this) {
is JetSimpleNameExpression -> this
is JetCallExpression -> getCalleeExpression()
is JetQualifiedExpression -> {
val selector = getSelectorExpression()
if (selector is JetCallExpression) selector.getCalleeExpression() else selector
}
is JetUserType -> getReferenceExpression()
else -> null
}
}
/**
* Returns outermost qualified element ([[JetQualifiedExpression]] or [[JetUserType]]) in the non-interleaving chain
* of qualified elements which enclose given expression
* If there is no such elements original expression is returned
*/
public fun JetSimpleNameExpression.getOutermostNonInterleavingQualifiedElement(): JetElement {
var element = ((getParent() as? JetCallExpression) ?: this).getParent()
if (element !is JetQualifiedExpression && element !is JetUserType) return this
while (true) {
val parent = element!!.getParent()
if (parent !is JetQualifiedExpression && parent !is JetUserType) return element as JetElement
element = parent
}
}
public fun PsiDirectory.getPackage(): PsiPackage? = JavaDirectoryService.getInstance()!!.getPackage(this)
public fun JetModifierListOwner.isPrivate(): Boolean = hasModifier(JetTokens.PRIVATE_KEYWORD)
public fun PsiElement.isInsideOf(elements: Iterable<PsiElement>): Boolean = elements.any { it.isAncestor(this) }
public tailRecursive fun PsiElement.getOutermostParentContainedIn(container: PsiElement): PsiElement? {
val parent = getParent()
return if (parent == container) this else parent?.getOutermostParentContainedIn(container)
}
public fun JetSimpleNameExpression.getReceiverExpression(): JetExpression? {
val parent = getParent()
when {
parent is JetQualifiedExpression && !isImportDirectiveExpression() -> {
val receiverExpression = parent.getReceiverExpression()
// Name expression can't be receiver for itself
if (receiverExpression != this) {
return receiverExpression
}
}
parent is JetCallExpression -> {
//This is in case `a().b()`
val callExpression = parent
val grandParent = callExpression.getParent()
if (grandParent is JetQualifiedExpression) {
val parentsReceiver = grandParent.getReceiverExpression()
if (parentsReceiver != callExpression) {
return parentsReceiver
}
}
}
parent is JetBinaryExpression && parent.getOperationReference() == this -> {
return if (parent.getOperationToken() in OperatorConventions.IN_OPERATIONS) parent.getRight() else parent.getLeft()
}
parent is JetUnaryExpression && parent.getOperationReference() == this -> {
return parent.getBaseExpression()!!
}
parent is JetUserType -> {
val qualifier = parent.getQualifier()
if (qualifier != null) {
return qualifier.getReferenceExpression()!!
}
}
}
return null
}
public fun JetSimpleNameExpression.isImportDirectiveExpression(): Boolean {
val parent = getParent()
if (parent == null) {
return false
}
else {
return parent is JetImportDirective || parent.getParent() is JetImportDirective
}
}
public fun JetElement.getTextWithLocation(): String = "'${this.getText()}' at ${DiagnosticUtils.atLocation(this)}"
public fun JetExpression.isFunctionLiteralOutsideParentheses(): Boolean {
// Annotations on labeled expression lies on it's base expression
public fun JetExpression.getAnnotationEntries(): List<JetAnnotationEntry> {
val parent = getParent()
return when (parent) {
is JetFunctionLiteralArgument -> true
is JetLabeledExpression -> parent.isFunctionLiteralOutsideParentheses()
else -> false
is JetAnnotatedExpression -> parent.getAnnotationEntries()
is JetLabeledExpression -> parent.getAnnotationEntries()
else -> emptyList<JetAnnotationEntry>()
}
}
public fun PsiElement.siblings(forward: Boolean = true, withItself: Boolean = true): Sequence<PsiElement> {
val stepFun = if (forward) { e: PsiElement -> e.getNextSibling() } else { e: PsiElement -> e.getPrevSibling() }
val sequence = sequence(this, stepFun)
return if (withItself) sequence else sequence.drop(1)
}
public fun ASTNode.siblings(forward: Boolean = true, withItself: Boolean = true): Sequence<ASTNode> {
val stepFun = if (forward) { node: ASTNode -> node.getTreeNext() } else { e: ASTNode -> e.getTreeNext() }
val sequence = sequence(this, stepFun)
return if (withItself) sequence else sequence.drop(1)
}
public fun PsiElement.parents(withItself: Boolean = true): Sequence<PsiElement> {
val sequence = sequence(this) { if (it is PsiFile) null else it.getParent() }
return if (withItself) sequence else sequence.drop(1)
}
public fun ASTNode.parents(withItself: Boolean = true): Sequence<ASTNode> {
val sequence = sequence(this) { it.getTreeParent() }
return if (withItself) sequence else sequence.drop(1)
}
public fun JetExpression.getAssignmentByLHS(): JetBinaryExpression? {
val parent = getParent() as? JetBinaryExpression ?: return null
return if (JetPsiUtil.isAssignment(parent) && parent.getLeft() == this) parent else null
}
public fun PsiElement.prevLeaf(skipEmptyElements: Boolean = false): PsiElement?
= PsiTreeUtil.prevLeaf(this, skipEmptyElements)
public fun PsiElement.nextLeaf(skipEmptyElements: Boolean = false): PsiElement?
= PsiTreeUtil.nextLeaf(this, skipEmptyElements)
public fun PsiElement.prevLeaf(filter: (PsiElement) -> Boolean): PsiElement? {
var leaf = prevLeaf()
while (leaf != null && !filter(leaf)) {
leaf = leaf.prevLeaf()
public fun JetAnnotationsContainer.collectAnnotationEntriesFromStubOrPsi(): List<JetAnnotationEntry> {
return when (this) {
is StubBasedPsiElementBase<*> -> getStub()?.collectAnnotationEntriesFromStubElement() ?: collectAnnotationEntriesFromPsi()
else -> collectAnnotationEntriesFromPsi()
}
return leaf
}
public fun PsiElement.nextLeaf(filter: (PsiElement) -> Boolean): PsiElement? {
var leaf = nextLeaf()
while (leaf != null && !filter(leaf)) {
leaf = leaf.nextLeaf()
}
return leaf
}
public fun JetExpression.isDotReceiver(): Boolean =
(getParent() as? JetDotQualifiedExpression)?.getReceiverExpression() == this
public fun Call.isSafeCall(): Boolean {
if (this is CallForImplicitInvoke) {
//implicit safe 'invoke'
if (getOuterCall().isExplicitSafeCall()) {
return true
private fun StubElement<*>.collectAnnotationEntriesFromStubElement(): List<JetAnnotationEntry> {
return getChildrenStubs().flatMap {
child ->
when (child.getStubType()) {
JetNodeTypes.ANNOTATION_ENTRY -> listOf(child.getPsi() as JetAnnotationEntry)
JetNodeTypes.ANNOTATION -> (child.getPsi() as JetAnnotation).getEntries()
else -> emptyList<JetAnnotationEntry>()
}
}
return isExplicitSafeCall()
}
public fun Call.isExplicitSafeCall(): Boolean = getCallOperationNode()?.getElementType() == JetTokens.SAFE_ACCESS
public fun JetStringTemplateExpression.getContentRange(): TextRange {
val start = getNode().getFirstChildNode().getTextLength()
val lastChild = getNode().getLastChildNode()
val length = getTextLength()
return TextRange(start, if (lastChild.getElementType() == JetTokens.CLOSING_QUOTE) length - lastChild.getTextLength() else length)
}
public fun JetStringTemplateExpression.isSingleQuoted(): Boolean
= getNode().getFirstChildNode().getTextLength() == 1
public fun PsiFile.elementsInRange(range: TextRange): List<PsiElement> {
var offset = range.getStartOffset()
val result = ArrayList<PsiElement>()
while (offset < range.getEndOffset()) {
val currentRange = TextRange(offset, range.getEndOffset())
val leaf = findFirstLeafWhollyInRange(this, currentRange) ?: break
val element = leaf
.parents(withItself = true)
.first {
val parent = it.getParent()
it is PsiFile || parent.getTextRange() !in currentRange
}
result.add(element)
offset = element.endOffset
}
return result
}
private fun findFirstLeafWhollyInRange(file: PsiFile, range: TextRange): PsiElement? {
var element = file.findElementAt(range.getStartOffset()) ?: return null
var elementRange = element.getTextRange()
if (elementRange.getStartOffset() < range.getStartOffset()) {
element = element.nextLeaf(skipEmptyElements = true) ?: return null
elementRange = element.getTextRange()
}
assert(elementRange.getStartOffset() >= range.getStartOffset())
return if (elementRange.getEndOffset() <= range.getEndOffset()) element else null
}
fun JetNamedDeclaration.getValueParameters(): List<JetParameter> {
return getValueParameterList()?.getParameters() ?: Collections.emptyList()
}
fun JetNamedDeclaration.getValueParameterList(): JetParameterList? {
return when (this) {
is JetCallableDeclaration -> getValueParameterList()
is JetClass -> getPrimaryConstructorParameterList()
else -> null
private fun JetAnnotationsContainer.collectAnnotationEntriesFromPsi(): List<JetAnnotationEntry> {
return getChildren().flatMap { child ->
when (child) {
is JetAnnotationEntry -> listOf(child)
is JetAnnotation -> child.getEntries()
else -> emptyList<JetAnnotationEntry>()
}
}
}
public fun PsiElement.getElementTextWithContext(): String {
if (this is PsiFile) {
return getContainingFile().getText()
}
// Find parent for element among file children
val topLevelElement = PsiTreeUtil.findFirstParent(this, { it.getParent() is PsiFile }) ?:
throw AssertionError("For non-file element we should always be able to find parent in file children")
val startContextOffset = topLevelElement.startOffset
val elementContextOffset = getTextRange().getStartOffset()
val inFileParentOffset = elementContextOffset - startContextOffset
return StringBuilder(topLevelElement.getText())
.insert(inFileParentOffset, "<caret>")
.insert(0, "File name: ${getContainingFile().getName()}\n")
.toString()
}
// -------- Recursive tree visiting --------------------------------------------------------------------------------------------------------
// Calls `block` on each descendant of T type
// Note, that calls happen in order of DFS-exit, so deeper nodes are applied earlier
@@ -561,118 +295,81 @@ public inline fun <reified T : JetElement, R> flatMapDescendantsOfTypeVisitor(ac
return forEachDescendantOfTypeVisitor<T> { accumulator.addAll(map(it)) }
}
public inline fun <reified T : PsiElement> PsiElement.forEachDescendantOfType(noinline action: (T) -> Unit) {
this.accept(object : PsiRecursiveElementVisitor(){
override fun visitElement(element: PsiElement) {
super.visitElement(element)
if (element is T) {
action(element)
}
}
})
}
// ----------- Other -----------------------------------------------------------------------------------------------------------------------
public inline fun <reified T : PsiElement> PsiElement.anyDescendantOfType(noinline predicate: (T) -> Boolean = { true }): Boolean {
return findDescendantOfType(predicate) != null
}
public inline fun <reified T : PsiElement> PsiElement.findDescendantOfType(noinline predicate: (T) -> Boolean = { true }): T? {
var result: T? = null
this.accept(object : PsiRecursiveElementVisitor(){
override fun visitElement(element: PsiElement) {
if (result != null) return
if (element is T && predicate(element)) {
result = element
return
}
super.visitElement(element)
}
})
return result
}
public inline fun <reified T : PsiElement> PsiElement.collectDescendantsOfType(noinline predicate: (T) -> Boolean = { true }): List<T> {
val result = ArrayList<T>()
forEachDescendantOfType<T> {
if (predicate(it)) {
result.add(it)
}
public fun JetClassOrObject.effectiveDeclarations(): List<JetDeclaration> {
return when(this) {
is JetClass -> getDeclarations() + getPrimaryConstructorParameters().filter { p -> p.hasValOrVarNode() }
else -> getDeclarations()
}
return result
}
public fun PsiFile.getFqNameByDirectory(): FqName {
val qualifiedNameByDirectory = getParent()?.getPackage()?.getQualifiedName()
return qualifiedNameByDirectory?.let { FqName(it) } ?: FqName.ROOT
}
public fun JetFile.packageMatchesDirectory(): Boolean = getPackageFqName() == getFqNameByDirectory()
public fun JetAnnotationsContainer.collectAnnotationEntriesFromStubOrPsi(): List<JetAnnotationEntry> =
when (this) {
is StubBasedPsiElementBase<*> -> getStub()?.collectAnnotationEntriesFromStubElement() ?: collectAnnotationEntriesFromPsi()
else -> collectAnnotationEntriesFromPsi()
public fun JetDeclaration.isExtensionDeclaration(): Boolean {
val callable: JetCallableDeclaration? = when (this) {
is JetNamedFunction, is JetProperty -> this as JetCallableDeclaration
is JetPropertyAccessor -> getNonStrictParentOfType<JetProperty>()
else -> null
}
private fun StubElement<*>.collectAnnotationEntriesFromStubElement() =
getChildrenStubs().flatMap {
child ->
when (child.getStubType()) {
JetNodeTypes.ANNOTATION_ENTRY -> listOf(child.getPsi() as JetAnnotationEntry)
JetNodeTypes.ANNOTATION -> (child.getPsi() as JetAnnotation).getEntries()
else -> emptyList<JetAnnotationEntry>()
}
}
private fun JetAnnotationsContainer.collectAnnotationEntriesFromPsi() =
getChildren().flatMap {
child ->
when (child) {
is JetAnnotationEntry -> listOf(child)
is JetAnnotation -> child.getEntries()
else -> emptyList<JetAnnotationEntry>()
}
}
public fun JetElement.getCalleeHighlightingRange(): TextRange {
val annotationEntry: JetAnnotationEntry =
PsiTreeUtil.getParentOfType<JetAnnotationEntry>(
this, javaClass<JetAnnotationEntry>(), /* strict = */false, javaClass<JetValueArgumentList>()
) ?: return getTextRange()
val startOffset = annotationEntry.getAtSymbol()?.getTextRange()?.getStartOffset()
?: annotationEntry.getCalleeExpression().startOffset
return TextRange(startOffset, annotationEntry.getCalleeExpression().endOffset)
return callable?.getReceiverTypeReference() != null
}
public fun JetBlockExpression.contentRange(): PsiChildRange {
val first = (getLBrace()?.getNextSibling() ?: getFirstChild())
?.siblings(withItself = false)
?.firstOrNull { it !is PsiWhiteSpace }
val rBrace = getRBrace()
if (first == rBrace) return PsiChildRange.EMPTY
val last = rBrace!!
.siblings(forward = false, withItself = false)
.first { it !is PsiWhiteSpace }
return PsiChildRange(first, last)
public fun JetClassOrObject.isObjectLiteral(): Boolean = this is JetObjectDeclaration && isObjectLiteral()
//TODO: strange method, and not only Kotlin specific (also Java)
public fun PsiElement.parameterIndex(): Int {
val parent = getParent()
return when {
this is JetParameter && parent is JetParameterList -> parent.getParameters().indexOf(this)
this is PsiParameter && parent is PsiParameterList -> parent.getParameterIndex(this)
else -> -1
}
}
// Annotations on labeled expression lies on it's base expression
public fun JetExpression.getAnnotationEntries(): List<JetAnnotationEntry> {
public fun JetModifierListOwner.isPrivate(): Boolean = hasModifier(JetTokens.PRIVATE_KEYWORD)
public fun JetSimpleNameExpression.isImportDirectiveExpression(): Boolean {
val parent = getParent()
if (parent == null) {
return false
}
else {
return parent is JetImportDirective || parent.getParent() is JetImportDirective
}
}
public fun JetExpression.isFunctionLiteralOutsideParentheses(): Boolean {
val parent = getParent()
return when (parent) {
is JetAnnotatedExpression -> parent.getAnnotationEntries()
is JetLabeledExpression -> parent.getAnnotationEntries()
else -> emptyList<JetAnnotationEntry>()
is JetFunctionLiteralArgument -> true
is JetLabeledExpression -> parent.isFunctionLiteralOutsideParentheses()
else -> false
}
}
public fun JetElement.getQualifiedExpressionForSelector(): JetQualifiedExpression? {
val parent = getParent()
return if (parent is JetQualifiedExpression && parent.getSelectorExpression() == this) parent else null
public fun JetExpression.getAssignmentByLHS(): JetBinaryExpression? {
val parent = getParent() as? JetBinaryExpression ?: return null
return if (JetPsiUtil.isAssignment(parent) && parent.getLeft() == this) parent else null
}
public fun JetElement.getQualifiedExpressionForSelectorOrThis(): JetElement {
return getQualifiedExpressionForSelector() ?: this
}
public fun JetStringTemplateExpression.getContentRange(): TextRange {
val start = getNode().getFirstChildNode().getTextLength()
val lastChild = getNode().getLastChildNode()
val length = getTextLength()
return TextRange(start, if (lastChild.getElementType() == JetTokens.CLOSING_QUOTE) length - lastChild.getTextLength() else length)
}
public fun JetStringTemplateExpression.isSingleQuoted(): Boolean
= getNode().getFirstChildNode().getTextLength() == 1
public fun JetNamedDeclaration.getValueParameters(): List<JetParameter> {
return getValueParameterList()?.getParameters() ?: Collections.emptyList()
}
public fun JetNamedDeclaration.getValueParameterList(): JetParameterList? {
return when (this) {
is JetCallableDeclaration -> getValueParameterList()
is JetClass -> getPrimaryConstructorParameterList()
else -> null
}
}

View File

@@ -17,9 +17,188 @@
package org.jetbrains.kotlin.psi.psiUtil
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.*
import com.intellij.psi.search.PsiSearchScopeUtil
import com.intellij.psi.search.SearchScope
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import java.util.ArrayList
//TODO: move here more functions from jetPsiUtil.kt
// NOTE: in this file we collect only LANGUAGE INDEPENDENT methods working with PSI and not modifying it
// ----------- Walking children/siblings/parents -------------------------------------------------------------------------------------------
public val PsiElement.allChildren: PsiChildRange
get() {
val first = getFirstChild()
return if (first != null) PsiChildRange(first, getLastChild()) else PsiChildRange.EMPTY
}
public fun PsiElement.siblings(forward: Boolean = true, withItself: Boolean = true): Sequence<PsiElement> {
val stepFun = if (forward) { e: PsiElement -> e.getNextSibling() } else { e: PsiElement -> e.getPrevSibling() }
val sequence = sequence(this, stepFun)
return if (withItself) sequence else sequence.drop(1)
}
public val PsiElement.parentsWithSelf: Sequence<PsiElement>
get() = sequence(this) { if (it is PsiFile) null else it.getParent() }
public val PsiElement.parents: Sequence<PsiElement>
get() = parentsWithSelf.drop(1)
public fun PsiElement.prevLeaf(skipEmptyElements: Boolean = false): PsiElement?
= PsiTreeUtil.prevLeaf(this, skipEmptyElements)
public fun PsiElement.nextLeaf(skipEmptyElements: Boolean = false): PsiElement?
= PsiTreeUtil.nextLeaf(this, skipEmptyElements)
public fun PsiElement.prevLeaf(filter: (PsiElement) -> Boolean): PsiElement? {
var leaf = prevLeaf()
while (leaf != null && !filter(leaf)) {
leaf = leaf.prevLeaf()
}
return leaf
}
public fun PsiElement.nextLeaf(filter: (PsiElement) -> Boolean): PsiElement? {
var leaf = nextLeaf()
while (leaf != null && !filter(leaf)) {
leaf = leaf.nextLeaf()
}
return leaf
}
public fun PsiElement.getParentOfTypesAndPredicate<T: PsiElement>(
strict : Boolean = false, vararg parentClasses : Class<T>, predicate: (T) -> Boolean
) : T? {
var element = if (strict) getParent() else this
while (element != null) {
@suppress("UNCHECKED_CAST")
when {
(parentClasses.isEmpty() || parentClasses.any {parentClass -> parentClass.isInstance(element)}) && predicate(element!! as T) ->
return element as T
element is PsiFile ->
return null
else ->
element = element!!.getParent()
}
}
return null
}
public fun PsiElement.getNonStrictParentOfType<T: PsiElement>(parentClass : Class<T>) : T? {
return PsiTreeUtil.getParentOfType(this, parentClass, false)
}
inline public fun PsiElement.getParentOfType<reified T: PsiElement>(strict: Boolean): T? {
return PsiTreeUtil.getParentOfType(this, javaClass<T>(), strict)
}
inline public fun PsiElement.getStrictParentOfType<reified T: PsiElement>(): T? {
return PsiTreeUtil.getParentOfType(this, javaClass<T>(), true)
}
inline public fun PsiElement.getNonStrictParentOfType<reified T: PsiElement>(): T? {
return PsiTreeUtil.getParentOfType(this, javaClass<T>(), false)
}
inline public fun PsiElement.getChildOfType<reified T: PsiElement>(): T? {
return PsiTreeUtil.getChildOfType(this, javaClass<T>())
}
inline public fun PsiElement.getChildrenOfType<reified T: PsiElement>(): Array<T> {
return PsiTreeUtil.getChildrenOfType(this, javaClass<T>()) ?: arrayOf()
}
public fun PsiElement.getNextSiblingIgnoringWhitespaceAndComments(): PsiElement? {
return siblings(withItself = false).filter { it !is PsiWhiteSpace && it !is PsiComment }.firstOrNull()
}
public fun PsiElement?.isAncestor(element: PsiElement, strict: Boolean = false): Boolean {
return PsiTreeUtil.isAncestor(this, element, strict)
}
public fun <T: PsiElement> T.getIfChildIsInBranch(element: PsiElement, branch: T.() -> PsiElement?): T? {
return if (branch().isAncestor(element)) this else null
}
public inline fun PsiElement.getParentOfTypeAndBranch<reified T: PsiElement>(strict: Boolean = false, noinline branch: T.() -> PsiElement?) : T? {
return getParentOfType<T>(strict)?.getIfChildIsInBranch(this, branch)
}
public tailRecursive fun PsiElement.getOutermostParentContainedIn(container: PsiElement): PsiElement? {
val parent = getParent()
return if (parent == container) this else parent?.getOutermostParentContainedIn(container)
}
public fun PsiElement.isInsideOf(elements: Iterable<PsiElement>): Boolean = elements.any { it.isAncestor(this) }
// -------------------- Recursive tree visiting --------------------------------------------------------------------------------------------
public inline fun <reified T : PsiElement> PsiElement.forEachDescendantOfType(noinline action: (T) -> Unit) {
forEachDescendantOfType<T>({true}, action)
}
public inline fun <reified T : PsiElement> PsiElement.forEachDescendantOfType(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) canGoInside: (PsiElement) -> Boolean, noinline action: (T) -> Unit) {
this.accept(object : PsiRecursiveElementVisitor(){
override fun visitElement(element: PsiElement) {
if (canGoInside(element)) {
super.visitElement(element)
}
if (element is T) {
action(element)
}
}
})
}
public inline fun <reified T : PsiElement> PsiElement.anyDescendantOfType(noinline predicate: (T) -> Boolean = { true }): Boolean {
return findDescendantOfType<T>(predicate) != null
}
public inline fun <reified T : PsiElement> PsiElement.anyDescendantOfType(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) canGoInside: (PsiElement) -> Boolean, noinline predicate: (T) -> Boolean = { true }): Boolean {
return findDescendantOfType<T>(canGoInside, predicate) != null
}
public inline fun <reified T : PsiElement> PsiElement.findDescendantOfType(noinline predicate: (T) -> Boolean = { true }): T? {
return findDescendantOfType<T>({ true}, predicate)
}
public inline fun <reified T : PsiElement> PsiElement.findDescendantOfType(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) canGoInside: (PsiElement) -> Boolean, noinline predicate: (T) -> Boolean = { true }): T? {
var result: T? = null
this.accept(object : PsiRecursiveElementVisitor(){
override fun visitElement(element: PsiElement) {
if (result != null) return
if (element is T && predicate(element)) {
result = element
return
}
if (canGoInside(element)) {
super.visitElement(element)
}
}
})
return result
}
public inline fun <reified T : PsiElement> PsiElement.collectDescendantsOfType(noinline predicate: (T) -> Boolean = { true }): List<T> {
return collectDescendantsOfType<T>({ true }, predicate)
}
public inline fun <reified T : PsiElement> PsiElement.collectDescendantsOfType(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) canGoInside: (PsiElement) -> Boolean, noinline predicate: (T) -> Boolean = { true }): List<T> {
val result = ArrayList<T>()
forEachDescendantOfType<T>(canGoInside) {
if (predicate(it)) {
result.add(it)
}
}
return result
}
// ----------- Working with offsets, ranges and texts ----------------------------------------------------------------------------------------------
public val PsiElement.startOffset: Int
get() = getTextRange().getStartOffset()
@@ -30,50 +209,13 @@ public val PsiElement.endOffset: Int
public fun PsiElement.getStartOffsetIn(ancestor: PsiElement): Int {
var offset = 0
var parent = this
while (parent != this) {
while (parent != ancestor) {
offset += parent.getStartOffsetInParent()
parent = parent.getParent()
}
return offset
}
public data class PsiChildRange(public val first: PsiElement?, public val last: PsiElement?) : Sequence<PsiElement> {
init {
if (first == null) {
assert(last == null)
}
else {
assert(first.getParent() == last!!.getParent())
}
}
public val isEmpty: Boolean
get() = first == null
override fun iterator(): Iterator<PsiElement> {
val sequence = if (first == null) {
emptySequence<PsiElement>()
}
else {
val afterLast = last!!.getNextSibling()
first.siblings().takeWhile { it != afterLast }
}
return sequence.iterator()
}
companion object {
public val EMPTY: PsiChildRange = PsiChildRange(null, null)
public fun singleElement(element: PsiElement): PsiChildRange = PsiChildRange(element, element)
}
}
public val PsiElement.allChildren: PsiChildRange
get() {
val first = getFirstChild()
return if (first != null) PsiChildRange(first, getLastChild()) else PsiChildRange.EMPTY
}
public val PsiChildRange.textRange: TextRange?
get() {
if (isEmpty) return null
@@ -85,3 +227,62 @@ public fun PsiChildRange.getText(): String {
return this.map { it.getText() }.joinToString("")
}
public fun PsiFile.elementsInRange(range: TextRange): List<PsiElement> {
var offset = range.getStartOffset()
val result = ArrayList<PsiElement>()
while (offset < range.getEndOffset()) {
val currentRange = TextRange(offset, range.getEndOffset())
val leaf = findFirstLeafWhollyInRange(this, currentRange) ?: break
val element = leaf
.parentsWithSelf
.first {
val parent = it.getParent()
it is PsiFile || parent.getTextRange() !in currentRange
}
result.add(element)
offset = element.endOffset
}
return result
}
private fun findFirstLeafWhollyInRange(file: PsiFile, range: TextRange): PsiElement? {
var element = file.findElementAt(range.getStartOffset()) ?: return null
var elementRange = element.getTextRange()
if (elementRange.getStartOffset() < range.getStartOffset()) {
element = element.nextLeaf(skipEmptyElements = true) ?: return null
elementRange = element.getTextRange()
}
assert(elementRange.getStartOffset() >= range.getStartOffset())
return if (elementRange.getEndOffset() <= range.getEndOffset()) element else null
}
// ---------------------------------- Debug/logging ----------------------------------------------------------------------------------------
public fun PsiElement.getElementTextWithContext(): String {
if (this is PsiFile) {
return getContainingFile().getText()
}
// Find parent for element among file children
val topLevelElement = PsiTreeUtil.findFirstParent(this, { it.getParent() is PsiFile }) ?:
throw AssertionError("For non-file element we should always be able to find parent in file children")
val startContextOffset = topLevelElement.startOffset
val elementContextOffset = getTextRange().getStartOffset()
val inFileParentOffset = elementContextOffset - startContextOffset
return StringBuilder(topLevelElement.getText())
.insert(inFileParentOffset, "<caret>")
.insert(0, "File name: ${getContainingFile().getName()}\n")
.toString()
}
public fun PsiElement.getTextWithLocation(): String = "'${this.getText()}' at ${DiagnosticUtils.atLocation(this)}"
// -----------------------------------------------------------------------------------------------------------------------------------------
public fun SearchScope.contains(element: PsiElement): Boolean = PsiSearchScopeUtil.isInScope(this, element)

View File

@@ -19,7 +19,9 @@ package org.jetbrains.kotlin.resolve.annotations
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
public fun DeclarationDescriptor.hasInlineAnnotation(): Boolean {
@@ -49,3 +51,12 @@ private fun CallableDescriptor.isPlatformStaticIn(predicate: (DeclarationDescrip
}
else -> predicate(getContainingDeclaration()) && hasPlatformStaticAnnotation()
}
public fun AnnotationDescriptor.argumentValue(parameterName: String): Any? {
return getAllValueArguments().entrySet()
.singleOrNull { it.key.getName().asString() == parameterName }
?.value?.getValue()
}
public fun AnnotationDescriptor.deprecatedAnnotationMessage(): String?
= argumentValue("value") as? String

View File

@@ -339,9 +339,6 @@ public class BodyResolver {
recordSupertype(typeReference, supertype);
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
if (classDescriptor != null) {
if (classDescriptor.getKind() == ClassKind.INTERFACE) {
trace.report(CONSTRUCTOR_IN_TRAIT.on(elementToMark));
}
// allow only one delegating constructor
if (primaryConstructorDelegationCall[0] == null) {
primaryConstructorDelegationCall[0] = results.getResultingCall();
@@ -374,6 +371,7 @@ public class BodyResolver {
}
if (descriptor.getKind() != ClassKind.INTERFACE &&
descriptor.getUnsubstitutedPrimaryConstructor() != null &&
superClass.getKind() != ClassKind.INTERFACE &&
!superClass.getConstructors().isEmpty() &&
!ErrorUtils.isError(superClass)
) {
@@ -429,6 +427,8 @@ public class BodyResolver {
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
if (classDescriptor != null) {
if (ErrorUtils.isError(classDescriptor)) continue;
if (classDescriptor.getKind() != ClassKind.INTERFACE) {
if (supertypeOwner.getKind() == ClassKind.ENUM_CLASS) {
trace.report(CLASS_IN_SUPERTYPE_FOR_ENUM.on(typeReference));
@@ -501,8 +501,7 @@ public class BodyResolver {
private void resolvePrimaryConstructorParameters(@NotNull BodiesResolveContext c) {
for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
if (!(entry.getKey() instanceof JetClass)) continue;
JetClass klass = (JetClass) entry.getKey();
JetClassOrObject klass = entry.getKey();
ClassDescriptorWithResolutionScopes classDescriptor = entry.getValue();
ConstructorDescriptor unsubstitutedPrimaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();

View File

@@ -87,6 +87,8 @@ public class DeclarationsChecker {
checkObject((JetObjectDeclaration) classOrObject, classDescriptor);
}
checkPrimaryConstructor(classOrObject, classDescriptor);
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor);
}
@@ -244,7 +246,6 @@ public class DeclarationsChecker {
private void checkClass(BodiesResolveContext c, JetClass aClass, ClassDescriptorWithResolutionScopes classDescriptor) {
AnnotationResolver.reportDeprecatedAnnotationSyntax(aClass.getAnnotations(), trace);
checkOpenMembers(classDescriptor);
checkPrimaryConstructor(aClass, classDescriptor);
checkTypeParameters(aClass);
if (aClass.isInterface()) {
@@ -271,9 +272,9 @@ public class DeclarationsChecker {
}
}
private void checkPrimaryConstructor(JetClass aClass, ClassDescriptor classDescriptor) {
private void checkPrimaryConstructor(JetClassOrObject classOrObject, ClassDescriptor classDescriptor) {
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
JetPrimaryConstructor declaration = aClass.getPrimaryConstructor();
JetPrimaryConstructor declaration = classOrObject.getPrimaryConstructor();
if (primaryConstructor == null || declaration == null) return;
for (JetParameter parameter : declaration.getValueParameters()) {
@@ -287,6 +288,10 @@ public class DeclarationsChecker {
trace.report(MISSING_CONSTRUCTOR_KEYWORD.on(declaration.getModifierList()));
}
if (!(classOrObject instanceof JetClass)) {
trace.report(CONSTRUCTOR_IN_OBJECT.on(declaration));
}
checkConstructorDeclaration(primaryConstructor, declaration);
}
@@ -303,9 +308,9 @@ public class DeclarationsChecker {
}
private void checkConstructorInTrait(JetClass klass) {
JetParameterList primaryConstructorParameterList = klass.getPrimaryConstructorParameterList();
if (primaryConstructorParameterList != null) {
trace.report(CONSTRUCTOR_IN_TRAIT.on(primaryConstructorParameterList));
JetPrimaryConstructor primaryConstructor = klass.getPrimaryConstructor();
if (primaryConstructor != null) {
trace.report(CONSTRUCTOR_IN_TRAIT.on(primaryConstructor));
}
}

View File

@@ -210,7 +210,7 @@ class FunctionDescriptorResolver(
public fun resolvePrimaryConstructorDescriptor(
scope: JetScope,
classDescriptor: ClassDescriptor,
classElement: JetClass,
classElement: JetClassOrObject,
trace: BindingTrace
): ConstructorDescriptorImpl? {
if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY || !classElement.hasPrimaryConstructor()) return null

View File

@@ -23,7 +23,7 @@ import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors.CONSTRUCTOR_IN_TRAIT
import org.jetbrains.kotlin.diagnostics.Errors.MANY_COMPANION_OBJECTS
import org.jetbrains.kotlin.diagnostics.Errors.SECONDARY_CONSTRUCTOR_IN_OBJECT
import org.jetbrains.kotlin.diagnostics.Errors.CONSTRUCTOR_IN_OBJECT
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
@@ -176,7 +176,7 @@ public class LazyTopDownAnalyzer {
}
else if (jetDeclaration is JetSecondaryConstructor) {
if (DescriptorUtils.isSingletonOrAnonymousObject(classDescriptor)) {
trace!!.report(SECONDARY_CONSTRUCTOR_IN_OBJECT.on(jetDeclaration))
trace!!.report(CONSTRUCTOR_IN_OBJECT.on(jetDeclaration))
}
else if (classDescriptor.getKind() == ClassKind.INTERFACE) {
trace!!.report(CONSTRUCTOR_IN_TRAIT.on(jetDeclaration))
@@ -199,10 +199,6 @@ public class LazyTopDownAnalyzer {
}
override fun visitSecondaryConstructor(constructor: JetSecondaryConstructor) {
val classDescriptor = lazyDeclarationResolver!!.resolveToDescriptor(constructor.getClassOrObject()) as ClassDescriptor
if (!DescriptorUtils.canHaveSecondaryConstructors(classDescriptor)) {
return
}
c.getSecondaryConstructors().put(constructor, lazyDeclarationResolver!!.resolveToDescriptor(constructor) as ConstructorDescriptor)
registerScope(c, constructor)
}

View File

@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext;
import org.jetbrains.kotlin.resolve.calls.context.CheckValueArgumentsMode;
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
@@ -283,7 +283,7 @@ public class ArgumentTypeResolver {
// For an unsafe call, we should not do it,
// otherwise not-null will propagate to successive statements
// Sample: x?.foo(x.bar()) // Inside foo call, x is not-nullable
if (PsiUtilPackage.isSafeCall(call)) {
if (CallUtilPackage.isSafeCall(call)) {
initialDataFlowInfo = initialDataFlowInfo.disequate(receiverDataFlowValue, DataFlowValue.NULL);
}
}

View File

@@ -349,9 +349,12 @@ public class CallResolver {
Collection<ConstructorDescriptor> constructors = delegateClassDescriptor.getConstructors();
if (!isThisCall && currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on(
(JetConstructorDelegationCall) calleeExpression.getParent()
));
if (DescriptorUtils.canHaveDeclaredConstructors(currentClassDescriptor)) {
// Diagnostic is meaningless when reporting on interfaces and object
context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on(
(JetConstructorDelegationCall) calleeExpression.getParent()
));
}
if (call.isImplicit()) return OverloadResolutionResultsImpl.nameNotFound();
}

View File

@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.kotlin.resolve.calls.context.*;
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl;
@@ -637,7 +638,7 @@ public class CandidateResolver {
D candidateDescriptor = candidateCall.getCandidateDescriptor();
if (TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) return SUCCESS;
boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && PsiUtilPackage.isExplicitSafeCall(candidateCall.getCall());
boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && CallUtilPackage.isExplicitSafeCall(candidateCall.getCall());
boolean isSubtypeBySmartCast = SmartCastUtils.isSubTypeBySmartCastIgnoringNullability(
receiverArgument, receiverParameter.getType(), context);
if (!isSubtypeBySmartCast) {

View File

@@ -21,6 +21,7 @@ import com.google.common.collect.Sets;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor;
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
@@ -37,6 +38,8 @@ import java.util.Map;
import java.util.Set;
import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.INVOKE_ON_FUNCTION_TYPE;
import static org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.NON_KOTLIN_FUNCTION;
import static org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET;
import static org.jetbrains.kotlin.resolve.calls.ValueArgumentsToParametersMapper.Status.*;
@@ -150,11 +153,17 @@ public class ValueArgumentsToParametersMapper {
public ProcessorState processNamedArgument(@NotNull ValueArgument argument) {
assert argument.isNamed();
D candidate = candidateCall.getCandidateDescriptor();
JetSimpleNameExpression nameReference = argument.getArgumentName().getReferenceExpression();
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(nameReference.getReferencedNameAsName());
if (!candidateCall.getCandidateDescriptor().hasStableParameterNames()) {
report(NAMED_ARGUMENTS_NOT_ALLOWED.on(nameReference));
if (!candidate.hasStableParameterNames()) {
report(NAMED_ARGUMENTS_NOT_ALLOWED.on(
nameReference,
candidate instanceof FunctionInvokeDescriptor ? INVOKE_ON_FUNCTION_TYPE : NON_KOTLIN_FUNCTION
));
}
if (valueParameterDescriptor == null) {
report(NAMED_PARAMETER_NOT_FOUND.on(nameReference, nameReference));
unmappedArguments.add(argument);

View File

@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.psi.Call;
import org.jetbrains.kotlin.psi.ValueArgument;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace;
import org.jetbrains.kotlin.resolve.calls.CallResolverUtil;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus;
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
@@ -288,7 +288,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
@Override
public boolean isSafeCall() {
return PsiUtilPackage.isSafeCall(call);
return CallUtilPackage.isSafeCall(call);
}
@NotNull

View File

@@ -87,7 +87,14 @@ private fun createSynthesizedFunctionWithFirstParameterAsReceiver(descriptor: Fu
}
fun isSynthesizedInvoke(descriptor: DeclarationDescriptor): Boolean {
return descriptor.getName() == OperatorConventions.INVOKE &&
(descriptor as? FunctionDescriptor)?.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED &&
descriptor.getContainingDeclaration() is FunctionClassDescriptor
if (descriptor.getName() != OperatorConventions.INVOKE || descriptor !is FunctionDescriptor) return false
var real: FunctionDescriptor = descriptor
while (!real.getKind().isReal()) {
// You can't override two different synthesized invokes at the same time
real = real.getOverriddenDescriptors().singleOrNull() ?: return false
}
return real.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED &&
real.getContainingDeclaration() is FunctionClassDescriptor
}

View File

@@ -20,15 +20,16 @@ import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getTextWithLocation
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.CALL
import org.jetbrains.kotlin.resolve.BindingContext.RESOLVED_CALL
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
import org.jetbrains.kotlin.resolve.calls.CallTransformer
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.utils.sure
// resolved call
@@ -176,6 +177,18 @@ public fun JetExpression.getFunctionResolvedCallWithAssert(context: BindingConte
assert(resolvedCall.getResultingDescriptor() is FunctionDescriptor) {
"ResolvedCall for this expression must be ResolvedCall<? extends FunctionDescriptor>: ${this.getTextWithLocation()}"
}
[suppress("UNCHECKED_CAST")]
@suppress("UNCHECKED_CAST")
return resolvedCall as ResolvedCall<out FunctionDescriptor>
}
public fun Call.isSafeCall(): Boolean {
if (this is CallTransformer.CallForImplicitInvoke) {
//implicit safe 'invoke'
if (getOuterCall().isExplicitSafeCall()) {
return true
}
}
return isExplicitSafeCall()
}
public fun Call.isExplicitSafeCall(): Boolean = getCallOperationNode()?.getElementType() == JetTokens.SAFE_ACCESS

View File

@@ -143,7 +143,7 @@ public class LazyDeclarationResolver {
public DeclarationDescriptor visitParameter(@NotNull JetParameter parameter, Void data) {
PsiElement grandFather = parameter.getParent().getParent();
if (grandFather instanceof JetPrimaryConstructor) {
JetClass jetClass = ((JetPrimaryConstructor) grandFather).getContainingClass();
JetClassOrObject jetClass = ((JetPrimaryConstructor) grandFather).getContainingClassOrObject();
// This is a primary constructor parameter
ClassDescriptor classDescriptor = getClassDescriptor(jetClass);
if (parameter.hasValOrVarNode()) {
@@ -183,7 +183,7 @@ public class LazyDeclarationResolver {
@Override
public DeclarationDescriptor visitPrimaryConstructor(@NotNull JetPrimaryConstructor constructor, Void data) {
JetClass klass = constructor.getContainingClass();
JetClassOrObject klass = constructor.getContainingClassOrObject();
getClassDescriptor(klass).getConstructors();
return getBindingContext().get(BindingContext.CONSTRUCTOR, klass);
}

View File

@@ -55,8 +55,9 @@ class AliasImportsIndexed(allImports: Collection<JetImportDirective>) : IndexedI
val builder = ImmutableListMultimap.builder<Name, JetImportDirective>()
for (directive in imports) {
val path = directive.getImportPath() ?: continue // can be some parse errors
builder.put(path.getImportedName()!!, directive)
val path = directive.getImportPath() ?: continue // parse error
val importedName = path.getImportedName() ?: continue // parse error
builder.put(importedName, directive)
}
builder.build()

View File

@@ -51,12 +51,6 @@ public class JetClassInfo extends JetClassOrObjectInfo<JetClass> {
return element.getTypeParameterList();
}
@NotNull
@Override
public List<? extends JetParameter> getPrimaryConstructorParameters() {
return element.getPrimaryConstructorParameters();
}
@NotNull
@Override
public ClassKind getClassKind() {

View File

@@ -90,6 +90,12 @@ public abstract class JetClassOrObjectInfo<E extends JetClassOrObject> implement
return body == null ? Collections.<JetAnnotationEntry>emptyList() : body.getDanglingAnnotations();
}
@NotNull
@Override
public List<? extends JetParameter> getPrimaryConstructorParameters() {
return element.getPrimaryConstructorParameters();
}
@Override
public String toString() {
return "info for " + element.getText();

View File

@@ -42,12 +42,6 @@ public class JetObjectInfo extends JetClassOrObjectInfo<JetObjectDeclaration> {
return null;
}
@NotNull
@Override
public List<? extends JetParameter> getPrimaryConstructorParameters() {
return Collections.emptyList();
}
@NotNull
@Override
public ClassKind getClassKind() {

View File

@@ -134,8 +134,7 @@ public open class LazyClassMemberScope(
private fun generateDataClassMethods(result: MutableCollection<FunctionDescriptor>, name: Name) {
if (!KotlinBuiltIns.isData(thisDescriptor)) return
val constructor = getPrimaryConstructor()
if (constructor == null) return
val constructor = getPrimaryConstructor() ?: return
val primaryConstructorParameters = declarationProvider.getOwnerInfo().getPrimaryConstructorParameters()
assert(constructor.getValueParameters().size() == primaryConstructorParameters.size()) { "From descriptor: " + constructor.getValueParameters().size() + " but from PSI: " + primaryConstructorParameters.size() }
@@ -150,8 +149,6 @@ public open class LazyClassMemberScope(
val properties = getProperties(parameter.getName())
if (properties.isEmpty()) continue
assert(properties.size() == 1) { "A constructor parameter is resolved to more than one (" + properties.size() + ") property: " + parameter }
val property = properties.iterator().next() as PropertyDescriptor
++componentIndex
@@ -275,15 +272,12 @@ public open class LazyClassMemberScope(
protected open fun resolvePrimaryConstructor(): ConstructorDescriptor? {
val ownerInfo = declarationProvider.getOwnerInfo()
val classOrObject = ownerInfo.getCorrespondingClassOrObject()
if (!thisDescriptor.getKind().isSingleton() && !classOrObject.isObjectLiteral()) {
assert(classOrObject is JetClass) { "No JetClass for $thisDescriptor" }
classOrObject as JetClass
val classOrObject = ownerInfo.getCorrespondingClassOrObject() ?: return null
if (DescriptorUtils.isTrait(thisDescriptor) && declarationProvider.getOwnerInfo().getPrimaryConstructorParameters().isEmpty()) {
return null
}
val hasPrimaryConstructor = classOrObject.hasExplicitPrimaryConstructor()
if (DescriptorUtils.isTrait(thisDescriptor) && !hasPrimaryConstructor) return null
if (DescriptorUtils.canHaveDeclaredConstructors(thisDescriptor) || hasPrimaryConstructor) {
val constructor = c.functionDescriptorResolver.resolvePrimaryConstructorDescriptor(
thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor, classOrObject, trace)
constructor ?: return null
@@ -298,10 +292,7 @@ public open class LazyClassMemberScope(
}
private fun resolveSecondaryConstructors(): Collection<ConstructorDescriptor> {
val classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject()
if (!DescriptorUtils.canHaveSecondaryConstructors(thisDescriptor)) return emptyList()
// Script classes have usual class descriptors but do not have conventional class body
if (classOrObject !is JetClass) return emptyList()
val classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject() ?: return emptyList()
return classOrObject.getSecondaryConstructors().map { constructor ->
val descriptor = c.functionDescriptorResolver.resolveSecondaryConstructorDescriptor(

View File

@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.annotations.argumentValue
import org.jetbrains.kotlin.resolve.annotations.deprecatedAnnotationMessage
public class DeprecatedSymbolValidator : SymbolUsageValidator {
private val JAVA_DEPRECATED = FqName(javaClass<Deprecated>().getName())
@@ -89,28 +91,13 @@ public class DeprecatedSymbolValidator : SymbolUsageValidator {
}
private fun createDeprecationDiagnostic(element: PsiElement, descriptor: DeclarationDescriptor, deprecated: AnnotationDescriptor): Diagnostic {
val message = getMessageFromAnnotationDescriptor(deprecated)
val message = deprecated.deprecatedAnnotationMessage()
return if (message == null)
Errors.DEPRECATED_SYMBOL.on(element, descriptor)
else
Errors.DEPRECATED_SYMBOL_WITH_MESSAGE.on(element, descriptor, message)
}
private fun getMessageFromAnnotationDescriptor(descriptor: AnnotationDescriptor): String? {
val parameterName = Name.identifier("value")
for ((parameterDescriptor, argument) in descriptor.getAllValueArguments()) {
if (parameterDescriptor.getName() == parameterName) {
val parameterValue = argument.getValue()
if (parameterValue is String) {
return parameterValue
}
else
return null
}
}
return null
}
private val PROPERTY_SET_OPERATIONS = TokenSet.create(JetTokens.EQ, JetTokens.PLUSEQ, JetTokens.MINUSEQ, JetTokens.MULTEQ, JetTokens.DIVEQ, JetTokens.PERCEQ, JetTokens.PLUSPLUS, JetTokens.MINUSMINUS)
fun propertyGetterWorkaround(propertyDescriptor: PropertyDescriptor, trace: BindingTrace, expression: PsiElement) {
// property getters do not come as callable yet, so we analyse surroundings to check for deprecation annotation on getter

View File

@@ -234,7 +234,7 @@ public class LightClassUtil {
@Nullable
private static PsiClass getWrappingClass(@NotNull JetDeclaration declaration) {
if (declaration instanceof JetParameter) {
JetClass constructorClass = JetPsiUtil.getClassIfParameterIsProperty((JetParameter) declaration);
JetClassOrObject constructorClass = JetPsiUtil.getClassIfParameterIsProperty((JetParameter) declaration);
if (constructorClass != null) {
return getPsiClass(constructorClass);
}

View File

@@ -17,22 +17,24 @@
package org.jetbrains.kotlin.asJava
import com.intellij.psi.*
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.psi.*
import java.util.Collections
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import java.util.ArrayList
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
public fun JetClassOrObject.toLightClass(): KotlinLightClass? = LightClassUtil.getPsiClass(this) as KotlinLightClass?
public fun JetDeclaration.toLightElements(): List<PsiNamedElement> =
when (this) {
is JetClassOrObject -> Collections.singletonList(LightClassUtil.getPsiClass(this))
is JetClassOrObject -> LightClassUtil.getPsiClass(this).singletonOrEmptyList()
is JetNamedFunction,
is JetSecondaryConstructor -> Collections.singletonList(LightClassUtil.getLightClassMethod(this as JetFunction))
is JetSecondaryConstructor -> LightClassUtil.getLightClassMethod(this as JetFunction).singletonOrEmptyList()
is JetProperty -> LightClassUtil.getLightClassPropertyMethods(this).toList()
is JetPropertyAccessor -> Collections.singletonList(LightClassUtil.getLightClassAccessorMethod(this))
is JetPropertyAccessor -> LightClassUtil.getLightClassAccessorMethod(this).singletonOrEmptyList()
is JetParameter -> ArrayList<PsiNamedElement>().let { elements ->
toPsiParameter()?.let { psiParameter -> elements.add(psiParameter) }
LightClassUtil.getLightClassPropertyMethods(this).toCollection(elements)
@@ -49,8 +51,8 @@ public fun PsiElement.toLightMethods(): List<PsiMethod> =
is JetProperty -> LightClassUtil.getLightClassPropertyMethods(this).toList()
is JetParameter -> LightClassUtil.getLightClassPropertyMethods(this).toList()
is JetPropertyAccessor -> LightClassUtil.getLightClassAccessorMethod(this).singletonOrEmptyList()
is JetClass -> Collections.singletonList(LightClassUtil.getPsiClass(this).getConstructors()[0])
is PsiMethod -> Collections.singletonList(this)
is JetClass -> LightClassUtil.getPsiClass(this)?.getConstructors()?.first().singletonOrEmptyList()
is PsiMethod -> this.singletonList()
else -> listOf()
}
@@ -70,12 +72,12 @@ public fun JetParameter.toPsiParameter(): PsiParameter? {
val paramIndex = paramList.getParameters().indexOf(this)
val owner = paramList.getParent()
val lightParamIndex = if (owner != null && owner.isExtensionDeclaration()) paramIndex + 1 else paramIndex
val lightParamIndex = if (owner is JetDeclaration && owner.isExtensionDeclaration()) paramIndex + 1 else paramIndex
val method: PsiMethod? = when (owner) {
is JetFunction -> LightClassUtil.getLightClassMethod(owner)
is JetPropertyAccessor -> LightClassUtil.getLightClassAccessorMethod(owner)
is JetPrimaryConstructor -> LightClassUtil.getPsiClass(owner.getContainingClass())?.getConstructors()?.let { constructors ->
is JetPrimaryConstructor -> LightClassUtil.getPsiClass(owner.getContainingClassOrObject())?.getConstructors()?.let { constructors ->
if (constructors.isNotEmpty()) constructors[0] else null
}
else -> null

View File

@@ -1,7 +1,8 @@
class A {
fun foo() {
try {
val a = 1
var a = 1
a++
}
catch(e : Throwable) {

View File

@@ -6,6 +6,7 @@ class A {
fun foo() {
inlineFun ({
var zzz = it;
zzz++
})
}
}

View File

@@ -8,6 +8,7 @@ class A {
fun foo() {
inlineFun ({ l ->
var zzz = l;
zzz++
}, 11)
}
}

View File

@@ -7,6 +7,7 @@ class A {
var s = 1;
inlineFun ({
var zzz = 2;
zzz++
})
}
}

View File

@@ -7,9 +7,11 @@ class A {
var s = 0;
inlineFun {
var z = 1;
z++
inlineFun {
var zz2 = 2;
zz2++
}
}
}

View File

@@ -0,0 +1,13 @@
fun box(): String {
try {
return "OK"
if (1 == 1) {
val z = 2
}
if (3 == 3) {
val z = 4
}
} finally {
}
}

View File

@@ -0,0 +1,12 @@
fun box(): String {
try {
return "OK"
} finally {
if (1 == 1) {
val z = 2
}
if (3 == 3) {
val z = 4
}
}
}

View File

@@ -6,14 +6,17 @@ enum class Game {
companion object {
fun foo() = ROCK
val bar = PAPER
val values2 = values()
val scissors = valueOf("SCISSORS")
}
}
fun box(): String {
if (Game.foo() != Game.ROCK) return "Fail 1"
// TODO: fix initialization order and uncomment (KT-5761)
// if (Game.bar != Game.PAPER) return "Fail 2: ${Game.bar}"
if (Game.bar != Game.PAPER) return "Fail 2: ${Game.bar}"
if (Game.values().size() != 3) return "Fail 3"
if (Game.valueOf("SCISSORS") != Game.SCISSORS) return "Fail 4"
if (Game.values2.size() != 3) return "Fail 5"
if (Game.scissors != Game.SCISSORS) return "Fail 6"
return "OK"
}

View File

@@ -1,43 +1,36 @@
import java.lang.annotation.*
import kotlin.reflect.jvm.java
import kotlin.test.assertEquals
Retention(RetentionPolicy.RUNTIME)
annotation class Ann(val x: Int)
class A {
Ann(1) fun foo(Ann(2) x: Int, y: Int = 2, Ann(3) z: Int) {}
Ann(1) fun foo(x: Int, y: Int = 2, z: Int) {}
Ann(1) constructor(Ann(2) x: Int, y: Int = 2, Ann(3) z: Int)
Ann(1) constructor(x: Int, y: Int = 2, z: Int)
}
class B [Ann(1)] (Ann(2) x: Int, y: Int = 2, Ann(3) z: Int) {}
class B @Ann(1) constructor(x: Int, y: Int = 2, z: Int) {}
fun Array<out Annotation>.ann() = filterIsInstance<Ann>()
fun test(name: String, annotations: Array<out Annotation>, parameters: Array<out Array<out Annotation>>) {
assertEquals(1, annotations.ann()[0].x, "$name[0]")
assertEquals(2, parameters[0].ann()[0].x, "$name-param[0]")
assertEquals(0, parameters[1].ann().size(), "$name-param[1]")
assertEquals(3, parameters[2].ann()[0].x, "$name-param[2]")
fun test(name: String, annotations: Array<out Annotation>) {
assertEquals(1, annotations.filterIsInstance<Ann>().single().x, "$name[0]")
}
fun box(): String {
val foo = javaClass<A>().getDeclaredMethods().first { it.getName() == "foo" }
test("foo", foo.getDeclaredAnnotations(), foo.getParameterAnnotations())
test("foo", foo.getDeclaredAnnotations())
val fooDefault = javaClass<A>().getDeclaredMethods().first { it.getName() == "foo\$default" }
test("foo", foo.getDeclaredAnnotations(), foo.getParameterAnnotations())
test("foo", foo.getDeclaredAnnotations())
val (secondary, secondaryDefault) = javaClass<A>().getDeclaredConstructors().partition { it.getParameterTypes().size() == 3 }
test("secondary", secondary[0].getDeclaredAnnotations(), secondary[0].getParameterAnnotations())
test("secondary\$default", secondaryDefault[0].getDeclaredAnnotations(), secondaryDefault[0].getParameterAnnotations())
test("secondary", secondary[0].getDeclaredAnnotations())
test("secondary\$default", secondaryDefault[0].getDeclaredAnnotations())
val (primary, primaryDefault) = javaClass<B>().getConstructors().partition { it.getParameterTypes().size() == 3 }
test("primary", primary[0].getDeclaredAnnotations(), primary[0].getParameterAnnotations())
test("secondary\$default", primaryDefault[0].getDeclaredAnnotations(), primaryDefault[0].getParameterAnnotations())
test("primary", primary[0].getDeclaredAnnotations())
test("primary\$default", primaryDefault[0].getDeclaredAnnotations())
return "OK"
}

View File

@@ -0,0 +1,30 @@
import kotlin.test.assertEquals
import kotlin.jvm.internal.FunctionImpl
fun test(f: Function<*>, arity: Int) {
assertEquals(arity, (f as FunctionImpl).getArity())
}
fun foo(s: String, i: Int) {}
class A {
fun bar(s: String, i: Int) {}
}
fun Double.baz(s: String, i: Int) {}
fun box(): String {
test(::foo, 2)
test(A::bar, 3)
test(Double::baz, 3)
test(::box, 0)
fun local(x: Int) {}
test(::local, 1)
test(fun(s: String) = s, 1)
test(fun(){}, 0)
test({}, 0)
test({x: Int -> x}, 1)
return "OK"
}

View File

@@ -0,0 +1,33 @@
package test
public/*package*/ open class ClassObject {
public/*package*/ constructor ClassObject()
public/*package*/ open fun accessToClassObject(): kotlin.Unit
public/*package*/ open fun accessToInnerClass(): kotlin.Unit
public/*package*/ open fun accessToPackageObject(): kotlin.Unit
}
internal object PackageInner {
private constructor PackageInner()
internal final val value: kotlin.Int
internal final fun foo(): kotlin.Unit
}
internal final class WithClassObject {
public constructor WithClassObject()
internal companion object Companion {
private constructor Companion()
internal final val value: kotlin.Int
internal final val valueWithGetter: kotlin.Int
internal final var variable: kotlin.Int
internal final var variableWithAccessors: kotlin.Int
internal final fun foo(): kotlin.Unit
}
internal final class MyInner {
public constructor MyInner()
internal final val value: kotlin.Int
internal final fun foo(): kotlin.Unit
}
}

View File

@@ -0,0 +1,11 @@
package test
internal final class A {
public constructor A(/*0*/ kotlin.Int = ...)
internal final val a: kotlin.Int
}
public/*package*/ open class Simple {
public/*package*/ constructor Simple()
public/*package*/ open fun foo(): kotlin.Unit
}

View File

@@ -0,0 +1,12 @@
package test
internal final class A {
public constructor A(/*0*/ kotlin.Int = ..., /*1*/ kotlin.String = ...)
internal final val a: kotlin.Int
internal final val b: kotlin.String
}
public/*package*/ open class Simple {
public/*package*/ constructor Simple()
public/*package*/ open fun foo(): kotlin.Unit
}

View File

@@ -0,0 +1,36 @@
package test
public/*package*/ open class ExtendsAbstractListT {
public/*package*/ constructor ExtendsAbstractListT()
}
internal abstract class Mine</*0*/ T> : java.util.AbstractList<T> {
public constructor Mine</*0*/ T>()
protected/*protected and package*/ final /*fake_override*/ var modCount: kotlin.Int
public open /*fake_override*/ fun add(/*0*/ T!): kotlin.Boolean
public open /*fake_override*/ fun add(/*0*/ kotlin.Int, /*1*/ T!): kotlin.Unit
public open /*fake_override*/ fun addAll(/*0*/ kotlin.Collection<T!>): kotlin.Boolean
public open /*fake_override*/ fun addAll(/*0*/ kotlin.Int, /*1*/ (kotlin.MutableCollection<out T!>..kotlin.Collection<T!>?)): kotlin.Boolean
public open /*fake_override*/ fun clear(): kotlin.Unit
public open /*fake_override*/ fun contains(/*0*/ kotlin.Any?): kotlin.Boolean
public open /*fake_override*/ fun containsAll(/*0*/ kotlin.Collection<kotlin.Any?>): kotlin.Boolean
public abstract /*fake_override*/ fun get(/*0*/ kotlin.Int): T!
public open /*fake_override*/ fun indexOf(/*0*/ kotlin.Any!): kotlin.Int
public open /*fake_override*/ fun isEmpty(): kotlin.Boolean
public open /*fake_override*/ fun iterator(): kotlin.(Mutable)Iterator<T!>!
public open /*fake_override*/ fun lastIndexOf(/*0*/ kotlin.Any!): kotlin.Int
public open /*fake_override*/ fun listIterator(): kotlin.(Mutable)ListIterator<T!>!
public open /*fake_override*/ fun listIterator(/*0*/ kotlin.Int): kotlin.(Mutable)ListIterator<T!>!
invisible_fake open /*fake_override*/ fun outOfBoundsMsg(/*0*/ kotlin.Int): kotlin.String!
invisible_fake open /*fake_override*/ fun rangeCheckForAdd(/*0*/ kotlin.Int): kotlin.Unit
public open /*fake_override*/ fun remove(/*0*/ kotlin.Any?): kotlin.Boolean
public open /*fake_override*/ fun remove(/*0*/ kotlin.Int): T!
public open /*fake_override*/ fun removeAll(/*0*/ kotlin.Collection<kotlin.Any?>): kotlin.Boolean
protected/*protected and package*/ open /*fake_override*/ fun removeRange(/*0*/ kotlin.Int, /*1*/ kotlin.Int): kotlin.Unit
public open /*fake_override*/ fun retainAll(/*0*/ kotlin.Collection<kotlin.Any?>): kotlin.Boolean
public open /*fake_override*/ fun set(/*0*/ kotlin.Int, /*1*/ T!): T!
public abstract /*fake_override*/ fun size(): kotlin.Int
public open /*fake_override*/ fun subList(/*0*/ kotlin.Int, /*1*/ kotlin.Int): kotlin.(Mutable)List<T!>!
public open /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>!
public open /*fake_override*/ fun </*0*/ T> toArray(/*0*/ kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>!
}

View File

@@ -0,0 +1,32 @@
package test
internal abstract class Mine : java.util.List<kotlin.String> {
public constructor Mine()
public abstract /*fake_override*/ fun add(/*0*/ kotlin.Int, /*1*/ kotlin.String!): kotlin.Unit
public abstract /*fake_override*/ fun add(/*0*/ kotlin.String!): kotlin.Boolean
public abstract /*fake_override*/ fun addAll(/*0*/ (kotlin.MutableCollection<out kotlin.String!>..kotlin.Collection<kotlin.String!>?)): kotlin.Boolean
public abstract /*fake_override*/ fun addAll(/*0*/ kotlin.Int, /*1*/ (kotlin.MutableCollection<out kotlin.String!>..kotlin.Collection<kotlin.String!>?)): kotlin.Boolean
public abstract /*fake_override*/ fun clear(): kotlin.Unit
public abstract /*fake_override*/ fun contains(/*0*/ kotlin.Any!): kotlin.Boolean
public abstract /*fake_override*/ fun containsAll(/*0*/ kotlin.(Mutable)Collection<*>!): kotlin.Boolean
public abstract /*fake_override*/ fun get(/*0*/ kotlin.Int): kotlin.String!
public abstract /*fake_override*/ fun indexOf(/*0*/ kotlin.Any!): kotlin.Int
public abstract /*fake_override*/ fun isEmpty(): kotlin.Boolean
public abstract /*fake_override*/ fun iterator(): kotlin.(Mutable)Iterator<kotlin.String!>!
public abstract /*fake_override*/ fun lastIndexOf(/*0*/ kotlin.Any!): kotlin.Int
public abstract /*fake_override*/ fun listIterator(): kotlin.(Mutable)ListIterator<kotlin.String!>!
public abstract /*fake_override*/ fun listIterator(/*0*/ kotlin.Int): kotlin.(Mutable)ListIterator<kotlin.String!>!
public abstract /*fake_override*/ fun remove(/*0*/ kotlin.Any!): kotlin.Boolean
public abstract /*fake_override*/ fun remove(/*0*/ kotlin.Int): kotlin.String!
public abstract /*fake_override*/ fun removeAll(/*0*/ kotlin.(Mutable)Collection<*>!): kotlin.Boolean
public abstract /*fake_override*/ fun retainAll(/*0*/ kotlin.(Mutable)Collection<*>!): kotlin.Boolean
public abstract /*fake_override*/ fun set(/*0*/ kotlin.Int, /*1*/ kotlin.String!): kotlin.String!
public abstract /*fake_override*/ fun size(): kotlin.Int
public abstract /*fake_override*/ fun subList(/*0*/ kotlin.Int, /*1*/ kotlin.Int): kotlin.(Mutable)List<kotlin.String!>!
public abstract /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>!
public abstract /*fake_override*/ fun </*0*/ T> toArray(/*0*/ kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>!
}
public/*package*/ open class PlainExtendsListString {
public/*package*/ constructor PlainExtendsListString()
}

View File

@@ -0,0 +1,21 @@
package test
public/*package*/ open class ImplementsMapPP {
public/*package*/ constructor ImplementsMapPP()
}
internal abstract class Mine</*0*/ P1, /*1*/ P2> : java.util.Map<P2, P1> {
public constructor Mine</*0*/ P1, /*1*/ P2>()
public abstract /*fake_override*/ fun clear(): kotlin.Unit
public abstract /*fake_override*/ fun containsKey(/*0*/ kotlin.Any!): kotlin.Boolean
public abstract /*fake_override*/ fun containsValue(/*0*/ kotlin.Any!): kotlin.Boolean
public abstract /*fake_override*/ fun entrySet(): kotlin.(Mutable)Set<kotlin.(Mutable)Map.(Mutable)Entry<P2!, P1!>!>!
public abstract /*fake_override*/ fun get(/*0*/ kotlin.Any!): P1!
public abstract /*fake_override*/ fun isEmpty(): kotlin.Boolean
public abstract /*fake_override*/ fun keySet(): kotlin.(Mutable)Set<P2!>!
public abstract /*fake_override*/ fun put(/*0*/ P2!, /*1*/ P1!): P1!
public abstract /*fake_override*/ fun putAll(/*0*/ (kotlin.MutableMap<out P2!, out P1!>..kotlin.Map<out P2!, P1!>?)): kotlin.Unit
public abstract /*fake_override*/ fun remove(/*0*/ kotlin.Any!): P1!
public abstract /*fake_override*/ fun size(): kotlin.Int
public abstract /*fake_override*/ fun values(): kotlin.(Mutable)Collection<P1!>!
}

View File

@@ -0,0 +1,19 @@
package test
public/*package*/ open class InnerClass {
public/*package*/ constructor InnerClass()
public/*package*/ final var field1: test.Outer.Inner1!
public/*package*/ final var field2: test.Outer.Inner2!
}
internal final class Outer {
public constructor Outer()
internal final inner class Inner1 {
public constructor Inner1()
}
internal final inner class Inner2 {
public constructor Inner2(/*0*/ kotlin.String)
}
}

View File

@@ -0,0 +1,20 @@
package test
public/*package*/ open class InnerClassConstructors {
public/*package*/ constructor InnerClassConstructors()
// Static members
public open fun main(/*0*/ kotlin.Array<(out) kotlin.String!>!): kotlin.Unit
}
internal final class Outer {
public constructor Outer()
internal final inner class InnerGeneric {
public constructor InnerGeneric(/*0*/ kotlin.List<kotlin.String>)
}
internal final inner class InnerPrimitive {
public constructor InnerPrimitive(/*0*/ kotlin.Int)
}
}

View File

@@ -0,0 +1,20 @@
package test
public/*package*/ open class InnerClassOfGeneric {
public/*package*/ constructor InnerClassOfGeneric()
// Static members
public open fun main(/*0*/ kotlin.Array<(out) kotlin.String!>!): kotlin.Unit
}
internal final class Outer</*0*/ T> {
public constructor Outer</*0*/ T>()
internal final inner class Inner {
public constructor Inner(/*0*/ kotlin.List<T>)
}
internal final inner class InnerSimple {
public constructor InnerSimple()
}
}

View File

@@ -0,0 +1,9 @@
package test
internal final class Impossible</*0*/ P> {
public constructor Impossible</*0*/ P>()
}
public/*package*/ open class Simple {
public/*package*/ constructor Simple()
}

View File

@@ -0,0 +1,20 @@
package test
internal fun bar(/*0*/ test.K<*>): kotlin.Unit
internal open class K</*0*/ out T : test.K<T>> {
public constructor K</*0*/ out T : test.K<T>>()
internal final fun foo(): test.K<*>
internal final fun foo(/*0*/ test.K<*>): kotlin.Unit
}
public open class StarProjection {
public constructor StarProjection()
public/*package*/ open fun foo(/*0*/ test.K<*>!): kotlin.Unit
}
internal final class Sub : test.K<test.K<*>> {
public constructor Sub()
internal final /*fake_override*/ fun foo(): test.K<*>
internal final /*fake_override*/ fun foo(/*0*/ test.K<*>): kotlin.Unit
}

View File

@@ -0,0 +1,24 @@
package test
internal final enum class MyEnum : kotlin.Enum<test.MyEnum> {
public enum entry OK : test.MyEnum {
private constructor OK()
public final /*fake_override*/ fun compareTo(/*0*/ test.MyEnum): kotlin.Int
public final /*fake_override*/ fun name(): kotlin.String
public final /*fake_override*/ fun ordinal(): kotlin.Int
}
private constructor MyEnum()
public final /*fake_override*/ fun compareTo(/*0*/ test.MyEnum): kotlin.Int
public final /*fake_override*/ fun name(): kotlin.String
public final /*fake_override*/ fun ordinal(): kotlin.Int
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ kotlin.String): test.MyEnum
public final /*synthesized*/ fun values(): kotlin.Array<test.MyEnum>
}
public open class kt3561 {
public constructor kt3561()
public open fun getEntryName(): test.MyEnum!
}

View File

@@ -0,0 +1,30 @@
package test
internal final enum class MyEnum : kotlin.Enum<test.MyEnum> {
public enum entry ENTRY : test.MyEnum {
private constructor ENTRY()
kotlin.deprecated(value = "": kotlin.String) internal final /*fake_override*/ val ord: kotlin.Int
public final /*fake_override*/ fun compareTo(/*0*/ test.MyEnum): kotlin.Int
internal final /*fake_override*/ fun f(/*0*/ java.lang.Deprecated() kotlin.Int): kotlin.Unit
public final /*fake_override*/ fun name(): kotlin.String
public final /*fake_override*/ fun ordinal(): kotlin.Int
}
private constructor MyEnum(/*0*/ kotlin.deprecated(value = "": kotlin.String) kotlin.Int)
kotlin.deprecated(value = "": kotlin.String) internal final val ord: kotlin.Int
public final /*fake_override*/ fun compareTo(/*0*/ test.MyEnum): kotlin.Int
internal final fun f(/*0*/ java.lang.Deprecated() kotlin.Int): kotlin.Unit
public final /*fake_override*/ fun name(): kotlin.String
public final /*fake_override*/ fun ordinal(): kotlin.Int
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ kotlin.String): test.MyEnum
public final /*synthesized*/ fun values(): kotlin.Array<test.MyEnum>
}
public open class kt4050 {
public constructor kt4050()
// Static members
public open fun main(/*0*/ kotlin.Array<(out) kotlin.String!>!): kotlin.Unit
}

View File

@@ -0,0 +1,7 @@
// KT-7892 Parameter with default value in enum's constructor breaks Java compilation
package test;
public class DefaultArgumentInEnumConstructor {
static K entry = K.ENTRY;
}

View File

@@ -0,0 +1,5 @@
package test
enum class K(private val default: String = "default") {
ENTRY()
}

View File

@@ -0,0 +1,28 @@
package test
public open class DefaultArgumentInEnumConstructor {
public constructor DefaultArgumentInEnumConstructor()
// Static members
public/*package*/ final var entry: test.K!
}
internal final enum class K : kotlin.Enum<test.K> {
public enum entry ENTRY : test.K {
private constructor ENTRY()
invisible_fake final /*fake_override*/ val default: kotlin.String
public final /*fake_override*/ fun compareTo(/*0*/ test.K): kotlin.Int
public final /*fake_override*/ fun name(): kotlin.String
public final /*fake_override*/ fun ordinal(): kotlin.Int
}
private constructor K(/*0*/ kotlin.String = ...)
private final val default: kotlin.String
public final /*fake_override*/ fun compareTo(/*0*/ test.K): kotlin.Int
public final /*fake_override*/ fun name(): kotlin.String
public final /*fake_override*/ fun ordinal(): kotlin.Int
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ kotlin.String): test.K
public final /*synthesized*/ fun values(): kotlin.Array<test.K>
}

View File

@@ -0,0 +1,13 @@
package test
public open class AccessorGenericSignature {
public constructor AccessorGenericSignature()
private final val b: test.BadClass!
}
public final class BadClass {
public constructor BadClass()
private final fun </*0*/ D> bar(/*0*/ kotlin.List<D>): kotlin.Unit
private final fun </*0*/ E : kotlin.Number, /*1*/ F : kotlin.MutableList<E>> baz(/*0*/ kotlin.List<F>): kotlin.Unit
internal final fun foo(): kotlin.Unit
}

View File

@@ -0,0 +1,7 @@
package test
internal fun anyany(/*0*/ kotlin.Any, /*1*/ java.util.List<kotlin.String>): kotlin.Any
public/*package*/ open class Any {
public/*package*/ constructor Any()
}

View File

@@ -0,0 +1,7 @@
package test
internal fun ohMy(/*0*/ kotlin.Array<kotlin.IntArray>): kotlin.Array<kotlin.IntArray>
public/*package*/ open class ArrayOfIntArray {
public/*package*/ constructor ArrayOfIntArray()
}

View File

@@ -0,0 +1,7 @@
package test
internal fun ohMy(/*0*/ kotlin.Array<kotlin.Array<kotlin.Int>>, /*1*/ java.util.List<kotlin.String>): kotlin.Array<kotlin.Array<kotlin.Int>>
public/*package*/ open class ArrayOfIntArray {
public/*package*/ constructor ArrayOfIntArray()
}

View File

@@ -0,0 +1,12 @@
package test
public open class ClashingSignaturesWithoutReturnType {
public constructor ClashingSignaturesWithoutReturnType()
public/*package*/ open fun test(/*0*/ kotlin.(Mutable)List<kotlin.String!>!, /*1*/ kotlin.(Mutable)List<kotlin.Int!>!): kotlin.Unit
}
internal final class K {
public constructor K()
internal final fun foo(/*0*/ kotlin.List<kotlin.Int>): kotlin.Int
internal final fun foo(/*0*/ kotlin.List<kotlin.String>): kotlin.String
}

View File

@@ -0,0 +1,25 @@
package test
internal final class Impl : test.Trait {
public constructor Impl()
internal open val bar: kotlin.Int
internal open fun foo(): kotlin.Unit
}
public/*package*/ open class JavaClass {
public/*package*/ constructor JavaClass()
// Static members
public open fun main(/*0*/ kotlin.Array<(out) kotlin.String!>!): kotlin.Unit
}
internal final class Test : test.Trait {
public constructor Test()
internal open /*delegation*/ val bar: kotlin.Int
internal open /*delegation*/ fun foo(): kotlin.Unit
}
internal interface Trait {
internal abstract val bar: kotlin.Int
internal abstract fun foo(): kotlin.Unit
}

View File

@@ -0,0 +1,8 @@
package test
internal fun kotlin.String.noParam(): kotlin.Unit
internal fun kotlin.String.param(/*0*/ kotlin.String): kotlin.Unit
public/*package*/ open class GenericArray {
public/*package*/ constructor GenericArray()
}

View File

@@ -0,0 +1,10 @@
package test
internal fun </*0*/ P> ffgg(/*0*/ kotlin.Array<P>): kotlin.Array<P>
public/*package*/ open class GenericArray {
public/*package*/ constructor GenericArray()
// Static members
public open fun ggff(): kotlin.Unit
}

View File

@@ -0,0 +1,10 @@
package test
internal fun f(): kotlin.String
public/*package*/ open class Hello {
public/*package*/ constructor Hello()
// Static members
public open fun xx(): kotlin.Unit
}

View File

@@ -0,0 +1,7 @@
package test
internal fun lll(/*0*/ kotlin.Int): kotlin.Int
public/*package*/ open class Int {
public/*package*/ constructor Int()
}

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