Compare commits

...

249 Commits

Author SHA1 Message Date
Dmitry Jemerov
45528e2e8e increase codecache size for tests run configuration 2015-08-24 20:32:25 +03:00
Dmitry Jemerov
72429f7b1c bump max permgen size for All tests configuration 2015-08-24 20:32:01 +03:00
Nikolay Krasko
99c7ab75c4 Force building markdown artifacts to avoid standard library compatibility issues 2015-08-24 14:59:19 +03:00
Nikolay Krasko
e1131b4e78 Revert using properties instead of methods 2015-08-21 16:11:14 +03:00
Nikolay Krasko
9b074d490d Cache information about library in file user data (KT-8537)
KT-8537 Kotlin plugin is causing Intellij to freeze during Indexing

 #Fix KT-8537
2015-08-21 15:59:59 +03:00
Nikolay Krasko
e4f6d8589a Store on local jar files to have valid timestamp 2015-08-21 15:59:56 +03:00
Nikolay Krasko
34acef25f5 Simplify jar-processor framework 2015-08-21 15:59:53 +03:00
Nikolay Krasko
188e85c6b1 Create background jar-processor that can store meta information for jars
Conflicts:
	idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/KotlinJavaScriptLibraryDetectionUtil.kt
	idea/src/META-INF/plugin.xml
	idea/src/org/jetbrains/kotlin/idea/PluginStartupComponent.java
2015-08-21 15:59:45 +03:00
Nikolay Krasko
b5f7ccfb84 Update to 141.1532.4 2015-08-21 15:51:55 +03:00
Michael Nedzelsky
adb4817fc0 kdoc: pegdown 1.1.0 -> 1.5.0 & fix KotlinModel 2015-08-17 17:07:30 +03:00
Natalia Ukhorskaya
94e827747e Change until version of plugin for Android Studio compatibility 2015-08-04 17:38:49 +03:00
Nikolay Krasko
65269976c7 Fake commit to activate dependency on teamcity 2015-07-30 22:39:10 +03:00
Ilya Chernikov
18b6a7f741 Merge pull request #728 from JetBrains/rr/gradle-plugin-classloading-M12
Fixing gradle plugin classloading, refs: KT-6451
2015-07-30 11:04:52 +02:00
ligee
1ffdeff757 Some more minor fixes after review 2015-07-30 10:39:48 +02:00
ligee
c9057704eb moving embeddable compiler jar creation to libraries/maven, using maven-shade-plugin instead of jarjar; configuring more relocations of 3-party libs 2015-07-29 22:52:33 +02:00
ligee
928769e714 Fixing minor issues after review 2015-07-29 18:11:50 +02:00
ligee
a3b7be4c1a Dropping custom classloading again, now without creating a transparent one, restoring cleanup for gradle <2.4 to minimize leaks under daemon, adding diagnostics 2015-07-29 13:19:02 +02:00
ligee
6801d8a672 Using isolated classloader again, but as a singleton; regular compiler jar instead of embeddable; more logging 2015-07-23 20:48:31 +02:00
Nikolay Krasko
31e63fed1d Use partial resolve for getting annotation fqn
#KT-8557 In Progress
2015-07-22 15:22:14 +03:00
Nikolay Krasko
b622f332e4 Test for annotation resolve 2015-07-22 15:22:06 +03:00
Nikolay Krasko
fc97978ac8 Minor: remove commented code 2015-07-22 15:13:49 +03:00
ligee
200638c84d Implementing simple classloading for plugin core, since embeddable compiler allows it
(cherry picked from commit 587d75a)
2015-07-22 09:36:41 +02:00
ligee
7fa59d49bd Adding new target - embeddable compiler (after jarjar), using it in the gradle plugin
(cherry picked from commit bf4b26f)
(cherry picked from commit e38d904)
2015-07-22 09:36:28 +02:00
Nikolay Krasko
e86ac42b89 Disable annotation check for Android Studio and non-android sdk
Android studio always creates that sdk from scratch so no configuration will be stored after restart (KT-7517)
2015-07-16 18:47:28 +03:00
Yan Zhulanow
cf19b7ad5f Revert publicField-related commits 2015-07-15 00:58:49 +03:00
Zalim Bashorov
556aea8d6b JS: don't pollute object with $metadata$
#KT-8126 Fixed
(cherry picked from commit f7ccb38)
2015-07-14 00:37:53 +03:00
Nikolay Krasko
e549376368 Fake commit to activate dependency on teamcity 2015-07-13 13:54:09 +03:00
Nikolay Krasko
82ce60f5c7 Empty commit to activate dependency on teamcity 2015-07-13 13:28:15 +03:00
Yan Zhulanow
e8a475973b Change bootstrap.locator to M12.1 2015-07-10 15:32:39 +03:00
Michael Nedzelsky
d016c40ea4 fix KT-7879 KotlinJS - Cannot browse jslib sources
#KT-7879 Fixed
2015-07-09 21:21:23 +03:00
Michael Nedzelsky
4d0e7d3b28 fix KT-7932 plugin generates absolute path to kotlin-jslib.jar for JS module (in .iml files)
#KT-7932 Fixed
2015-07-09 21:21:20 +03:00
Michael Nedzelsky
f3fed44d66 remove KotlinJavaScriptLibraryPresentationProvider
#KT-8056 Fixed
#KT-8058 Fixed
#KT-8398 Fixed
2015-07-09 21:21:17 +03:00
Yan Zhulanow
bbf5c575c2 Minor: Replace lazy with Delegates.lazy() 2015-07-09 15:27:49 +03:00
Yan Zhulanow
b7267b7fe9 FileKeyword test fix: add new line 2015-07-09 01:23:54 +03:00
Yan Zhulanow
0f8b636bc5 Fix tests on M12/bootstrap 2015-07-08 21:33:51 +03:00
Yan Zhulanow
c893df200d Fix muted completion test for the @file keyword
(cherry picked from commit 9cb88a9)
2015-07-07 17:47:27 +03:00
Yan Zhulanow
d4b8139a7f Use KotlinJvmCheckerProvider to check @publicField
(cherry picked from commit 9c8ea54)
2015-07-07 17:46:50 +03:00
Yan Zhulanow
4800147f4e publicField & field in companion object
(cherry picked from commit 3bcdee2)
2015-07-07 17:30:32 +03:00
Yan Zhulanow
9fcfb6a823 Add tests for publicField
(cherry picked from commit 74f44dd)
2015-07-07 17:30:24 +03:00
Yan Zhulanow
58867d5500 Add publicField annotation
(cherry picked from commit bffb24b)
2015-07-07 17:30:16 +03:00
Yan Zhulanow
b739794c3e kapt: Add class declarations test in AP wrapper
(cherry picked from commit 441e72a)
2015-07-07 17:27:00 +03:00
Yan Zhulanow
5135e24bd1 kapt: Add inherited annotations test
(cherry picked from commit c6ac878)
2015-07-07 17:26:55 +03:00
Yan Zhulanow
97805ce031 Minor: fix deprecations in Kotlin Android Extensions code
(cherry picked from commit cf08390)
2015-07-07 17:26:48 +03:00
Yan Zhulanow
60d5559d44 kapt: Support inherited annotations in Gradle
(cherry picked from commit 700d495)
2015-07-07 17:26:42 +03:00
Yan Zhulanow
d790ea9604 kapt: Support inherited annotations in AP wrapper
(cherry picked from commit a90f175)
2015-07-07 17:26:37 +03:00
Yan Zhulanow
a7cac634fc Add tests for inherited annotations (class declarations)
(cherry picked from commit afa3ae4)
2015-07-07 17:26:33 +03:00
Yan Zhulanow
097b82084c kapt: Support inherited annotations in Kotlin plugin
(cherry picked from commit 09c3bd8)
2015-07-07 17:26:29 +03:00
Yan Zhulanow
1a809eafae kapt: Use actual classpath in the second Kotlin task as well
(cherry picked from commit d089719)
2015-07-07 17:26:22 +03:00
Yan Zhulanow
1ed1772e6c kapt: Fix ConcurrentModificationException in Gradle
(cherry picked from commit 5f85a02)
2015-07-07 17:26:18 +03:00
Yan Zhulanow
cd06178dda kapt: Pass annotation declarations options via Java APT options
(cherry picked from commit d9ac8c9)
2015-07-07 17:26:13 +03:00
Yan Zhulanow
33ed77e87b kapt: Support lazy evaluation of additional kapt arguments in test
(cherry picked from commit 205585c)
2015-07-07 17:26:08 +03:00
Yan Zhulanow
00b57b6fbf Add Gradle test for additional kapt arguments
(cherry picked from commit 8a10de3)
2015-07-07 17:26:03 +03:00
Yan Zhulanow
8758898386 Add basic kapt tests
(cherry picked from commit 7f2bd5b)
2015-07-07 17:25:58 +03:00
Yan Zhulanow
b9207a7e8b Write annotations with RetensionPolicy(SOURCE) to light classes
(cherry picked from commit fee1726)
2015-07-07 17:25:52 +03:00
Yan Zhulanow
2a3523fbaa kapt: Lazy evaluation of additional arguments
(cherry picked from commit 17e6b8f)
2015-07-07 17:25:47 +03:00
Yan Zhulanow
ea7496294c Support additional compiler arguments
(cherry picked from commit f158b5b)
2015-07-07 17:25:43 +03:00
Yan Zhulanow
8085303783 kapt: Generate stub source file just after Kotlin compile
(cherry picked from commit 3ea4306)
2015-07-07 17:25:39 +03:00
Yan Zhulanow
f4277c9d9e Add simple annotation processor for tests
(cherry picked from commit 37d5250)
2015-07-07 17:25:34 +03:00
Yan Zhulanow
02ec7a152e Gradle: update annotation syntax
(cherry picked from commit 08fa9b6)
2015-07-07 17:25:30 +03:00
Yan Zhulanow
9f836e8151 Gradle: Subplugin loading process is unrelated to kapt
(cherry picked from commit e3c6f32)
2015-07-07 17:25:25 +03:00
Yan Zhulanow
19c3ab4487 kapt: Move class generation methods to core plugin
(cherry picked from commit 853cfdb)
2015-07-07 17:25:18 +03:00
Yan Zhulanow
14fdad27d8 kapt: Create kotlinAfterJava task after project evaluation
(cherry picked from commit 3cfdf21)
2015-07-07 17:25:07 +03:00
Yan Zhulanow
9e7544518c kapt: Warn on using android-apt with kapt
(cherry picked from commit 7561b43)
2015-07-07 17:25:00 +03:00
Yan Zhulanow
a1c5cef667 kapt: Fix compatibility with android-apt
(cherry picked from commit 39d7674)
2015-07-07 17:24:54 +03:00
Yan Zhulanow
e3b8ed3b49 Gradle: Remove logger argument in SubpluginEnvironment
(cherry picked from commit b9bfc65)
2015-07-07 17:24:49 +03:00
Yan Zhulanow
7303d18568 kapt: Add logging information
(cherry picked from commit c2073cb)
2015-07-07 17:24:44 +03:00
Yan Zhulanow
f475a7f7cf kapt: Initial .class stub support in Gradle
(cherry picked from commit 6ed5bbc)
2015-07-07 17:24:36 +03:00
Yan Zhulanow
1f1496c516 kapt: Do not fail if annotations.txt file does not exist
(cherry picked from commit 78af866)
2015-07-07 17:24:29 +03:00
Yan Zhulanow
70d627e972 Gradle: Do not inline getOrNull()
(cherry picked from commit a900a42)
2015-07-07 17:24:22 +03:00
Yan Zhulanow
5fa8ccca66 kapt: Stop compiler gracefully
(cherry picked from commit f1b6bd5)
2015-07-07 17:24:12 +03:00
Yan Zhulanow
63276e36fc kapt: Light class stub producer in compiler
(cherry picked from commit fbb8d28)
2015-07-07 17:24:01 +03:00
Yan Zhulanow
1b1affd7ac Add AnalyzeCompletedHandlerExtension
(cherry picked from commit 571c907)
2015-07-07 17:20:24 +03:00
Nikolay Krasko
ff631643aa Revert creating new psi file each time in provider file create
Revert "Getting decompiled file content through getPsi() doesn't work for local class files" (d564f44aad)
Revert "Refactoring: rename file" (dde295011b)
Revert "Create file must return new file, as old one can be invalidated (KT-8266)" (ef477f99e9)
2015-07-03 17:14:29 +03:00
Sergey Mashkov
b418288acd KT-8080 RemoveExplicitTypeArgumentsIntention crashes with AssertionError 2015-07-03 15:06:15 +03:00
Nikolay Krasko
7351880a19 Getting decompiled file content through getPsi() doesn't work for local class files
Decompiler view providers are created with EmptyFileManager (see ClassFileDecompiler.decompile()). This makes impossible to create psi file for virtual class file in local file system because parent directory is null in SingleRootFileViewProvider.createFile() pre-check.
2015-07-02 00:58:04 +03:00
Evgeny Gerashchenko
2ef90cff80 KT-7883 Receiver parameter falsely marked as unused
#KT-7883 fixed
2015-07-01 19:52:25 +03:00
Evgeny Gerashchenko
e7d2157429 KT-7651 IllegalArgumentException on attempt to rename class when it has anonymous subclasses
#KT-7651 fixed
 #EA-69049 fixed
2015-07-01 19:52:24 +03:00
Evgeny Gerashchenko
8353a78167 KT-8042 ISE at KotlinHighlightExitPointsHandlerFactory.createHighlightUsagesHandler() on typing a function name starting with throw
#KT-8042 fixed
 #EA-68157 fixed
2015-07-01 19:52:24 +03:00
Nikolay Krasko
23835c7c65 Refactoring: rename file 2015-07-01 15:56:08 +03:00
Nikolay Krasko
ac6e159f4c Create file must return new file, as old one can be invalidated (KT-8266)
Invalidation in SingleRootFileViewProvider.getPsiInner()

 #KT-8266 Fixed
2015-07-01 15:56:06 +03:00
Dmitry Jemerov
72e1202579 correct place for enabling alternative resolve in library configurator
(cherry picked from commit 7bcc3dd)
2015-06-30 14:06:10 +02:00
Dmitry Jemerov
eec2aff821 show Kotlin bytecode by explicit request, rather than always
(cherry picked from commit e441aa0)
2015-06-29 17:20:24 +02:00
Yan Zhulanow
04d81a7c35 Do not bundle annotation collector plugin into IDE plugin 2015-06-23 19:28:41 +03:00
Sergey Mashkov
6e7f6b2bcf JS and IDL2K: make dictionary builder functions public
(cherry picked from commit 0e518e4)
2015-06-22 17:43:56 +03:00
Sergey Mashkov
aada36905c Fix gradle test
(cherry picked from commit bff88b9)
2015-06-17 20:41:38 +03:00
Sergey Mashkov
bb56a2a587 IDL2K better dictionary support: generate interfaces with builder function
suppress inline warning, replace Long with Int
(cherry picked from commit 342f35f)
2015-06-17 16:01:19 +03:00
Sergey Mashkov
0806e947e8 IDL2K better dictionary support: generate interfaces with builder function
(cherry picked from commit 8238883)
2015-06-17 16:01:16 +03:00
Sergey Mashkov
b88b8f5f43 IDL2K introduce required parameters list to avoid possible ambiguous calls
(cherry picked from commit c4d53e1)
2015-06-17 16:01:14 +03:00
Sergey Mashkov
989591043f IDL2K introduce commented declarations list
(cherry picked from commit 20a67c4)
2015-06-17 16:01:12 +03:00
Sergey Mashkov
c38180601a IDL2K restrict readonly attributes to vals
(cherry picked from commit 2cc708c)
2015-06-17 16:01:11 +03:00
Sergey Mashkov
e710fe9b24 IDL2K avoid unnecessary super() calls in secondary constructors
(cherry picked from commit c0c0f61)
2015-06-17 16:01:09 +03:00
Sergey Mashkov
f9750e60f3 IDL2K better results stability
(cherry picked from commit 28f228c)
2015-06-17 16:01:06 +03:00
Sergey Mashkov
3d37154e2c JS generate new stubs with latest IDL2K
(cherry picked from commit 1a5e663)
2015-06-17 16:01:04 +03:00
Sergey Mashkov
38c693d47d IDL2K rework types
Fixes #KT-8015
(cherry picked from commit 68183a7)
2015-06-17 16:01:01 +03:00
Sergey Mashkov
91eeb9c3fd IDL2K support static members
(cherry picked from commit 387291c)
2015-06-17 16:00:59 +03:00
Sergey Mashkov
6e302f6453 IDL2K Multiple constructors (via secondary constructors when needed)
(cherry picked from commit 5000fe8)
2015-06-17 16:00:57 +03:00
Pavel V. Talanov
e129306641 Module(Production/Test)SourceInfo#dependencies() is cached 2015-06-17 15:02:06 +03:00
Pavel V. Talanov
3224df4f7e KotlinQuickDocumentationProvider: fix quick doc for elements from type hierarchy
Fix quick doc for light classes

 #KT-7964 Fixed
2015-06-17 15:01:39 +03:00
Pavel V. Talanov
4375ed28a4 Fix a problem when invoking completion outside of source roots could lead to declarations from index being analyzed in a wrong resolution facade 2015-06-17 15:01:23 +03:00
Pavel V. Talanov
70ae2f319e Fix a problem where a sequence of out-of-block completions could lead to an inconsistent resolve session provided for a synthetic copy of a file 2015-06-17 15:01:05 +03:00
Pavel V. Talanov
8ab09c9bbe Fix folding after changes to parser 2015-06-17 15:00:29 +03:00
Pavel V. Talanov
8ef4b3e6bc Create import list psi element even if no directives are present
Fix a problem where deleting last import directive via "optimize imports" could lead to incorrect psi structure resulting in CCE, see EA-64291
New imports are inserted at the head (after package directive if present) of the file (before any comments) if no imports were present
Add test for inserting import to file where a first statement is a comment
Drop code dealing with non-existing import list in ImportInsertHelperImpl
AbstractQuickFixTest: check for unexpected actions before changes to the file are made as it relies on the first line having specific format
2015-06-17 15:00:15 +03:00
Ilya Gorbunov
c3d96fb58a Temporary Add jvmOverloads to String.indexOf
(cherry picked from commit acff722)
2015-06-17 12:21:55 +03:00
Valentin Kipyatkov
46b8ec7ebb KT-7989 ReplaceWith replacement adds redundant type arguments for platform types
Highlighting of redundant type arguments made more strict about platform types

 #KT-7989 Fixed
(cherry picked from commit 366a2be)
2015-06-16 14:08:49 +03:00
Valentin Kipyatkov
c4ed9861fe KT-7901 Auto import is not suggested
KT-7229 Completion for extension functions with complex capture

 #KT-7901 Fixed
 #KT-7229 Fixed
(cherry picked from commit 4deefce)
2015-06-16 14:04:11 +03:00
Alexander Udalov
1853d79076 Fix binary incompatibility between M12 and M12.1
#KT-8016 Fixed
2015-06-10 20:37:30 +03:00
Mikhail Glukhikh
a8056a67a4 Exception fix: more accurate type annotation parsing #EA-69124 Fixed
(cherry picked from commit a792b29)
2015-06-09 19:44:45 +03:00
Mikhail Glukhikh
64501a2198 Refactoring of AnnotationResolver.resolveAnnotation(s)Arguments
(cherry picked from commit 804bf3a)
2015-06-09 19:44:32 +03:00
Mikhail Glukhikh
d76542fad4 Recursive annotations are now possible for properties / functions / classes / primary constructors #EA-66984 Fixed #EA-63992 Fixed #EA-64272 Fixed
A set of tests provided.
(cherry picked from commit 98407a7)
2015-06-09 19:42:39 +03:00
Mikhail Glukhikh
6c27a1d0b3 Fix for EA-68871 #EA-68871 Fixed
(cherry picked from commit 969993b)
2015-06-09 19:41:06 +03:00
Alexander Udalov
191287fc1e Fix kotlin-reflect Maven artifact, attach sources jar 2015-06-09 16:01:58 +03:00
Alexander Udalov
23786caf32 Minor, specify version for maven-jar-plugin 2015-06-09 16:01:57 +03:00
Pavel V. Talanov
a9663fa2b5 KotlinSignatureInJavaMarkerProvider: do not report errors on exceptions
Fixing it is not in our immediate plans and these exceptions litter our EA and create a bad impression for users, while not really disrupting any workflow
2015-06-08 16:22:02 +03:00
Pavel V. Talanov
1a16e3cdeb Minor: fix test data 2015-06-08 16:21:45 +03:00
Pavel V. Talanov
f939640407 Minor: fix test 2015-06-08 16:21:32 +03:00
Pavel V. Talanov
a6f872a75d Companion objects have public visibility by default
#KT-7114 Fixed
2015-06-08 16:21:17 +03:00
Valentin Kipyatkov
739cb9ff7c KT-7955 "Add replaceWith to specify replacement pattern" intention/inpesction has too large a range
#KT-7955 Fixed
(cherry picked from commit 63b30cf)
2015-06-08 15:43:05 +03:00
Valentin Kipyatkov
d8df392542 Added test
(cherry picked from commit e1efb95)
2015-06-08 15:42:56 +03:00
Nikolay Krasko
940445fd88 Keep NullableNotNullManager methods for J2K converter 2015-06-08 15:24:39 +03:00
Valentin Kipyatkov
c3615b14be KT-6807 J2K: Convert "==" to "===" if class has equals() method
#KT-6807 Fixed
(cherry picked from commit 0cb2348)
2015-06-06 11:03:05 +03:00
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
1293 changed files with 14141 additions and 7765 deletions

View File

@@ -42,7 +42,6 @@
<element id="module-output" name="serialization" />
<element id="module-output" name="idea-completion" />
<element id="module-output" name="idea-core" />
<element id="module-output" name="annotation-collector" />
<element id="module-output" name="idea-js" />
</element>
<element id="library" level="project" name="javax.inject" />

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

@@ -13,7 +13,7 @@
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx900m -XX:MaxPermSize=320m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=64m" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx900m -XX:MaxPermSize=400m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />

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

@@ -183,7 +183,7 @@ public abstract class AnnotationCodegen {
ClassifierDescriptor classifierDescriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor();
assert classifierDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor;
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor);
if (rp == RetentionPolicy.SOURCE) {
if (rp == RetentionPolicy.SOURCE && typeMapper.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES) {
return null;
}

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)) {
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)) {
@@ -789,6 +789,10 @@ public class JetTypeMapper {
return result;
}
public ClassBuilderMode getClassBuilderMode() {
return classBuilderMode;
}
private static boolean isConstructor(@NotNull Method method) {
return "<init>".equals(method.getName());
}

View File

@@ -47,7 +47,7 @@ public class SwitchCodegenUtil {
// ensure that expression is constant
JetExpression patternExpression = ((JetWhenConditionWithExpression) condition).getExpression();
assert patternExpression != null : "expression in when should not be null";
if (patternExpression == null) return false;
CompileTimeConstant constant = ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext);
if (constant == null || !predicate.invoke(constant)) {

View File

@@ -78,6 +78,7 @@ import org.jetbrains.kotlin.parsing.JetScriptDefinitionProvider
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension
import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
import org.jetbrains.kotlin.utils.PathUtil
@@ -141,6 +142,7 @@ public class KotlinCoreEnvironment private(
ExternalDeclarationsProvider.registerExtensionPoint(project)
ExpressionCodegenExtension.registerExtensionPoint(project)
ClassBuilderInterceptorExtension.registerExtensionPoint(project)
AnalysisCompletedHandlerExtension.registerExtensionPoint(project)
for (registrar in configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) {
registrar.registerProjectComponents(project, configuration)

View File

@@ -299,6 +299,8 @@ public class KotlinToJVMBytecodeCompiler {
return null;
}
if (!result.getShouldGenerateCode()) return null;
result.throwIfError();
return generate(environment, result, environment.getSourceFiles(), null, null);

View File

@@ -91,7 +91,9 @@ messages/**)
# for gradle plugin and other server tools
-keep class com.intellij.openapi.util.io.ZipFileCache { public *; }
-keep class com.intellij.openapi.util.LowMemoryWatcher { public *; }
# for j2k
-keep class com.intellij.codeInsight.NullableNotNullManager { public protected *; }
-keepclassmembers enum * {
public static **[] values();

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

@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.context.ModuleContext;
import org.jetbrains.kotlin.context.MutableModuleContext;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.descriptors.ModuleParameters;
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
import org.jetbrains.kotlin.di.InjectorForTopDownAnalyzerForJvm;
@@ -36,10 +37,8 @@ import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.ImportPath;
import org.jetbrains.kotlin.resolve.TopDownAnalysisMode;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension;
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
import java.util.ArrayList;
@@ -148,7 +147,19 @@ public enum TopDownAnalyzerFacadeForJVM {
additionalProviders.add(injector.getJavaDescriptorResolver().getPackageFragmentProvider());
injector.getLazyTopDownAnalyzerForTopLevel().analyzeFiles(topDownAnalysisMode, allFiles, additionalProviders);
return AnalysisResult.success(trace.getBindingContext(), moduleContext.getModule());
BindingContext bindingContext = trace.getBindingContext();
ModuleDescriptor module = moduleContext.getModule();
Collection<AnalysisCompletedHandlerExtension> analysisCompletedHandlerExtensions =
AnalysisCompletedHandlerExtension.Companion.getInstances(moduleContext.getProject());
for (AnalysisCompletedHandlerExtension extension : analysisCompletedHandlerExtensions) {
AnalysisResult result = extension.analysisCompleted(project, module, bindingContext, files);
if (result != null) return result;
}
return AnalysisResult.success(bindingContext, module);
}
finally {
injector.destroy();

View File

@@ -0,0 +1,38 @@
/*
* 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.resolve.jvm.extensions
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.resolve.BindingContext
public interface AnalysisCompletedHandlerExtension {
companion object : ProjectExtensionDescriptor<AnalysisCompletedHandlerExtension>(
"org.jetbrains.kotlin.analyzeCompleteHandlerExtension",
javaClass<AnalysisCompletedHandlerExtension>()
)
public fun analysisCompleted(
project: Project,
module: ModuleDescriptor,
bindingContext: BindingContext,
files: Collection<JetFile>): AnalysisResult?
}

View File

@@ -21,9 +21,10 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.ErrorUtils
import kotlin.platform.platformStatic
public data open class AnalysisResult protected (
public data open class AnalysisResult protected constructor(
public val bindingContext: BindingContext,
public val moduleDescriptor: ModuleDescriptor
public val moduleDescriptor: ModuleDescriptor,
public val shouldGenerateCode: Boolean = true
) {
public val error: Throwable
@@ -43,7 +44,11 @@ public data open class AnalysisResult protected (
public val EMPTY: AnalysisResult = success(BindingContext.EMPTY, ErrorUtils.getErrorModule())
platformStatic public fun success(bindingContext: BindingContext, module: ModuleDescriptor): AnalysisResult {
return AnalysisResult(bindingContext, module)
return AnalysisResult(bindingContext, module, true)
}
platformStatic public fun success(bindingContext: BindingContext, module: ModuleDescriptor, shouldGenerateCode: Boolean): AnalysisResult {
return AnalysisResult(bindingContext, module, shouldGenerateCode)
}
platformStatic public fun error(bindingContext: BindingContext, error: Throwable): AnalysisResult {

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

@@ -149,9 +149,12 @@ public final class WhenChecker {
for (JetWhenEntry entry : expression.getEntries()) {
for (JetWhenCondition condition : entry.getConditions()) {
if (condition instanceof JetWhenConditionWithExpression) {
JetType type = trace.getBindingContext().getType(((JetWhenConditionWithExpression) condition).getExpression());
if (type != null && KotlinBuiltIns.isNothingOrNullableNothing(type)) {
return true;
JetWhenConditionWithExpression conditionWithExpression = (JetWhenConditionWithExpression) condition;
if (conditionWithExpression.getExpression() != null) {
JetType type = trace.getBindingContext().getType(conditionWithExpression.getExpression());
if (type != null && KotlinBuiltIns.isNothingOrNullableNothing(type)) {
return true;
}
}
}
}

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

@@ -86,3 +86,9 @@ object TrailingCommentsBinder : WhitespacesAndCommentsBinder {
return result
}
}
object DoNotBindAnything : WhitespacesAndCommentsBinder {
override fun getEdgePosition(tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter): Int {
return 0
}
}

View File

@@ -215,8 +215,8 @@ public class JetParsing extends AbstractJetParsing {
parseFileAnnotationList(FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED);
packageDirective = mark();
packageDirective.done(PACKAGE_DIRECTIVE);
// this is necessary to allow comments at the start of the file to be bound to the first declaration:
packageDirective.setCustomEdgeTokenBinders(PrecedingCommentsBinder.INSTANCE$, null);
// this is necessary to allow comments at the start of the file to be bound to the first declaration
packageDirective.setCustomEdgeTokenBinders(DoNotBindAnything.INSTANCE$, null);
}
parseImportDirectives();
@@ -351,13 +351,15 @@ public class JetParsing extends AbstractJetParsing {
}
private void parseImportDirectives() {
if (at(IMPORT_KEYWORD)) {
PsiBuilder.Marker importList = mark();
while (at(IMPORT_KEYWORD)) {
parseImportDirective();
}
importList.done(IMPORT_LIST);
PsiBuilder.Marker importList = mark();
if (!at(IMPORT_KEYWORD)) {
// this is necessary to allow comments at the start of the file to be bound to the first declaration
importList.setCustomEdgeTokenBinders(DoNotBindAnything.INSTANCE$, null);
}
while (at(IMPORT_KEYWORD)) {
parseImportDirective();
}
importList.done(IMPORT_LIST);
}
/*
@@ -705,14 +707,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 +760,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 +767,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 +800,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

@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.psi.stubs.impl.KotlinFileStubImpl;
import java.io.IOException;
public class JetFileElementType extends IStubFileElementType<KotlinFileStub> {
public static final int STUB_VERSION = 46;
public static final int STUB_VERSION = 47;
private static final String NAME = "kotlin.FILE";

View File

@@ -105,6 +105,15 @@ public class AnnotationResolver {
return resolveAnnotations(scope, modifierList, trace, true);
}
@NotNull
public Annotations resolveAnnotationsWithoutArguments(
@NotNull JetScope scope,
@NotNull List<JetAnnotationEntry> annotationEntries,
@NotNull BindingTrace trace
) {
return resolveAnnotationEntries(scope, annotationEntries, trace, false);
}
@NotNull
public Annotations resolveAnnotationsWithArguments(
@NotNull JetScope scope,
@@ -144,7 +153,7 @@ public class AnnotationResolver {
descriptor = new LazyAnnotationDescriptor(new LazyAnnotationsContextImpl(this, storageManager, trace, scope), entryElement);
}
if (shouldResolveArguments) {
resolveAnnotationArguments(entryElement, trace);
resolveAnnotationArguments(descriptor);
}
result.add(descriptor);
@@ -202,30 +211,13 @@ public class AnnotationResolver {
);
}
public static void resolveAnnotationsArguments(@Nullable JetModifierList modifierList, @NotNull BindingTrace trace) {
if (modifierList == null) {
return;
}
for (JetAnnotationEntry annotationEntry : modifierList.getAnnotationEntries()) {
resolveAnnotationArguments(annotationEntry, trace);
}
}
public static void resolveAnnotationsArguments(@NotNull Annotations annotations, @NotNull BindingTrace trace) {
public static void resolveAnnotationsArguments(@NotNull Annotations annotations) {
for (AnnotationDescriptor annotationDescriptor : annotations) {
JetAnnotationEntry annotationEntry = trace.getBindingContext().get(ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT, annotationDescriptor);
assert annotationEntry != null : "Cannot find annotation entry: " + annotationDescriptor;
resolveAnnotationArguments(annotationEntry, trace);
resolveAnnotationArguments(annotationDescriptor);
}
}
private static void resolveAnnotationArguments(
@NotNull JetAnnotationEntry annotationEntry,
@NotNull BindingTrace trace
) {
AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText();
private static void resolveAnnotationArguments(@NotNull AnnotationDescriptor annotationDescriptor) {
if (annotationDescriptor instanceof LazyAnnotationDescriptor) {
((LazyAnnotationDescriptor) annotationDescriptor).forceResolveAllContents();
}

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

@@ -159,7 +159,7 @@ public class BodyResolver {
@NotNull final ConstructorDescriptor descriptor,
@NotNull JetScope declaringScope
) {
AnnotationResolver.resolveAnnotationsArguments(constructor.getModifierList(), trace);
AnnotationResolver.resolveAnnotationsArguments(descriptor.getAnnotations());
final CallChecker callChecker = new ConstructorHeaderCallChecker(descriptor, additionalCheckerProvider.getCallChecker());
resolveFunctionBody(c, trace, constructor, descriptor, declaringScope,
@@ -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,17 +501,17 @@ 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();
AnnotationResolver.resolveAnnotationsArguments(klass.getPrimaryConstructorModifierList(), trace);
if (unsubstitutedPrimaryConstructor != null) {
WritableScope parameterScope = getPrimaryConstructorParametersScope(classDescriptor.getScopeForClassHeaderResolution(), unsubstitutedPrimaryConstructor);
valueParameterResolver.resolveValueParameters(klass.getPrimaryConstructorParameters(), unsubstitutedPrimaryConstructor.getValueParameters(),
parameterScope, c.getOuterDataFlowInfo(), trace);
AnnotationResolver.resolveAnnotationsArguments(unsubstitutedPrimaryConstructor.getAnnotations());
WritableScope parameterScope = getPrimaryConstructorParametersScope(classDescriptor.getScopeForClassHeaderResolution(),
unsubstitutedPrimaryConstructor);
valueParameterResolver.resolveValueParameters(klass.getPrimaryConstructorParameters(),
unsubstitutedPrimaryConstructor.getValueParameters(),
parameterScope, c.getOuterDataFlowInfo(), trace);
}
}
}
@@ -559,7 +559,7 @@ public class BodyResolver {
resolvePropertyDelegate(c, property, propertyDescriptor, delegateExpression, classDescriptor.getScopeForMemberDeclarationResolution(), propertyScope);
}
resolveAnnotationArguments(propertyScope, property);
AnnotationResolver.resolveAnnotationsArguments(propertyDescriptor.getAnnotations());
resolvePropertyAccessors(c, property, propertyDescriptor);
processed.add(property);
@@ -587,7 +587,7 @@ public class BodyResolver {
resolvePropertyDelegate(c, property, propertyDescriptor, delegateExpression, propertyScope, propertyScope);
}
resolveAnnotationArguments(propertyScope, property);
AnnotationResolver.resolveAnnotationsArguments(propertyDescriptor.getAnnotations());
resolvePropertyAccessors(c, property, propertyDescriptor);
}
@@ -610,7 +610,7 @@ public class BodyResolver {
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
if (getter != null && getterDescriptor != null) {
JetScope accessorScope = makeScopeForPropertyAccessor(c, getter, propertyDescriptor);
resolveAnnotationArguments(accessorScope, getter);
AnnotationResolver.resolveAnnotationsArguments(getterDescriptor.getAnnotations());
resolveFunctionBody(c, fieldAccessTrackingTrace, getter, getterDescriptor, accessorScope);
}
@@ -618,7 +618,7 @@ public class BodyResolver {
PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
if (setter != null && setterDescriptor != null) {
JetScope accessorScope = makeScopeForPropertyAccessor(c, setter, propertyDescriptor);
resolveAnnotationArguments(accessorScope, setter);
AnnotationResolver.resolveAnnotationsArguments(setterDescriptor.getAnnotations());
resolveFunctionBody(c, fieldAccessTrackingTrace, setter, setterDescriptor, accessorScope);
}
}
@@ -778,10 +778,6 @@ public class BodyResolver {
c.getOuterDataFlowInfo(), trace);
}
private void resolveAnnotationArguments(@NotNull JetScope scope, @NotNull JetModifierListOwner owner) {
AnnotationResolver.resolveAnnotationsArguments(owner.getModifierList(), trace);
}
private static void computeDeferredType(JetType type) {
// handle type inference loop: function or property body contains a reference to itself
// fun f() = { f() }

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

@@ -351,15 +351,6 @@ public class DescriptorResolver {
annotationResolver.resolveAnnotationsWithoutArguments(scope, valueParameter.getModifierList(), trace));
}
@NotNull
public ValueParameterDescriptorImpl resolveValueParameterDescriptorWithAnnotationArguments(
JetScope scope, DeclarationDescriptor declarationDescriptor,
JetParameter valueParameter, int index, JetType type, BindingTrace trace
) {
return resolveValueParameterDescriptor(declarationDescriptor, valueParameter, index, type, trace,
annotationResolver.resolveAnnotationsWithArguments(scope, valueParameter.getModifierList(), trace));
}
@NotNull
private ValueParameterDescriptorImpl resolveValueParameterDescriptor(
DeclarationDescriptor declarationDescriptor,

View File

@@ -88,7 +88,7 @@ class FunctionDescriptorResolver(
): SimpleFunctionDescriptor {
val functionDescriptor = functionConstructor(
containingDescriptor,
annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace),
annotationResolver.resolveAnnotationsWithoutArguments(scope, function.getModifierList(), trace),
function.getNameAsSafeName(),
CallableMemberDescriptor.Kind.DECLARATION,
function.toSourceElement()
@@ -147,6 +147,7 @@ class FunctionDescriptorResolver(
typeResolver.resolveType(innerScope, receiverTypeRef, trace, true)
else
expectedFunctionType.getReceiverType()
receiverType?.let { AnnotationResolver.resolveAnnotationsArguments(it.getAnnotations()) }
val valueParameterDescriptors = createValueParameterDescriptors(function, functionDescriptor, innerScope, trace, expectedFunctionType)
@@ -166,6 +167,9 @@ class FunctionDescriptorResolver(
modality,
visibility
)
for (valueParameterDescriptor in valueParameterDescriptors) {
AnnotationResolver.resolveAnnotationsArguments(valueParameterDescriptor.getType().getAnnotations())
}
}
private fun createValueParameterDescriptors(
@@ -210,7 +214,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
@@ -338,7 +342,7 @@ class FunctionDescriptorResolver(
checkConstructorParameterHasNoModifier(trace, valueParameter)
}
val valueParameterDescriptor = descriptorResolver.resolveValueParameterDescriptorWithAnnotationArguments(parameterScope, functionDescriptor,
val valueParameterDescriptor = descriptorResolver.resolveValueParameterDescriptor(parameterScope, functionDescriptor,
valueParameter, i, type, trace)
parameterScope.addVariableDescriptor(valueParameterDescriptor)
result.add(valueParameterDescriptor)

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

@@ -393,12 +393,10 @@ public class ModifiersChecker {
@NotNull
public static Visibility getDefaultClassVisibility(@NotNull ClassDescriptor descriptor) {
if (isEnumEntry(descriptor)) {
if (isEnumEntry(descriptor) || isCompanionObject(descriptor)) {
// should be be accessible where containing class is accessible by default
return Visibilities.PUBLIC;
}
if (isCompanionObject(descriptor)) {
return ((ClassDescriptor) descriptor.getContainingDeclaration()).getVisibility();
}
return Visibilities.INTERNAL;
}

View File

@@ -104,7 +104,7 @@ public class TypeResolver(
private fun doResolvePossiblyBareType(c: TypeResolutionContext, typeReference: JetTypeReference): PossiblyBareType {
AnnotationResolver.reportDeprecatedAnnotationSyntax(typeReference.getAnnotations(), c.trace);
val annotations = annotationResolver.resolveAnnotationsWithArguments(c.scope, typeReference.getAnnotationEntries(), c.trace)
val annotations = annotationResolver.resolveAnnotationsWithoutArguments(c.scope, typeReference.getAnnotationEntries(), c.trace)
val typeElement = typeReference.getTypeElement()

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

@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.AnnotationResolver;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor;
@@ -143,7 +144,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 +184,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);
}
@@ -210,6 +211,7 @@ public class LazyDeclarationResolver {
throw new IllegalStateException("No descriptor resolved for " + declaration + ":\n" +
PsiUtilPackage.getElementTextWithContext(declaration));
}
AnnotationResolver.resolveAnnotationsArguments(result.getAnnotations());
return result;
}

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

@@ -101,7 +101,6 @@ public abstract class AbstractLazyMemberScope<D : DeclarationDescriptor, DP : De
trace,
c.scopeProvider.getOuterDataFlowInfoForDeclaration(propertyDeclaration))
result.add(propertyDescriptor)
AnnotationResolver.resolveAnnotationsArguments(propertyDescriptor.getAnnotations(), trace)
}
getNonDeclaredProperties(name, result)

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

@@ -136,6 +136,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
VariableDescriptor propertyDescriptor = components.descriptorResolver.
resolveLocalVariableDescriptor(scope, property, context.dataFlowInfo, context.trace);
AnnotationResolver.resolveAnnotationsArguments(propertyDescriptor.getType().getAnnotations());
JetExpression initializer = property.getInitializer();
JetTypeInfo typeInfo;
if (initializer != null) {

View File

@@ -90,6 +90,7 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express
context.trace, context.dataFlowInfo, context.expectedType
)
}
AnnotationResolver.resolveAnnotationsArguments(functionDescriptor.getAnnotations());
val functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace)
components.expressionTypingServices.checkFunctionReturnType(
@@ -165,6 +166,9 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express
components.functionDescriptorResolver.
initializeFunctionDescriptorAndExplicitReturnType(context.scope.getContainingDeclaration(), context.scope, functionLiteral,
functionDescriptor, context.trace, context.expectedType)
for (parameterDescriptor in functionDescriptor.getValueParameters()) {
AnnotationResolver.resolveAnnotationsArguments(parameterDescriptor.getAnnotations())
}
BindingContextUtils.recordFunctionDeclarationToDescriptor(context.trace, functionLiteral, functionDescriptor)
return functionDescriptor
}

View File

@@ -49,7 +49,7 @@ public class ValueParameterResolver(
context: ExpressionTypingContext
) {
for ((descriptor, parameter) in valueParameterDescriptors zip valueParameters) {
AnnotationResolver.resolveAnnotationsArguments(parameter.getModifierList(), context.trace)
AnnotationResolver.resolveAnnotationsArguments(descriptor.getAnnotations())
resolveDefaultValue(descriptor, parameter, context)
}
}

View File

@@ -103,7 +103,7 @@ public class KotlinCodeBlockModificationListener(modificationTracker: PsiModific
return false
}
private fun isInsideCodeBlock(element: PsiElement?): Boolean {
public fun isInsideCodeBlock(element: PsiElement?): Boolean {
if (element is PsiFileSystemItem) return false
if (element == null || element.getParent() == null) return true

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

@@ -8,7 +8,7 @@ internal final class A {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal companion object Companion {
public companion object Companion {
private constructor Companion()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int

View File

@@ -9,7 +9,7 @@ internal final class A {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal companion object Companion : B {
public companion object Companion : B {
private constructor Companion()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int

View File

@@ -14,7 +14,7 @@ internal final class A {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal companion object Companion {
public companion object Companion {
private constructor Companion()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int

View File

@@ -14,7 +14,7 @@ internal final class A {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal companion object Companion {
public companion object Companion {
private constructor Companion()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int

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,3 @@
fun box(): String {
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()
public 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
}
}

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