Compare commits

...

995 Commits

Author SHA1 Message Date
Yan Zhulanow
9a2457ca58 ~ 2018-04-19 23:40:14 +03:00
Yan Zhulanow
aec1f79217 REPL: Prettify javadoc/kdoc output 2018-01-30 20:22:15 +03:00
Yan Zhulanow
63a02f9247 ~ Support reference variants 2018-01-30 20:22:14 +03:00
Yan Zhulanow
f6e9c2507d REPL: Find sources for kotlin-stdlib and JDK automatically 2018-01-30 20:22:13 +03:00
Yan Zhulanow
55a82615c8 REPL: Use idea-core functionality in documentation 2018-01-30 20:22:12 +03:00
Yan Zhulanow
64230721ae Put ide-common to dist/kotlinc 2018-01-30 20:22:11 +03:00
Yan Zhulanow
72fd50cd69 Refactoring: Extract base functionality of ResolutionFacade to ResolutionFacadeBase 2018-01-30 20:22:11 +03:00
Yan Zhulanow
eefe6cdfbc REPL: Show documentation for external libraries (if sources JAR is present in classpath) 2018-01-30 20:22:10 +03:00
Yan Zhulanow
a92b58d7ea REPL: Add ':doc' comment (for now only for REPL declarations) 2018-01-30 20:22:09 +03:00
Yan Zhulanow
1c7169e6b8 REPL, Minor: Rename ':dump bytecode' to ':classes' 2018-01-30 20:22:08 +03:00
Yan Zhulanow
8017da80da REPL, Minor: Refactor help message 2018-01-30 20:22:07 +03:00
Yan Zhulanow
2914b11097 REPL: Use single classloader in all REPL places 2018-01-30 20:22:06 +03:00
Yan Zhulanow
95ea14feb1 REPL: Reuse classloader between snippets 2018-01-30 20:22:06 +03:00
Yan Zhulanow
079360a4fe REPL: Ignore empty lines (KT-21611) 2018-01-30 20:22:05 +03:00
Yan Zhulanow
047b222240 REPL: Forbid 'this' in REPL lines (KT-14851, KT-12569) 2018-01-30 20:22:04 +03:00
Yan Zhulanow
e772054a37 REPL: Get rid of passing all previous line classses via constructor parameters 2018-01-30 20:22:03 +03:00
Yan Zhulanow
8c6ea5135b J2K: Script Codegen (step 2) 2018-01-30 20:22:02 +03:00
Yan Zhulanow
6075927624 J2K: Script Codegen (step 1) 2018-01-30 20:22:02 +03:00
Yan Zhulanow
ba526c91c9 REPL, Refactoring: Small code style fixes 2018-01-30 20:22:01 +03:00
Yan Zhulanow
1e2de8b113 REPL, Refactoring: A number of trivial renames/moves 2018-01-30 20:22:00 +03:00
Yan Zhulanow
648f9aae52 REPL, Refactoring, Minor: Lower property visibility 2018-01-30 20:21:59 +03:00
Yan Zhulanow
a1d68f4a79 REPL, Refactoring: Get rid of nasty enum-like String literals 2018-01-30 20:21:58 +03:00
Yan Zhulanow
08590c676c REPL, Refactoring: Make ReplFromTerminal and ReplInterpreter not to implement ReplConfiguration 2018-01-30 20:21:58 +03:00
Yan Zhulanow
668570e6b0 REPL, Refactoring: Replace strange callback function with an execution interceptor 2018-01-30 20:21:57 +03:00
Yan Zhulanow
0205c7d153 Minor: Delete an unused class 2018-01-30 20:21:56 +03:00
Yan Zhulanow
8351567f46 Minor: Add "repl" to dictionary 2018-01-30 20:21:55 +03:00
Yan Zhulanow
c5137be433 REPL, Refactoring: Rename ReplErrorLogger to ReplExceptionReporter
Also rethrow exceptions explicitly.
2018-01-30 20:21:54 +03:00
Yan Zhulanow
0238575a36 REPL: Fix crash on trying to :load with incorrect filename (KT-12037) 2018-01-30 20:21:54 +03:00
Mikhail Glukhikh
6fbf5a8904 Reverts commit 2472966
(Remove unused function parameter: minor improvement)
Transformation was not equivalent due to change signature in between
This revert fixes broken quick-fix tests (remove parameter based)
2018-01-30 18:43:25 +03:00
Vyacheslav Gerasimov
d0b232c172 Update readme part about dependencies 2018-01-30 17:06:18 +03:00
Vyacheslav Gerasimov
68b5dc756c Remove intellij-core from testRuntime if full idea is already there
Looks like it makes tests flacky
2018-01-30 17:06:18 +03:00
Vyacheslav Gerasimov
29caa00f23 Add asm-all to jps-plugin dependencies 2018-01-30 17:06:18 +03:00
Vyacheslav Gerasimov
bc86f40fd8 Update kotlinx-coroutines version to 0.20 2018-01-30 17:06:18 +03:00
Vyacheslav Gerasimov
89a07ded1c Extract versions and remove unnecessary '.jar' extensions 2018-01-30 17:06:18 +03:00
Vyacheslav Gerasimov
3e34b95610 Use KotlinTestUtils.findAndroidSdk() in BuildCacheRelocationIT 2018-01-30 17:06:18 +03:00
Vyacheslav Gerasimov
052be93c97 Add some logging to intellij-sdk build script 2018-01-30 17:06:17 +03:00
Vyacheslav Gerasimov
558a2cb8a8 Explicit intellijUltimateEnabled should override teamcity build 2018-01-30 17:06:17 +03:00
Vyacheslav Gerasimov
3d1e0c3b39 Add dependency versions for 171, 181, AS 2018-01-30 17:06:17 +03:00
Vyacheslav Gerasimov
ca6889b4c6 Fix build script for kotlin-gradle-subplugin-example 2018-01-30 17:06:17 +03:00
Vyacheslav Gerasimov
07b191f460 Update dependency versions after migration to 173 2018-01-30 17:06:17 +03:00
Ilya Chernikov
8ab121b373 Exclude new dependencies locations from CodeConformanceTest 2018-01-30 17:06:17 +03:00
Ilya Chernikov
555e9674b2 Fix dependencies to the cross-project tasks 2018-01-30 17:06:17 +03:00
Ilya Chernikov
434bbafe58 Implement runners without intellij plugin, share common part 2018-01-30 17:06:16 +03:00
Ilya Chernikov
0a95e7b20f Fix dependencies and artifacts contents after review 2018-01-30 17:06:16 +03:00
Ilya Chernikov
058ef31d7a Fixes after review 2018-01-30 17:06:16 +03:00
Ilya Chernikov
14e586d5a5 Refactor android sdk preparation project after review 2018-01-30 17:06:16 +03:00
Dmitry Jemerov
e83845ea72 Build changes to support Android Studio 2018-01-30 17:06:16 +03:00
Dmitry Jemerov
b2ca302bf7 Support downloading Android Studio 2018-01-30 17:06:16 +03:00
Dmitry Jemerov
f4feb71ad2 Extract repeated versions to a single location 2018-01-30 17:06:16 +03:00
Dmitry Jemerov
df17f20ec7 Fix project sync when intelliUltimateEnabled is not set 2018-01-30 17:06:16 +03:00
Dmitry Jemerov
a58a6290cc Fix typo 2018-01-30 17:06:15 +03:00
Ilya Chernikov
5dc094d290 Implement correct and fast ultimate/community sdks handling 2018-01-30 17:06:15 +03:00
Ilya Chernikov
6f1e6f1f1b Fix tests after rebasing and messing with the dependencies 2018-01-30 17:06:15 +03:00
Ilya Chernikov
246f73c879 Cleanup unused ant-related bits and script constants 2018-01-30 17:06:15 +03:00
Ilya Chernikov
0c35e79283 Fix idea home path usages 2018-01-30 17:06:15 +03:00
Ilya Chernikov
2dc4769c0a Fixes after rebase 2018-01-30 17:06:15 +03:00
Ilya Chernikov
172a29ba04 Implement NodeJS plugin downloading 2018-01-30 17:06:15 +03:00
Ilya Chernikov
48cbcbc496 Switch jsr305 usages to the maven version
since it is not available in the intellij ultimate SDK
2018-01-30 17:06:14 +03:00
Ilya Chernikov
acc84d2524 Rollback incorrect tests fix 2018-01-30 17:06:14 +03:00
Ilya Chernikov
7218bd536c Implement single idea sdk scheme, some refactoring 2018-01-30 17:06:14 +03:00
Ilya Chernikov
5f7c783bb2 Stop using com.intellij.openapi.components.service functions:
they are getting obfuscated in the ultimate SDK, which prevents us
from using ultimate sdk for all modules.
Could probably be rolled back after fixing KT-18563
2018-01-30 17:06:14 +03:00
Ilya Chernikov
d38b1c361a Add ultimate sdk 2018-01-30 17:06:14 +03:00
Ilya Chernikov
1219572aa0 Extract intellij params to buildSrc's build script 2018-01-30 17:06:14 +03:00
Ilya Chernikov
05f0978865 Fix after review 2018-01-30 17:06:14 +03:00
Ilya Chernikov
fbbece3c86 Fix publishing problem 2018-01-30 17:06:13 +03:00
Ilya Chernikov
7e21573cf4 Convert the rest of the project to intellij repo prepared in buildSrc 2018-01-30 17:06:13 +03:00
Ilya Chernikov
e23b1529b3 Convert intellij usages in the groovy build scripts 2018-01-30 17:06:13 +03:00
Ilya Chernikov
4eb557724c Convert compiler projects to the new intellij deps 2018-01-30 17:06:13 +03:00
Ilya Chernikov
a418a3ac49 Renaming for easier conversion, some more manual conversion 2018-01-30 17:06:13 +03:00
Ilya Chernikov
6f21c36d68 Switch first project to the new custom dependencies schema 2018-01-30 17:06:13 +03:00
Ilya Chernikov
47507ad694 Switch all usages of dx.jar to the new mechanism, cleanup and refactoring 2018-01-30 17:06:13 +03:00
Ilya Chernikov
eabbebd458 Prepare intellij sdk deps in buildSrc 2018-01-30 17:06:13 +03:00
Yan Zhulanow
59c8f33450 Fix jps android test 2018-01-30 17:06:12 +03:00
Ilya Chernikov
46be5e25be Rewrite android sdk dependencies to avoid config-time tasks execution 2018-01-30 17:06:12 +03:00
Ilya Chernikov
febab82c7e Switch jps android test to platform 26 2018-01-30 17:06:12 +03:00
Ilya Chernikov
7120fe190a Fix overrides of the findViewById in android tests for platform 26 2018-01-30 17:06:12 +03:00
Ilya Chernikov
587f76251e Fix os-specific downloads in android sdk 2018-01-30 17:06:12 +03:00
Ilya Chernikov
e8494a5371 Fix uast-kotlin dependencies and tests 2018-01-30 17:06:12 +03:00
Ilya Chernikov
a6f8db5d02 Fix script-util tests 2018-01-30 17:06:12 +03:00
Ilya Gorbunov
7710cc455c Refactor helper tasks for TeamCity builds
Invoke them properly from TeamCityBuild.xml acting as a temporary adapter.
Remove obsolete tasks from TeamCityBuild.xml.

Patch plugin version with regex replacement in plugin.xml.
2018-01-30 17:06:12 +03:00
Ilya Chernikov
b5db681e06 Switch tests to android sdk 26 2018-01-30 17:06:11 +03:00
Ilya Chernikov
c153a386ab Fix tests 2018-01-30 17:06:11 +03:00
Ilya Chernikov
a4f28cd94f Make all dependencies to idea sdk intransitive 2018-01-30 17:06:11 +03:00
Ilya Chernikov
e76cd802d8 Fix jps tests 2018-01-30 17:06:11 +03:00
Ilya Chernikov
b2926a9322 Add classpath printing tasks to all relevant projects 2018-01-30 17:06:11 +03:00
Ilya Chernikov
0b63e11ea8 Replace android sdk dependencies with custom project build, cleanup update_dependencies.xml 2018-01-30 17:06:11 +03:00
Ilya Chernikov
98204aa2d3 Move jflex download out from update_dependencies, add lexer (ant) tasks to frontend project 2018-01-30 17:06:11 +03:00
Ilya Chernikov
90e5558704 Re-add node.js tests, switch to direct usage of node_utils.xml, remove node parts from update_dependencies.xml 2018-01-30 17:06:10 +03:00
Ilya Chernikov
7f86fb9343 Switch to idea NodeJS plugin usage via intellij gradle plugin 2018-01-30 17:06:10 +03:00
Ilya Chernikov
69787bd0d1 Switch spring usages to regular dependency 2018-01-30 17:06:10 +03:00
Ilya Chernikov
d301938d23 Rewrite TeamCityBuild.xml tasks in gradle, finally drop build.xml files
also:
  proxying previous tasks from TeamCityBuild.xml to gradle,
  cleaning update_dependencies.xml from ant dependencies
2018-01-30 17:06:10 +03:00
Ilya Chernikov
12f0f019da Switch robolectric usages to regular dependency 2018-01-30 17:06:10 +03:00
Ilya Chernikov
361d8536ac Switch ant usages to regular dependency 2018-01-30 17:06:10 +03:00
Ilya Chernikov
486c3a2aff Do not depende on the ideaSdk location in integration tests
assume that tests are always run from the project's root
2018-01-30 17:06:10 +03:00
Ilya Chernikov
f96153693e Make tools.jar search non-throwing 2018-01-30 17:06:09 +03:00
Ilya Chernikov
80ad969f7b Switch markdown usages to regular (teamcity) dependency 2018-01-30 17:06:09 +03:00
Ilya Chernikov
78d2c655d5 Switch native-platform usages to regular dependency 2018-01-30 17:06:09 +03:00
Ilya Chernikov
4a47fb3ffb Switch protobuf usages to regular dependency 2018-01-30 17:06:09 +03:00
Ilya Chernikov
a952d797f1 Switch org.json:json usages to regular dependency 2018-01-30 17:06:09 +03:00
Ilya Chernikov
8f96157d7f Switch kotlinx-coroutines usages to regular dependency 2018-01-30 17:06:09 +03:00
Ilya Chernikov
8bc95295eb Drop other references to ideaSdk 2018-01-30 17:06:09 +03:00
Ilya Chernikov
9766508512 Drop drop lib folder and all (arguably obsolete) dependent usages 2018-01-30 17:06:09 +03:00
Ilya Chernikov
713fb9a0e7 Drop ideaSdk downloading in update_dependencies 2018-01-30 17:06:08 +03:00
Ilya Chernikov
b490a79d95 Replace direct usages of ideaSdk in tests with property passed from build scripts 2018-01-30 17:06:08 +03:00
Ilya Chernikov
eb8ef6e803 Drop unused sources 2018-01-30 17:06:08 +03:00
Ilya Chernikov
d39d2883e2 Ignore local data dir in idea and git 2018-01-30 17:06:08 +03:00
Ilya Chernikov
26369c3cca Cleanup obsolete ideaSdk helpers 2018-01-30 17:06:08 +03:00
Ilya Chernikov
28689f631c Convert instrumentation 2018-01-30 17:06:08 +03:00
Ilya Chernikov
10732a1bdd Convert ultimate runner to intellij plugin 2018-01-30 17:06:08 +03:00
Ilya Chernikov
5d3579c079 Convert idea ultimate module to intellij plugin 2018-01-30 17:06:08 +03:00
Ilya Chernikov
f0edb602da Convert ide-runner to intellij plugin 2018-01-30 17:06:07 +03:00
Ilya Chernikov
556287f9bb Move idea plugin artifacts one dir deeper to simplify runIde task
Running idea via specifying plugins dir (instead of plugin.path property
allow idea to select proper plugin version without a need to remove a bundled
plugin. But in order to make it work, the regular and ultimate plugins
should have separate parent dirs.
2018-01-30 17:06:07 +03:00
Ilya Chernikov
06c8cbf7d6 Convert all remaining plugin modules to intellij plugin 2018-01-30 17:06:07 +03:00
Ilya Chernikov
9b51a547d8 Convert generators to intellij plugin, clean up dependencies 2018-01-30 17:06:07 +03:00
Ilya Chernikov
0d264793ce Convert idea plugin modules to intellij plugin 2018-01-30 17:06:07 +03:00
Ilya Chernikov
3912025e14 Convert jps module to intellij plugin 2018-01-30 17:06:07 +03:00
Ilya Chernikov
8266777bd5 Convert js modules to intellij plugin 2018-01-30 17:06:07 +03:00
Ilya Chernikov
74411d9b9c Convert all compiler modules to intellij plugin 2018-01-30 17:06:06 +03:00
Ilya Chernikov
6614695616 Convert more projects 2018-01-30 17:06:06 +03:00
Ilya Chernikov
743f599262 Add infrastructure and helpers for using intellij plugin, convert first project 2018-01-30 17:06:06 +03:00
Mikhail Glukhikh
a0d0bc074b Cleanup: KotlinPullUpHelper 2018-01-30 16:32:20 +03:00
Mikhail Glukhikh
cefa17f877 Reformat: KotlinPullUpHelper 2018-01-30 16:30:08 +03:00
Mikhail Glukhikh
d88b5746c7 Delete companion manually during pull up 2018-01-30 16:29:22 +03:00
Mikhail Glukhikh
7c6a217579 Reformat: KotlinInlineCallableProcessor 2018-01-30 16:03:14 +03:00
Mikhail Glukhikh
6181ba47c8 Delete companion manually during callable inlining 2018-01-30 16:02:32 +03:00
Mikhail Glukhikh
9b1f323118 Retain empty companion in KtNamedDeclarationStub.remove 2018-01-30 15:41:38 +03:00
Mikhail Glukhikh
5abb9dd23e Create actual fix: handle companions correctly #KT-21114 Fixed 2018-01-30 15:41:37 +03:00
Mikhail Glukhikh
f46fa263ef Fix two psi checker tests (related to annotation diagnostic / parsing) 2018-01-30 15:41:06 +03:00
Mikhail Glukhikh
86f25bff63 KtVisitor: delegate constructors to KtNamedDeclaration
In particular, enables back "Unused symbol" on constructors
2018-01-30 15:24:39 +03:00
Mikhail Glukhikh
460688526d Fix testAnnotationInterface3 in J2K (error message) 2018-01-30 15:23:41 +03:00
Mikhail Glukhikh
899da99232 Fix testAnnotation in "member visibility can be private" 2018-01-30 14:59:47 +03:00
Dmitry Savvinov
404122654f Advance bootstrap version to 1.2.30-dev-672 2018-01-30 13:32:07 +03:00
Mikhail Zarechenskiy
c80beea6fd [NI] Refactoring: extract method to create resolution result out 2018-01-30 13:01:21 +03:00
Mikhail Zarechenskiy
0e31162df4 [NI] Fix substitution for receiver when resolving constructor super call 2018-01-30 13:00:44 +03:00
Mikhail Zarechenskiy
2a0bb68e1c [NI] Fix substitution of NotNullTypeParameter 2018-01-30 13:00:43 +03:00
Mikhail Zarechenskiy
4cd07f59a0 [NI] Don't fail on captured type that contains type variable 2018-01-30 13:00:42 +03:00
Mikhail Zarechenskiy
145c04e7e2 [NI] Fix substitution of incorporation constraint type 2018-01-30 13:00:40 +03:00
Mikhail Glukhikh
725704e70f ExclExclCallFixes: reformat 2018-01-30 11:23:18 +03:00
Mikhail Glukhikh
2472966749 Remove unused function parameter: minor improvement 2018-01-30 11:23:18 +03:00
Mikhail Glukhikh
1298ef7fed Redundant Unit expression: simplify code a bit 2018-01-30 11:18:01 +03:00
Mikhail Glukhikh
cd9e298e53 getParentOfTypesAndPredicate: Class<T> -> Class<out T> 2018-01-30 11:17:27 +03:00
Toshiaki Kameyama
18de0f75ab Redundant Unit inspection: fix false positive for single expression
So #KT-22097 Fixed
2018-01-30 10:03:36 +03:00
Mikhail Glukhikh
30acc224ec Reformat: redundant setter 2018-01-30 10:00:02 +03:00
Toshiaki Kameyama
69f3f04fe4 Correct report of "redundant setter" for override & empty block cases
So #KT-22364 Fixed
2018-01-30 09:59:55 +03:00
Alexander Udalov
0ad3872d1b Remove unneeded constructor parameters in CallCheckerContext 2018-01-29 19:38:03 +01:00
Dmitry Savvinov
1171fdb14d Add draft of changelog for 1.2.30 2018-01-29 19:50:04 +03:00
Dmitry Savvinov
a39aba4269 Revert "Add changelog for 1.2.30"
This reverts commit 4b70654c7e.
2018-01-29 19:45:08 +03:00
Dmitry Savvinov
4b70654c7e Add changelog for 1.2.30 2018-01-29 19:42:26 +03:00
Toshiaki Kameyama
28123eaf7b Add intention for changing setter accessibility #KT-22409 Fixed 2018-01-29 19:09:19 +03:00
Alexey Sedunov
7f97d58970 Type Hierarchy: Do not use JVM class mapping in non-JVM modules
#KT-21424 In Progress
2018-01-29 18:56:29 +03:00
Alexey Sedunov
089b34a8a9 Minor: Regenerate tests 2018-01-29 18:56:28 +03:00
Mikhail Glukhikh
1f8e2a1057 Reformat: unfold return to ... 2018-01-29 18:01:10 +03:00
Toshiaki Kameyama
3a81be6cfb Do not insert returns before Nothing in "Replace return with 'if'"
So #KT-22159 Fixed
2018-01-29 17:56:26 +03:00
Mikhail Glukhikh
f28bec0db1 Reformat: if-then utilities 2018-01-29 17:49:34 +03:00
Mikhail Glukhikh
3b8f5bce41 Reformat: "if then to safe access" inspection 2018-01-29 17:44:19 +03:00
Toshiaki Kameyama
fad7818bf0 Fix "if to safe access" false positive for check on incorrect type
So #KT-21881 Fixed
2018-01-29 17:43:01 +03:00
Mikhail Glukhikh
5798595206 Cleanup: IntentionDescriptionTest 2018-01-29 16:28:45 +03:00
kenji tomita
a28bc830f5 Add Intention for single character substring #KT-22171 Fixed 2018-01-29 16:23:01 +03:00
Mikhail Glukhikh
29eb594309 Inspection to replace Java Collections methods: simplify type check
Related to KT-22038
2018-01-29 15:52:45 +03:00
Mikhail Glukhikh
068f520c01 Inspection to replace Java Collections methods: fix formatting 2018-01-29 15:52:45 +03:00
Toshiaki Kameyama
be4739e65e Inspection to replace Java Collections methods: extend set of types
So #KT-22038 Fixed
2018-01-29 15:52:44 +03:00
Alexey Sedunov
bd8a4d78fa Line Markers: Don't show test run line markers for top-level functions
#KT-13509 Fixed
2018-01-29 14:48:41 +03:00
Mikhail Glukhikh
8cbf364457 Remove braces: add parentheses to if-else in more general case
Related to KT-18308
2018-01-29 14:32:36 +03:00
Toshiaki Kameyama
44c15d8311 Remove braces: add parentheses to if-else inside expression
So #KT-18308 Fixed
2018-01-29 14:32:36 +03:00
Alexander Udalov
19e38bbc72 Do not run annotation checkers for every non-annotated element 2018-01-29 12:22:41 +01:00
Alexander Udalov
46b8deedf7 Run classifier usage checkers on constructor calls
In some cases, REFERENCE_TARGET for annotation entries is the annotation
class descriptor, and in others -- the constructor of that class
2018-01-29 12:22:41 +01:00
Alexander Udalov
8cd7686535 Introduce DeclarationCheckerContext, remove SimpleDeclarationChecker 2018-01-29 12:22:40 +01:00
Alexander Udalov
4cb5483c13 Introduce CheckerContext and ClassifierUsageCheckerContext
To reduce the number of parameters in classifier usage checker
implementations, and to unify the API with call checkers
2018-01-29 12:20:36 +01:00
Alexander Udalov
e2def0c60e Do not report "invalid type of annotation member" on error types
In case the referred type is actually an enum that is not found in
dependencies due to a configuration problem, this usage could be valid.
So we can avoid reporting an error here, to reduce the number of
diagnostics.

Also do not report "default value of annotation parameter must be a
compile-time constant" in the same case for the same reason
2018-01-29 12:20:36 +01:00
Natalia Selezneva
c251386fc3 Rearrange script templates in GradleScriptTemplateProvider
#KT-22473 Fixed
2018-01-29 11:16:29 +03:00
Alexey Sedunov
b091500adc Rename: Wrap facade class when renaming file
This prevents assertion error (introduced in IDEA 181)
caused by facade light class invalidation
and fixes failing test
2018-01-29 01:34:48 +03:00
Alexey Sedunov
80643c5603 Rename: Fix processing of functions without light methods
#KT-22461 Fixed
2018-01-29 01:34:48 +03:00
Alexander Udalov
245d1de2a2 Remove runtime dependency on projectDist(":kotlin-compiler")
This dependency makes IDEA reindex kotlin-compiler.jar after every
Gradle build, which takes time and breaks some key IDE features
2018-01-28 10:14:24 +01:00
Dmitry Savvinov
4d951de616 Propagate nullability changes to enhancement for JSR-305 types
Fix TypeUtils.makeNullableAsSpecified for SimpleTypeWithEnhancement and
FlexibleTypeWithEnhancement: change nullability of enhancement too. This
fixes several false-positive warnings, like in KT-20855 and KT-20466.

Note that it removes warning in some cases (see testdata change for
uselessElvisRightIsNull.kt). However, this removes warning about
*unnecessary* elvis, i.e. this fixed introduces weak false-negatives, which
is acceptable for the moment.

#KT-20855 Fixed Target versions 1.2.30
#KT-20466 Fixed Target versions 1.2.30
#KT-21238 Fixed Target versions 1.2.30
2018-01-26 12:49:14 +03:00
Nikolay Krasko
4c76dc7287 Forbid modification for KtLambdaExpression in JavaCodeBlockModificationListener
See IDEA-185462 for details
2018-01-26 12:42:17 +03:00
Nikolay Krasko
4d2061d836 Minor: reformat coverage 2018-01-26 12:42:17 +03:00
Nikolay Krasko
6d7c779df2 Better diagnostic for file absence in updateJar (KT-22272)
#EA-96117 Fixed
 #KT-22272 Fixed
2018-01-26 12:42:16 +03:00
Toshiaki Kameyama
7e417272b2 "Join lines" works incorrectly in case of line containing more than one string literal (KT-22374)
#KT-22374 Fixed
2018-01-26 12:42:16 +03:00
Mikhael Bogdanov
cc346aef64 Support @JvmStatic for interface companion objects in backend 2018-01-26 10:09:21 +01:00
Mikhael Bogdanov
8bfd6d7404 Support JVM_TARGET in diagnostic tests 2018-01-26 10:09:20 +01:00
Mikhael Bogdanov
c4da370b0b Allow to use @JvmStatic in interface companion object 2018-01-26 10:09:20 +01:00
Mikhael Bogdanov
2340756b88 Minor. Reformat 2018-01-26 10:09:20 +01:00
Dmitry Savvinov
253cd3871b Support effect system-related args in platform 2018-01-26 11:30:44 +03:00
Dmitry Savvinov
b29a6e48fb Refactor language features, which control effect system
- Introduce new language feature 'ReadDeserializedContracts', which
allows to deserialize contracts from metadata.

- Introduce new language feature 'AllowContractsForCustomFunctions',
which allows reading contracts from sources.

- Use new features instead of combination 'CallsInPlaceEffect ||
ReturnsEffect'

- Rename 'CallsInPlaceEffect' -> 'UseCallsInPlaceEffect',
'ReturnsEffect' -> 'UseReturnsEffect'. As names suggest, they control
if it is allowed to use corresponding effect in analysis.

We have to introduce separate 'ReadDeserializedContracts' to enable
contracts only in some modules of the project, because libraries are
read with project-wide settings (see KT-20692).
2018-01-26 11:30:44 +03:00
Dmitry Savvinov
78850087be Revert reformatting for OperationsMapGenerated.kt 2018-01-26 11:00:28 +03:00
Dmitry Petrov
5e34f290ce Reified 'as?' produces nullable result
Previously, this was treated as a regular CHECKCAST, causing KT-22410.

 #Fixed KT-22410 Target versions 1.2.30
2018-01-26 10:22:59 +03:00
Dmitry Petrov
bd25bf14df Minor: reformat code in org.jetbrains.kotlin.codegen.optimization 2018-01-26 10:18:17 +03:00
Yan Zhulanow
e12deb54d6 Android Extensions: Fix "Inconsistent file tree" exception on Activity creation (KT-22349) 2018-01-25 22:03:30 +03:00
Yan Zhulanow
7b055c2172 Kapt: Prefer non-aliased imports over aliased. Make sure the imported short names are unique (KT-22083) 2018-01-25 22:03:29 +03:00
Ilya Gorbunov
233376eef0 Improve min/max specialization for longs and 3-arg overloads in JS 2018-01-25 21:41:18 +03:00
Ilya Gorbunov
2da9f12bc5 Inline findAnyOf(chars) into indexOfAny/lastIndexOfAny
This helps to reduce allocation count

#KT-22042
2018-01-25 21:37:22 +03:00
Cuihtlauac ALVARADO
923d9f03fc Update test results
Separated issue reported: KT-22522

#KT-22369 Fixed
2018-01-25 21:15:08 +03:00
Denis Zharkov
31e73e90d6 Explicitly state that PluginDeclarationProviderFactory is source-only
Before this change `filesScope` was effectively empty in cases when
module info is a library, thus looking
into PackageIndexUtil.packageExists(name, indexedFilesScope, project)
was kind of redundant since it always returns false for empty scopes

The initial motivation was run by 1716720604
that made PackageIndexUtil::packageExists calls much more frequent
2018-01-25 14:41:28 +03:00
Denis Zharkov
2224f95294 Minor. Avoid wrapping GlobalSearchScope.EMPTY_SCOPE 2018-01-25 14:41:28 +03:00
Denis Zharkov
4d378912bf Minor. Reformat JVM/JS analyzer facades 2018-01-25 14:41:28 +03:00
Toshiaki Kameyama
4232ad8dfe "Join lines" works incorrectly in case of line with more than one string literal (KT-22374)
#KT-22374 Fixed
2018-01-24 20:09:32 +03:00
Toshiaki Kameyama
c06aaf6128 Some Live Templates should probably be enabled also for "expressions" not only "statements" (KT-19194)
Consider if-then, if-else, do-while, while positions without block as
statement position.

 #KT-19194 Fixed
2018-01-24 20:09:32 +03:00
Alexander Udalov
543db380d2 Use isJvmInterface in JVM back-end instead of isInterface
To support const vals and proper initialization order for companions of
annotations (since 1.3+) as well as interfaces

 #KT-16962 Fixed
2018-01-24 15:54:35 +01:00
Alexander Udalov
a46a2b9b1c Support nested classes in annotation classes
#KT-16962 In Progress
2018-01-24 15:54:35 +01:00
Alexey Sedunov
5947b4eb8e Minor: Fix Maven server url 2018-01-24 17:52:41 +03:00
Alexey Sedunov
c96eb8df85 Minor: Fix test data for ConvertFunctionTypeParameterToReceiverIntention 2018-01-24 17:28:34 +03:00
Sergey Igushkin
a59fd3bc85 Remove the usage of repository.jetbrains.com 2018-01-24 17:12:45 +03:00
Ilya Gorbunov
32b68ae1d5 Rearrange platform specialized functions
Place them according to their operation to ArrayOps and Filtering.
2018-01-24 02:10:05 +03:00
Ilya Gorbunov
eda8bbacb3 Remove obsolete JvmVersion annotation from generated functions
These functions are already generated in jvm-only file
2018-01-24 02:10:01 +03:00
Sergey Igushkin
20c4775da0 Remove repository.jetbrains.com mirror of Maven Central in libraries. 2018-01-23 23:41:39 +03:00
Sergey Igushkin
0c78a2c026 Remove some of the remaining mentions of repository.jetbrains.com 2018-01-23 23:35:50 +03:00
Alexander Udalov
f516667640 Exclude META-INF/services from kotlin-reflect-sources.jar 2018-01-23 17:11:20 +01:00
Alexander Udalov
3bf5f44b9d Exclude .proto files from kotlin-reflect.jar
#KT-22459 Fixed
2018-01-23 17:11:09 +01:00
Vyacheslav Gerasimov
399282234e Add changelog for 1.2.21 2018-01-23 17:47:17 +03:00
Ilya Gorbunov
6b9520ec73 KT-16661 Simplify String.split a bit more
Check that limit is reached only once in a loop, move nextIndex check to the end of loop.
2018-01-23 13:29:35 +03:00
Vsevolod
510e17246f KT-16661 Simplify Strings#split
Do not search for next occurrence if limit is reached.
2018-01-23 13:29:29 +03:00
Vsevolod
2805371bdc KT-16661 Provide fast-path for Strings#split with single delimiter
Optimize single delimiter split when no matches is found:
Return listOf() of single element instead of adding 'this' to result
because underlying array in ArrayList is created lazily and
by default its size is 16.

Pre-size resulting list in split when limit is known.
2018-01-23 13:29:05 +03:00
Dmitry Petrov
72ffbb9825 Add test for array modification within for-in-array-withIndex loop body 2018-01-23 10:55:24 +03:00
Dmitry Petrov
40d1925e19 Provide optimized code generation for for-in-withIndex for sequences
#KT-5177 In Progress
2018-01-23 10:55:24 +03:00
Dmitry Petrov
2399a39414 Provide optimized code generation for for-in-withIndex for CharSequences
#KT-5177 In Progress
2018-01-23 10:55:24 +03:00
Dmitry Petrov
9c9e507172 Provide optimized code generation for for-in-withIndex for iterables
#KT-5177 In Progress
2018-01-23 10:55:24 +03:00
Dmitry Petrov
08622b0953 Provide optimized code generation for for-in-withIndex for arrays
#KT-5177 In Progress
2018-01-23 10:55:24 +03:00
Dmitry Petrov
e07e9c0ea5 Refactor RangeCodegenUtil: introduce isTopLevelExtensionOnType 2018-01-23 10:55:24 +03:00
Dmitry Petrov
fb487b31ba Minor: format code in RangeCodegenUtil 2018-01-23 10:55:24 +03:00
Dmitry Petrov
5c1321a29f Minor: format code in org.jetbrains.kotlin.codegen.range 2018-01-23 10:55:24 +03:00
Alexey Tsvetkov
f77586574f Always sort files in K2JSCompiler
Previously files were sorted only when IncrementalDataProvider
was not null to normalize js output in case of incremental compilation.
Because of that an output js file could be different after rebuild
in IC tests.
The issue could be reproduced anywhere, but the tests failed only on
Windows, and it seems tests were not run on Windows for some time.
2018-01-22 18:34:17 +03:00
Alexey Tsvetkov
21f2b68357 Fix BuildLogParserParametrizedTest on Windows: normalize line separators 2018-01-22 18:34:17 +03:00
Alexey Tsvetkov
6fc5c3325c Minor: rename file to match class name 2018-01-22 18:34:17 +03:00
Alexey Sedunov
737d7dcc2f Kotlin Facet: Use Kotlin SDK for non-JVM imported modules 2018-01-22 12:21:13 +03:00
Alexey Sedunov
70cb08bfdb Misc: Update test data (new 'allopen' Spring annotations added) 2018-01-22 12:21:12 +03:00
Denis Zharkov
2e933a165a Avoid retaining all protobuf objects in DeserializedMemberScope
Object model for deserialized protobuf isn't very cheap, so
loading just our stdlib's packages several times (as we do in the IDE)
might lead to ~ 96 MB of retained memory just by these objects.

While in fact many of them remain unused

 #KT-21517 Fixed
2018-01-22 10:48:25 +03:00
Nikolay Krasko
b701117ffb Minor: reformat, and warning fixes in outdated notification subsystem 2018-01-19 22:41:52 +03:00
Nikolay Krasko
2386cfbd07 Do not spell check overridden declaration names (KT-15000)
#KT-15000 Fixed
2018-01-19 22:41:51 +03:00
Anton Bannykh
ff00831109 JS: minor fixes in kotlin-test-js-it
Jasmine version 2.6.0 doesn't support Promise-based
asynchronous tests.
Also the error message for an unexpected test result was incorrect.
2018-01-19 20:16:31 +03:00
Ilmir Usmanov
f4ad5182b8 Fix OOM error in ReturnUnitMethodTransformer
#KT-22345: Fixed
2018-01-19 20:13:23 +03:00
Ilya Gorbunov
40aa2280a5 Replace .. with until or indices where appropriate
Replace indices.reversed() with lastIndex..0 as it is not optimized in JS yet
2018-01-19 19:53:09 +03:00
Alexander Udalov
513f50785e Use processResources task to copy compiler.xml to IDEA plugin
This fixes tests broken in 4b2d281bba and 95f9884799
2018-01-19 17:26:33 +01:00
Alexander Udalov
4b2d281bba Include META-INF/extensions/compiler.xml into IDEA plugin
This fixes tests and IDEA run configurations broken in 95f9884799
2018-01-19 15:13:40 +01:00
Mikhail Glukhikh
577c6cde82 KtInvokeFunctionReference: protect from KNPE in getLambdaExpression
So EA-114887 Fixed
2018-01-19 16:16:33 +03:00
Mikhail Glukhikh
26c1673da0 J2K: KtInvokeFunctionReference 2018-01-19 16:16:31 +03:00
Mikhail Glukhikh
117c5a29fb KtInvokeFunctionReference.java -> kt 2018-01-19 16:16:22 +03:00
Mikhail Glukhikh
b1bff24cde Move lambda inside: protect from KNPE in getLambdaExpression
So EA-114888 Fixed
2018-01-19 16:16:21 +03:00
Mikhail Glukhikh
f675d9fd81 Convert reference to lambda: protect from root fq name EA-114907 Fixed 2018-01-19 16:16:19 +03:00
Mikhail Glukhikh
3c19af3645 Convert reference to lambda: reformat 2018-01-19 16:16:18 +03:00
Mikhail Glukhikh
9d9b2b2a58 Fix stub inconsistency in "inline type parameter fix"
Fixes one quick-fix test
2018-01-19 16:16:17 +03:00
Mikhail Glukhikh
1924172189 Inline type parameter fix: reformat 2018-01-19 16:16:16 +03:00
Mikhail Glukhikh
ee3f89df87 Remove unused function parameter: delete empty constructor accurately
So #KT-22221 Fixed
Fixes also some quick-fix tests
2018-01-19 16:16:15 +03:00
Mikhail Glukhikh
c4ef95dbf7 Remove empty primary constructor: reformat 2018-01-19 16:16:13 +03:00
Mikhail Glukhikh
ac1c40c0e6 Add function to supertype fix: get rid of incorrect type comparator
So EA-100297 Fixed
2018-01-19 16:16:12 +03:00
Mikhail Glukhikh
7f947bed1e Add function to supertype fix: reformat 2018-01-19 16:16:11 +03:00
Mikhail Glukhikh
925e4e0a67 KotlinUnusedImportInspection: use LocalQuickFixOnPsiElement 2018-01-19 16:16:10 +03:00
Mikhail Glukhikh
a3dda258c8 KotlinUnusedImportInspection (minor): specify platform type 2018-01-19 16:16:09 +03:00
Mikhail Glukhikh
dade8deea6 KotlinUnusedImportInspection: reformat 2018-01-19 16:16:07 +03:00
Mikhail Glukhikh
c54dd6385c KotlinUnusedImportInspection: check for disposal of progress indicator
So #KT-22335 Fixed
2018-01-19 16:16:06 +03:00
Mikhail Glukhikh
c52fcdde70 Remove explicit type: reformat 2018-01-19 16:16:05 +03:00
Mikhail Glukhikh
512e287f3a Remove setter parameter type: do not suggest if type is empty
So #KT-22339 Fixed
2018-01-19 16:16:04 +03:00
Mikhail Glukhikh
f0b172ca35 Remove setter parameter type: reformat 2018-01-19 16:16:02 +03:00
Sergey Igushkin
c8900d672f Update Gradle plugins build instructions 2018-01-19 12:58:39 +03:00
Mikhael Bogdanov
4c1eb21805 Minor. Add assertion message 2018-01-19 10:42:02 +01:00
Nicolay Mitropolsky
2623ae714c Uast: consistency updates for ULambdaExpression 2018-01-19 10:45:58 +03:00
Nicolay Mitropolsky
25cd54713b Uast: consistency for imports-expressions 2018-01-19 10:45:58 +03:00
Nicolay Mitropolsky
d5d49c65b4 Uast: tests for UClass.uastSuperTypes 2018-01-19 10:45:58 +03:00
Mikhael Bogdanov
7b212c5650 Add support for android MPP
#KT-18462 Fixed
2018-01-18 15:21:19 +01:00
Toshiaki Kameyama
2a10d8e837 KT-15176 Remove "Create type alias" intention when called on java class 2018-01-18 16:23:40 +03:00
Dmitry Savvinov
44920f42d8 [NI] Fix unit coercion
Consider following case:

fun foo(): Unit = run { "hello" }

Previously, NI would analyze lambda body without expected type, because
it is a type variable 'R' from 'run', which hasn't been fixed yet. This
leads to treating "hello" as lambda-return argument and adding bogus
'String' constraint on 'R', and, consequently, type mismatch.

Now, we peek into current constraint system and check if return-type of
lambda is type variable with upper-Unit constraint (which is exactly
condition for its body to be Unit-coerced). If so, then we provide
expected Unit-type for body explicitly, and the rest will be done
automatically (in particular, in aforementioned example "hello" wouldn't
be treated as lambda return argument).
2018-01-18 15:13:45 +03:00
Alexander Udalov
b3eeb2f735 Remove unneeded members of ConstantValueFactory 2018-01-18 12:49:38 +01:00
Alexander Udalov
82574cb570 Do not store ClassDescriptor in EnumValue
Only store the ClassId of the enum class and the Name of the entry, and
resolve the needed descriptor in getType() instead, which now takes the
module instance where that descriptor should be resolved
2018-01-18 12:49:38 +01:00
Alexander Udalov
9290d58ed0 Improve "firstArgumentValue" and "argumentValue" extension functions
Using the argument value, which is of type "Any?", is more implicit and
thus difficult to read than using the ConstantValue instance and casting
it to the needed constant value implementation before taking the value
2018-01-18 12:49:38 +01:00
Alexander Udalov
899002b681 Refactor JavaEnumValueAnnotationArgument and implementations
Only require implementations to be able to compute the enum class name
and the corresponding entry name. Only this should be necessary to
correctly resolve the argument; the resolvers will find the
corresponding class descriptor if necessary
2018-01-18 12:49:38 +01:00
Alexander Udalov
907f53e539 Refactor ConstantValue implementations
Remove KotlinBuiltIns and take a ModuleDescriptor instance in getType
instead. This will allow to create constant values in contexts where
there's no module or built-ins accessible (such as, deserialization of
module annotations during indexing of .kotlin_module files in IDE).

Note that some values (KClassValue, EnumValue, AnnotationValue) still
take module-dependent objects (KotlinType, ClassDescriptor and
AnnotationDescriptor respectively). This is to be refactored later
2018-01-18 12:49:38 +01:00
Alexander Udalov
5e97517c8b Fix bug in StringValue.equals
Also simplify equals() implementations of other constant values
2018-01-18 12:49:38 +01:00
Alexander Udalov
95f9884799 Move META-INF/extensions/compiler.xml to module 'cli' 2018-01-18 12:48:04 +01:00
Alexander Udalov
02857dbfdb JS: support "LANGUAGE" directives in box tests 2018-01-18 12:46:27 +01:00
Alexander Udalov
8b3d439d5b JS: minor, simplify code locating default argument values
At the only call site of getDefaultArgument it is checked that the
parameter actually _declares_ default value, so it's not necessary to
try to load that value from supertypes
2018-01-18 12:46:27 +01:00
Nikolay Krasko
ae2d67a5b1 Update "Kotlin configured but no stdlib" status on file update (KT-22356)
Provide feedback before project re-import is finished.

 #KT-22356 Fixed
2018-01-18 12:13:54 +03:00
Nikolay Krasko
2637a36e22 Inspection doesn't suggest Maven Plugin for kotlin-stdlib-jre8 (KT-18007)
#KT-18007 Fixed
2018-01-18 12:13:53 +03:00
Nikolay Krasko
4a2440ea0f Reformat and cleanup idea-maven_main module 2018-01-18 12:13:53 +03:00
Mikhael Bogdanov
7f1cc81d39 Support test directives in android tests 2018-01-18 10:08:58 +01:00
Mikhael Bogdanov
ef1a3ec32d Convert CodegenTestsOnAndroidGenerator to Kotlin 2018-01-18 10:08:58 +01:00
Mikhael Bogdanov
7e6542b8c8 Renema CodegenTestsOnAndroidGenerator.java to CodegenTestsOnAndroidGenerator.kt 2018-01-18 10:08:57 +01:00
Denis Zharkov
1716720604 Optimize declaration providers for case of non-existing packages
Avoid creating memoized function nodes when the value is obviously null
Otherwise, it may lead to about 25M retained by empty concurrent hashmap
nodes
2018-01-18 11:40:26 +03:00
Denis Zharkov
0f74bb4a7a Get rid of compile dependency to 'compiler-embeddable' from :idea
Previously, it's been added transitively from :kotlin-compiler-runner
as a compile dependency instead of runtime as it's declared in compiler-runner
2018-01-18 11:39:34 +03:00
Alexey Tsvetkov
72f2406083 Turn IC on by default for MPP projects 2018-01-17 21:23:43 +03:00
Sergey Igushkin
5deb20543f Get rid of gradle-api artifacts uploaded to and used from JB repo
Remove redundant Maven dependency to `gradle-api` scoped as provided
2018-01-17 18:45:26 +03:00
Vyacheslav Gerasimov
d16883deaa Build: Clean previous output before instrumentation
Otherwise it may lead to unnecessary classes (left from previous plugin build) being packed to plugin
2018-01-17 16:57:56 +03:00
Dmitry Savvinov
c704f2de9a Reformat 'resolution' module according to new codestyle 2018-01-17 16:47:45 +03:00
Vyacheslav Gerasimov
e2b83aecd7 Fix publishing to Gradle plugin portal 2018-01-17 15:33:15 +03:00
Anton Bannykh
7b0070ea62 Promise-based async integration test for kotlin-test-js 2018-01-17 14:46:13 +03:00
Dmitry Jemerov
ca57309374 Temp revert fix for KT-10591 as it causes non-obvious test breakage 2018-01-17 11:39:35 +01:00
Alexey Sedunov
a752f3f38e Misc: Rename class 2018-01-17 12:54:39 +03:00
Alexey Sedunov
62580a47dc Misc: Add test for KT-7316
#KT-7316 Fixed
2018-01-17 12:53:57 +03:00
Alexey Sedunov
54f4f5ff24 Configuration: Add Kotlin SDK for non-JVM projects
#KT-16976 Fixed
2018-01-17 12:52:51 +03:00
Alexey Sedunov
af1d6124ce JS: Do not specify NodeJS path in Gradle projects
We rely on node_modules directory content which must be populated
by the build script itself
2018-01-17 12:45:45 +03:00
Alexey Sedunov
c6a9c36275 Analyze Data Flow: Support cross-language analysis
#KT-16833 Fixed
2018-01-17 12:40:34 +03:00
Dmitry Petrov
6cb68531ae Minor: add missing "'" 2018-01-17 12:31:07 +03:00
Dmitry Petrov
bba8168150 Add test for extension properties declaration in IR 2018-01-17 12:31:07 +03:00
Dmitry Petrov
1f841e35bc Formatting: psi2ir 2018-01-17 12:31:07 +03:00
Dmitry Petrov
432c743771 Formatting: ir.tree and some common code 2018-01-17 12:31:07 +03:00
Dmitry Petrov
fdd000c94f Update testData to new format 2018-01-17 12:31:07 +03:00
Dmitry Petrov
4d54036d21 Use declaration properties in RenderIrElementVisitor 2018-01-17 12:31:07 +03:00
Dmitry Petrov
7dc15b15bb Add basic properties to IR declarations 2018-01-17 12:31:07 +03:00
Dmitry Petrov
2f09c51dca Formatting: IR test classes 2018-01-17 12:31:07 +03:00
Nikolay Krasko
704ce121bc Use other property name in Java with Kotlin static import tests 2018-01-17 12:05:06 +03:00
Nikolay Krasko
1c7e42f1d4 Collapsed comments containing * get removed in the summary line (KT-21994)
#KT-21994 Fixed
2018-01-17 12:05:05 +03:00
Nikolay Krasko
a1b20535b2 Search same place for it usages in rainbow highlighter (KT-22242)
Reuse KotlinTargetElementEvaluator for getting same declaration
context for implicit 'it' parameter.

 #KT-22242 Fixed
2018-01-17 12:05:04 +03:00
Vyacheslav Gerasimov
f86b77083f Add sources and javadoc to kotlin-annotations-android 2018-01-16 21:19:46 +03:00
Alexey Tsvetkov
d1d786dffa Fix lookup tracking in JPS with enabled daemon
#KT-21962 fixed
2018-01-16 21:09:57 +03:00
Alexey Tsvetkov
220fab0d3f Test JPS with Daemon and IC 2018-01-16 21:09:57 +03:00
Alexey Tsvetkov
ca09be1411 Minor: move 'KotlinJpsBuildTestIncremental' to separate file 2018-01-16 21:09:57 +03:00
Nicolay Mitropolsky
b4db744a9b Uast: KotlinStringULiteralExpression.getExpressionType() made always return String 2018-01-16 20:38:00 +03:00
Dmitry Jemerov
e46f69bb36 Disable "Decompile" button if bytecode generation threw exception
#KT-13791 Fixed
2018-01-16 17:54:49 +01:00
Dmitry Jemerov
404f9cc7d8 KotlinBytecodeToolWindow: convert to .kt 2018-01-16 17:54:48 +01:00
Dmitry Jemerov
bad76eb5c2 KotlinBytecodeToolWindow: rename to .kt 2018-01-16 17:54:47 +01:00
Dmitry Jemerov
5b3ab97b4e Highlight 'var' primary constructor parameters as mutable
#KT-11467 Fixed
2018-01-16 17:54:45 +01:00
Dmitry Jemerov
571b424b33 Use DescriptorToSourceUtilsIde.getAnyDeclaration in super navigation
#KT-16333 Fixed
2018-01-16 17:54:44 +01:00
Dmitry Jemerov
cc90dfa65b GotoSuperActionHandler: convert to .kt 2018-01-16 17:54:43 +01:00
Dmitry Jemerov
690c3433d6 GotoSuperActionHandler: rename to .kt 2018-01-16 17:54:42 +01:00
Dmitry Jemerov
106e1b8661 Don't include unindented comments preceding a function into its text range
#KT-10591 Fixed
2018-01-16 17:54:29 +01:00
Dmitry Jemerov
075541da21 Show location info for members defined in object literals
#KT-22179 Fixed
2018-01-16 17:54:27 +01:00
Dmitry Jemerov
564490c9d4 Don't require presence of PropertiesComponent
#KT-22214 Fixed
2018-01-16 17:54:19 +01:00
Dmitry Jemerov
1b6f6e8bf7 Don't indent block comments of typealiases
#KT-22230 Fixed
2018-01-16 17:54:16 +01:00
Dmitry Savvinov
c2b532b167 Reformat the rest of 'frontend'-module according to new codestyle 2018-01-16 18:26:21 +03:00
Dmitry Savvinov
e5f0ffb0c2 Reformat 'frontend' module according to new codestyle 2018-01-16 17:51:51 +03:00
Kirill Rakhman
b567817d1f Make completion for overriding functions respect suspend modifier
Fixes #KT-22200
2018-01-16 15:42:03 +01:00
Kirill Rakhman
8bc020f31b Fix modifier order in generated overriden functions
Fixes #KT-21600
2018-01-16 15:42:02 +01:00
Alexey Sedunov
99be75cbfc Refactoring: Use modifier list in CallableInfo where possible 2018-01-16 17:06:53 +03:00
Alexey Sedunov
ba0a91d74c Quick Fixes: Drop deprecated KotlinCommonIntentionActionsFactory
Also update relevant test to use new action factory API
2018-01-16 17:06:53 +03:00
Alexey Sedunov
908bf71ae6 Quick Fixes: Support cross-language "Create from Usage" with Kotlin target 2018-01-16 17:06:53 +03:00
Alexey Sedunov
d44313876c Create from Usage: Support primary constructor insertion 2018-01-16 17:06:52 +03:00
Alexey Sedunov
877874978f Misc: Add action text assertions to CommonIntentionActionsTest 2018-01-16 17:06:52 +03:00
Toshiaki Kameyama
113e9f496e Add quickfix for UnsafeCastFromDynamicInspection #KT-20915 Fixed 2018-01-16 17:06:51 +03:00
Vyacheslav Gerasimov
f709a382ae Update changelog for 1.2.20 2018-01-16 16:13:54 +03:00
Alexey Sedunov
05b618eec8 Gradle: Use copyable user data for compiler plugin options
#KT-22227 Fixed
2018-01-16 16:09:18 +03:00
Alexey Sedunov
5892944bfc Convert Enum to Sealed Class: Support expect/actual classes 2018-01-16 16:09:17 +03:00
Alexey Sedunov
9d5d85a1c5 Convert Sealed Class to Enum: Support expect/actual classes
#KT-18912 Fixed
2018-01-16 16:09:17 +03:00
Natalia Selezneva
dbd7ceb5fd Fix Evaluate Expression for inline functions from multifile package class.
Find main class generated for debugger by its name instead of relativePath length.
 #KT-22311 Fixed
2018-01-16 16:00:32 +03:00
Cuihtlauac Alvarado
c5982e7ff5 Avoid pick environement variables test failures (#1467)
Remove all lines containing a "Picked up <ENVIRONMENT_VARIALBE>: ..."

Remove empty ERR: section

FIX: KT-22241
2018-01-16 12:33:19 +01:00
Mikhael Bogdanov
b539adf105 Support simple capturing in IR inliner 2018-01-16 11:53:25 +01:00
Mikhael Bogdanov
ca22bc57fd Don't capture primary constructor variables 2018-01-16 11:53:25 +01:00
Mikhael Bogdanov
28f4cc5b18 Generate parameter name in assertion for lateinit properties 2018-01-16 11:53:24 +01:00
Mikhael Bogdanov
e58558dffd Support mapped companions 2018-01-16 11:53:24 +01:00
Mikhael Bogdanov
e57efc7233 Support external functions 2018-01-16 11:53:23 +01:00
Mikhael Bogdanov
c1a1a7f9fb Code clean 2018-01-16 11:53:22 +01:00
Mikhael Bogdanov
9d7eca1376 Support throwNpe intrinsic 2018-01-16 11:53:22 +01:00
Mikhael Bogdanov
d62a7cc9d1 Unwrap fake override on field access 2018-01-16 11:53:21 +01:00
Mikhael Bogdanov
dfbe92344f Skip setter accessors for val 2018-01-16 11:53:21 +01:00
Mikhael Bogdanov
2b95e6bc0d Generate proper vararg array 2018-01-16 11:53:20 +01:00
Mikhael Bogdanov
724f3bf714 Return proper type after coercion 2018-01-16 11:53:20 +01:00
Mikhael Bogdanov
77b93ab7ad Add classType property in IrClassReference, support class references in codegen 2018-01-16 11:53:19 +01:00
Mikhael Bogdanov
b2970ef771 Skip noinline lambdas during inline 2018-01-16 11:53:19 +01:00
Mikhael Bogdanov
ab96e0102a Support IrGetClass 2018-01-16 11:53:18 +01:00
Mikhael Bogdanov
9a1f484771 Fix equals 2018-01-16 11:53:18 +01:00
Nicolay Mitropolsky
d7f0695a51 Uast: KotlinNullabilityUAnnotation.javaPsi type set to PsiAnnotation? 2018-01-16 13:26:22 +03:00
Ilya Chernikov
c7f8312e1b Shade kotlinx.coroutines in embeddable artefacts
fixes #KT-22196
2018-01-16 09:03:53 +01:00
Sergey Igushkin
3ed7df506b Bump bootstrap to 1.2.30-dev-441 2018-01-15 22:38:28 +03:00
Nicolay Mitropolsky
9ce9b434fe Uast: testdata fix for KotlinUastTypesTest.testEa101715 2018-01-15 20:58:18 +03:00
Denis Zharkov
886d3ef3a6 Optimize KotlinScriptDefinitionFromAnnotatedTemplate::isScript
Avoid multiple pattern compilation for script file regex
2018-01-15 18:20:27 +03:00
Denis Zharkov
b4e5f8cf1c Optimize collecting module info in IDE
The problem was that there is no special entity for libraries
in the IntelliJ model, and when we have an element for a library
we have to search through all of its dependencies
(see getOrderEntriesForFile call in collectInfosByVirtualFile)

But for popular library there could be quite a lot of dependencies,
while in most cases we need only the first one to obtain module
info for library itself (see changed usage in resolverForElement).

So it's worth replacing List with Sequence here
2018-01-15 18:20:27 +03:00
Denis Zharkov
d848238a46 Add cache for Module::languageVersionSettings
It might be useful because getExtraLanguageFeatures might be
rather expensive to compute

 #KT-21450 Fixed
2018-01-15 18:20:27 +03:00
Dmitry Jemerov
60874f29fe Inspection for scope functions conversion
#KT-17047 Fixed
2018-01-15 15:37:36 +01:00
Dmitry Jemerov
0b24be9460 Don't enclose 'this' in braces inside string templates 2018-01-15 15:03:39 +01:00
Dmitry Jemerov
560dc920e4 Don't increase nesting level if we aren't processing current expression 2018-01-15 15:03:39 +01:00
Dmitry Jemerov
3a7e4acf22 Reformat and cleanup 2018-01-15 15:03:39 +01:00
Dmitry Jemerov
d15fa83749 API for building visitors from lambdas 2018-01-15 15:03:39 +01:00
Nikolay Krasko
46ac14198c Don't try to cast light element to KtElement (EA-114820) 2018-01-15 14:05:51 +03:00
Nikolay Krasko
adf6ad6283 Check file before cast in KotlinCompletionContributor (EA-101984) 2018-01-15 14:05:50 +03:00
Nikolay Krasko
eae79e96ee Fix NPE in PlainTextPasteImportResolver.tryResolveReferences (EA-10589) 2018-01-15 14:05:50 +03:00
Nikolay Krasko
93d40b0492 Fix NPE in SourceNavigationHelper.findFirstMatchingInIndex (EA-91517) 2018-01-15 14:05:50 +03:00
Nikolay Krasko
2ca7045228 Rewrite KotlinNameSuggesterTest test with KotlinLightCodeInsightFixtureTestCase
Use proper project descriptors and avoid reconfigure for test project.
2018-01-15 14:05:50 +03:00
Ilmir Usmanov
ed11528664 Ignore unreachable code on tail call optimization
#KT-21759: Fixed
2018-01-15 12:57:10 +03:00
Ilmir Usmanov
25998c1f9b Reformat tail call optimization related code 2018-01-15 12:56:54 +03:00
Yan Zhulanow
2ee23ddd02 EA-101715: Handle also case with IntegerValueTypeConstructor 2018-01-15 12:39:35 +09:00
Yan Zhulanow
108e91f2a2 Kapt: Be less strict when it's impossible to add a generated Kotlin source directory for Android project (KT-22056, EA-114271) 2018-01-15 12:39:34 +09:00
Yan Zhulanow
283c762b8b Kapt: Remove laziness from diagnosticFactory and javacMessages, use factory from supertype (KT-22189)
writeDiagnostic() may be invoked after the 'context' is cleared, and lazy implementations will fail.
2018-01-15 12:39:34 +09:00
Yan Zhulanow
192489ae66 Minor: Remove bulk class added by mistake 2018-01-15 12:39:33 +09:00
Yan Zhulanow
1c5cd1b3a0 Minor: Fix problem in IDE with @TestOnly annotation resolution 2018-01-15 12:39:32 +09:00
Yan Zhulanow
81aae03b57 Use Gradle API to import annotations from compiler plugins instead of nasty data storage tasks
Tasks itself will be left for some time until all users migrate to the newer IDE plugin versions.
2018-01-15 12:39:31 +09:00
Yan Zhulanow
e7c1d94c0f Minor: Fix red code in IDE 2018-01-15 12:39:30 +09:00
Yan Zhulanow
e978c42e52 SamWithReceiver: Add Maven/Gradle importers for SamWithReceiver 2018-01-15 12:39:30 +09:00
Yan Zhulanow
0a3a493f25 AllOpen: Fix incorrect 'accessing non-final property in constructor' warning (KT-16619) 2018-01-15 12:39:29 +09:00
Yan Zhulanow
df19162c8c Kapt: Store line information in a file doc comment, instead of annotations (KT-21936) 2018-01-15 12:39:28 +09:00
Yan Zhulanow
c66947ba40 NoArg: Parse 'invokeInitializers' option in Maven importer (KT-19900) 2018-01-15 12:39:27 +09:00
Yan Zhulanow
3512675d96 Compiler plugins: Refactor Maven import handlers in order to support other plugin options 2018-01-15 12:39:26 +09:00
Yan Zhulanow
a85b4ddb0f Kapt: Clear stubs directory on non-incremental stub generation (KT-21735) 2018-01-15 12:39:25 +09:00
Nicolay Mitropolsky
f4a7ecc1bb Uast: Fix for missing local variables in ctor-s bodies
similar to how it is done in `KotlinUBlockExpression`
2018-01-12 22:32:52 +03:00
Dmitry Jemerov
322ac6340a Fix GradleConfigureProjectByChangingFileTestGenerated 2018-01-12 18:58:04 +01:00
Anton Bannykh
c6d7ffb3eb JS DCE: drop unknown file report severity to WARNING
*.kjsm and other files might be received when FileCollection is
used in Gradle as a dependency.

Example: `testCompile project(":$coroutines_core").sourceSets.test.output`
(a popular-ish solution to introduce dependencies between tests)
2018-01-12 20:00:34 +03:00
Anton Bannykh
5d6d321fb2 Reformat K2JSDce.kt 2018-01-12 20:00:34 +03:00
Dmitry Jemerov
ce5b1acfa7 Regenerate tests 2018-01-12 16:59:31 +01:00
Alexander Podkhalyuzin
b8dded2685 Simple implementation for kt paste into project view #KT-8352 Fixed 2018-01-12 15:57:34 +03:00
Alexander Udalov
b925b6ef9f Add test for obsolete issue
#KT-10494
2018-01-12 12:50:38 +01:00
Nikolay Krasko
aee7329b89 Modify incremental test in 173 branch - files are not created anymore 2018-01-12 13:54:45 +03:00
Nikolay Krasko
5a6d58a799 Update to 2017.3.2 (173.4127.27) 2018-01-12 13:54:43 +03:00
Nikolay Krasko
4c09a6cf06 Allow different diagnostics in Javac tests - workaround for IDEA-184289 2018-01-12 13:54:42 +03:00
Nicolay Mitropolsky
27b3cdf1fa Uast: KotlinAccessorCallExpression made implement JvmDeclarationUElement 2018-01-12 13:54:41 +03:00
Nicolay Mitropolsky
254caef0e6 Idea version set to 173.3942.27 2018-01-12 13:54:39 +03:00
Nicolay Mitropolsky
f8601479de Uast: handling @receiver annotations 2018-01-12 13:54:38 +03:00
Nicolay Mitropolsky
f91f42c253 Uast: Constructors.kt testdata fixes 2018-01-12 13:54:36 +03:00
Nicolay Mitropolsky
2c81362ce1 Uast: uastParent made final in KotlinAbstractUElement 2018-01-12 13:54:35 +03:00
Nicolay Mitropolsky
e7200d16c3 Uast: no more need to exclude UIdentifier from JvmDeclarationUElement check 2018-01-12 13:54:33 +03:00
Nicolay Mitropolsky
e22e466485 Uast: making AbstractKotlinUClass not inherit from AbstractJavaUClass 2018-01-12 13:54:32 +03:00
Nicolay Mitropolsky
084da3665a Uast: removing java-uast usage from KotlinUastLanguagePlugin and KotlinEnumConstantClassReference 2018-01-12 13:54:31 +03:00
Nicolay Mitropolsky
260c549cd7 Uast: AbstractKotlinUVariable annotations now are retrieved from Kotlin Psi, not from compiled (KT-21025)
and `KotlinNullabilityUAnnotation` now is created for every `AbstractKotlinUVariable`
2018-01-12 13:54:29 +03:00
Nicolay Mitropolsky
f0723a5c07 Uast: WrappedUAnnotation as replacement for usage of JavaUAnnotation (KT-21025) 2018-01-12 13:54:28 +03:00
Vyacheslav Gerasimov
53d6c17417 Set correct until-build for Idea 173 plugin 2018-01-12 13:54:26 +03:00
Nicolay Mitropolsky
a278e4ccef Fixing non-running tests, that used MockApplication environment 2018-01-12 13:54:25 +03:00
Alexey Sedunov
c1cf03d89c Data Inflow: Support grouping by expression nullability 2018-01-12 13:54:23 +03:00
Nicolay Mitropolsky
0a1580159f Uast: Constructors.kt testData fixes 2018-01-12 13:54:22 +03:00
Alexey Sedunov
683bbe396d Data Inflow: Support grouping by leaf expressions 2018-01-12 13:54:20 +03:00
Alexey Sedunov
b46784ab86 Safe Delete: Suppress walking through light field initializer
This fixes some tests failing in 173 branch

 #KT-21508 Fixed
2018-01-12 13:54:19 +03:00
Nikolay Krasko
cbfd7088bf Fix inAnnotation test in 173 branch 2018-01-12 13:54:17 +03:00
Nikolay Krasko
c0582ed732 Update file name replace in QuickFix tests 2018-01-12 13:54:16 +03:00
Nicolay Mitropolsky
502a6fa9f1 Uast: SuperCalls.render.txt testdata fix 2018-01-12 13:54:14 +03:00
Nicolay Mitropolsky
5f6e5c5779 Uast: AbstractKotlinUClass compilation fix 2018-01-12 13:54:13 +03:00
Nicolay Mitropolsky
b51a7c6957 Spring: fix for package-completion tests
because otherwise `java` package name interfere with `java` directory name completion from somewhere
2018-01-12 13:54:12 +03:00
Nicolay Mitropolsky
1fd8abb0bb Spring: removing needless EP-s because they ported to UAST in platform 2018-01-12 13:54:10 +03:00
Nicolay Mitropolsky
79abc8743e KotlinSpringComponentScanInspection made to support platform JamReferenceContributor 2018-01-12 13:54:09 +03:00
Vyacheslav Gerasimov
0cad41bb0c Drop missing gradle extensions from gradle.xml 2018-01-12 13:54:07 +03:00
Nikolay Krasko
23bd0b3db5 Update test data because of changed action name in 173 2018-01-12 13:54:06 +03:00
Nicolay Mitropolsky
29fd34d1de Idea version set to 173.3727.22(RC1) 2018-01-12 13:54:05 +03:00
Nicolay Mitropolsky
8c27bf98f4 UAST: StringTemplateComplex testdata fix 2018-01-12 13:54:03 +03:00
Alexey Sedunov
f3dad53ad4 Line Markers: Respect subclass module when filtering out duplicates
#KT-21010 Fixed
2018-01-12 13:54:02 +03:00
Alexey Sedunov
d37c8397f5 Move: Fix applicability check in IDEA 173 2018-01-12 13:54:00 +03:00
Vyacheslav Gerasimov
ab50ccf995 Fix formatting for new kotlin dsl gradle project build script 2018-01-12 13:53:59 +03:00
Vyacheslav Gerasimov
560e2d1ced Drop new Kotlin Dsl gradle project wizard which has been merged to idea 2018-01-12 13:53:58 +03:00
Nicolay Mitropolsky
aa43bebbf1 SpringTestFixtureExtension: option to forbid facet autoconfigure added 2018-01-12 13:53:56 +03:00
Nicolay Mitropolsky
3a06b8fe3b SpringKotlinAutowiringInspection: getting rid of SpringJavaInjectionPointsAutowiringInspection 2018-01-12 13:53:55 +03:00
Nicolay Mitropolsky
bef100b46e AbstractIntentionTest: isApplicableOnPooled made run under ProgressIndicator 2018-01-12 13:53:53 +03:00
Vyacheslav Gerasimov
09f31076e6 Update ideaVersion to 173.3415.22 2018-01-12 13:53:52 +03:00
Nicolay Mitropolsky
2f30ca3fac Ultimate-plugin: UAST added as dependency 2018-01-12 13:53:51 +03:00
Nicolay Mitropolsky
f4a8a98157 Ultimate-plugin: multiplePropertiesAnnotationConfig.kt test data fixes
`@Qualifier` should not be there. It was a bug in platform
2018-01-12 13:53:49 +03:00
Nicolay Mitropolsky
6cb556dd6b AbstractQuickFixTest: FORCE_PACKAGE_FOLDER directive added
It was added as workaround for IDEA-176033 (IDEA-176032 in particular)
2018-01-12 13:53:48 +03:00
Nicolay Mitropolsky
ab0c081897 AbstractExtractionTest: fix for invalid files
`configureByFile` should be run after other configurations (like `configureKotlinRuntimeAndSdk`) because they could make configured file invalid
2018-01-12 13:53:46 +03:00
Nicolay Mitropolsky
dd45780de9 RecursiveMethodCallMarkerInfo and SuspendCallMarkerInfo forced to target Leaf-elements
because of restriction added in IDEA 173
2018-01-12 13:53:45 +03:00
Nicolay Mitropolsky
34bdc04fbe AbstractNavigateToLibraryTest: fix for invalid files
otherwise current file is invalidated by `configureAs` and `additionalConfig`
2018-01-12 13:53:44 +03:00
Nicolay Mitropolsky
7758875955 EdtTestUtil.runInEdtAndWait fix for proper user action emulation
changed because `com.intellij.ide.IdeEventQueue` doesn't consider events from `SwingUtilities.invokeAndWait` as user interaction
2018-01-12 13:53:42 +03:00
Nicolay Mitropolsky
0acfce55a8 KotlinCoreEnvironment: set ideaCompatibleBuildNumber = "173.1" 2018-01-12 13:53:41 +03:00
Nicolay Mitropolsky
6bfe168dd7 UAST: SimpleKotlinRenderLogTest.testWhenAndDestructing testdata fix 2018-01-12 13:53:39 +03:00
Nicolay Mitropolsky
8a23a62c90 AbstractJavaToKotlinConverterForWebDemoTest: setup fix: JvmElementProvider and JavaModuleSystem added 2018-01-12 13:53:38 +03:00
Mikhail Glukhikh
8810e15f08 ExpressionOfTypeProcessor: get member name in read action 2018-01-12 13:53:36 +03:00
Mikhail Glukhikh
3f9054b28b Fix find usages tests in 173 (run via ProgressIndicator) 2018-01-12 13:53:35 +03:00
Nicolay Mitropolsky
cfcee0a1fe Workaround for CoreEnvironment initialization: explicitly setting versions for extensions 2018-01-12 13:53:34 +03:00
Nicolay Mitropolsky
6b656d4da5 Spring gutter icons SpringApiIcons -> SpringApiIcons.Gutter fix.
Following the patch in idea https://upsource.jetbrains.com/IDEA/revision/ultimate-527b9189219f191b62eed59d699f57acccda05c3
2018-01-12 13:53:32 +03:00
Nicolay Mitropolsky
099c1a84ec Idea version set to 173.3302.8 2018-01-12 13:53:31 +03:00
Nikolay Krasko
60149e3021 Update file structure tests as FileStructurePopup api was changed in 173 2018-01-12 13:53:29 +03:00
Nicolay Mitropolsky
f5e3a5faa4 Spring-Kotlin: Gutter repaired (KT-20550, KT-20566)
Platform now allows Gutter to be placed only on leafs elements, this patch fixes it for `KotlinSpringClassAnnotator`.
2018-01-12 13:53:28 +03:00
Ilya Gorbunov
9e21744bf5 streamex version was changed in 173-snapshot to 0.6.5 2018-01-12 13:53:27 +03:00
Nicolay Mitropolsky
208a986eab UAST: support for JvmDeclarationUElement 2018-01-12 13:53:25 +03:00
Nicolay Mitropolsky
f1579d01af UAST test data fixes: LocalVariableWithAnnotationKt fix for variable type
it is not clear for me why it was not `String`
2018-01-12 13:53:24 +03:00
Nicolay Mitropolsky
7c3c59de00 UAST test data fixes: @null in render
as a "nullability" annotation for primitive types
2018-01-12 13:53:22 +03:00
Nicolay Mitropolsky
9fed8f1d24 idea-version set to since-build="173.1" until-build="181.*" 2018-01-12 13:53:21 +03:00
Vyacheslav Gerasimov
ceaa34201e Fix GradleNoduleBuilder use qualified names check 2018-01-12 13:53:19 +03:00
Nicolay Mitropolsky
4c775a9516 JvmFacade-related tests repair 2018-01-12 13:53:18 +03:00
Simon Ogorodnik
7da9268e10 Fix proguard settings for 173 (ignore com.intellij.util.io.TarUtil) 2018-01-12 13:53:16 +03:00
Simon Ogorodnik
f940c0b86f Fix compilation in 173 (GradleModuleBuilder.java) 2018-01-12 13:53:15 +03:00
Anton Bannykh
4f97040ce5 Fix compilation (MockParameterInfoUIContext.java)
(cherry picked from commit 21b0956)
2018-01-12 13:53:14 +03:00
Nicolay Mitropolsky
7eb2d0d185 KotlinLanguageInjector using Registry to enable annotation injections
(cherry picked from commit 8bdfeb7)
2018-01-12 13:53:12 +03:00
Simon Ogorodnik
12daf4389e Fix compilation in 173 (MockParameterInfoUIContext.java) 2018-01-12 13:53:11 +03:00
Dmitry Jemerov
53a3d08a0e Fix compatibility with BuildScriptDataBuilder API changes 2018-01-12 13:53:09 +03:00
Nicolay Mitropolsky
d7fcc69315 KotlinLanguageInjector#injectInAnnotationCall optimization: using PsiClassNamePatternCondition to avoid calling getResolvedCall 2018-01-12 13:53:08 +03:00
Nicolay Mitropolsky
81b6a61edf KotlinLanguageInjector can inject into files modified for autocompletion 2018-01-12 13:53:07 +03:00
Nicolay Mitropolsky
1435911437 KotlinLanguageInjector understands patterns-injections into Java annotations 2018-01-12 13:53:05 +03:00
xiexed
743dc80b4d KtLightAbstractAnnotation build fix for 173 (#1283) 2018-01-12 13:53:04 +03:00
Dmitry Jemerov
70caae4c6f Register new service and EPs added in 173 2018-01-12 13:53:02 +03:00
xiexed
defb5a9d10 Fixes for 173 after 28.08.17 changes in IDEA (#1271)
* `JarFileSystem.getJarRootForLocalFile` now is nullable in IDEA

* Spring-related renamings following ones in IDEA
2018-01-12 13:53:01 +03:00
Nicolay Mitropolsky
6690f9f1da Build fix for KotlinSpringClassAnnotator after collectNavigationMarkers nullability changes in IDEA 173 2018-01-12 13:52:59 +03:00
Vyacheslav Gerasimov
3f15f7a394 UAST: Fix testPropertyWithAnnotation 2018-01-12 13:52:58 +03:00
Vyacheslav Gerasimov
e6efaaf752 UAST: Add testConvertTypeInAnnotation 2018-01-12 13:52:56 +03:00
Vyacheslav Gerasimov
92c23aa0ed UAST: override getFunctionalInterfaceType + test 2018-01-12 13:52:55 +03:00
Vyacheslav Gerasimov
8eddb10870 UAST: Properly handle annotations on local variables 2018-01-12 13:52:54 +03:00
Vyacheslav Gerasimov
35fa8efbf3 Fix compilation after moving to idea 173 2018-01-12 13:52:52 +03:00
Vyacheslav Gerasimov
8f7a354592 Download IDEA 173.3188.16 2018-01-12 13:52:51 +03:00
Nikolay Krasko
2a0b7e293f Minor: KotlinCodeFragmentFactory.kt cleanup 2018-01-11 22:08:18 +03:00
Natalia Selezneva
4d6c83b5b9 Debugger: do not fail if j2k couldn't convert expression creating codeFragment from text 2018-01-11 22:08:17 +03:00
Ilmir Usmanov
c023831a00 Ignore open modifier on top-level suspend function when generating light classes
#KT-21642: Fixed
2018-01-11 19:33:47 +03:00
Nikolay Krasko
5da156e93c Setup modules before test configuration in NavigateToStdlibSourceTest.kt 2018-01-11 15:03:03 +03:00
Nikolay Krasko
91a9d3cf80 Search class after full test configuration in AbstractHierarchyWithLibTest 2018-01-11 15:02:14 +03:00
Nikolay Krasko
2f817662d5 Process only project scope in AbstractHierarchyWithLibTest 2018-01-11 15:01:47 +03:00
Nikolay Krasko
8ade03ac0b Avoid using mock JDK because of bad cast in ProjectJdkTableImpl.getState
com.intellij.openapi.projectRoots.impl.MockSdk cannot be cast to com.intellij.openapi.projectRoots.impl.ProjectJdkImpl
2018-01-11 15:00:57 +03:00
Nikolay Krasko
e710cbb0bb Don't fail during error reporting on invalid elements 2018-01-11 14:56:32 +03:00
Alexander Udalov
2593ce73f1 Update copyright in generated sources
To fix tests that are checking that the generated data is up to date
2018-01-11 12:45:36 +01:00
Nicolay Mitropolsky
9cb62d66cb KtLightAnnotation: handling vararg with single arg (EA-114679)
It is deprecated but yet possible form of usage
2018-01-11 14:05:15 +03:00
Ilya Gorbunov
6197c5bf7f Add sample for coerceIn with floating point range
#KT-20357
2018-01-11 09:05:28 +03:00
Ilya Gorbunov
8fc83e3ff5 Add samples for coerceIn, coerceAtLeast, coerceAtMost for comparable types
#KT-20357
2018-01-11 09:05:28 +03:00
shiraji
17573a3c21 Add samples for coerceIn
#KT-20357
2018-01-11 09:05:28 +03:00
shiraji
4559da9848 Add samples for coerceAtMost
#KT-20357
2018-01-11 09:05:28 +03:00
shiraji
db607e231c Add samples for coerceAtLeast
#KT-20357
2018-01-11 09:05:27 +03:00
kenji tomita
1db0e5c23e Add samples for reversed list views
#KT-20357
2018-01-11 09:05:27 +03:00
AdamMc331
2fc26ba08f Added samples for property delegates as part of KT-20357. 2018-01-11 09:05:27 +03:00
Vyacheslav Gerasimov
892e901f35 Update changelog for 1.2.20 2018-01-10 20:32:05 +03:00
Ilmir Usmanov
32a94c70e9 Use tail call optimization if ARETURN has multiple sources
#KT-21977: Fixed
2018-01-10 20:14:32 +03:00
Ilmir Usmanov
5dbab2f907 Disable tail call optimization, if the call is inside try block
#KT-21165: Fixed
2018-01-10 20:13:55 +03:00
Denis Zharkov
3cfe43f83a Add -Xsupport-compatqual-checker-framework-annotations flag
It's implemented through Jsr305State while it's not related
to jsr-305 becasue currently it's the most convenient way
to introduce the flag.

Probably, it's worth renaming Jsr305State to something more abstract
like NullabilityAnnotationsConfiguration

 #KT-21982 Fixed
2018-01-10 17:02:46 +03:00
Simon Ogorodnik
40706de3db Add ability to resolve kdoc links from package view 2018-01-10 16:37:07 +03:00
Alexey Sedunov
75ce68197f Configuration: Fix API version UI update on language version change
#KT-21979 Fixed
 #KT-21980 Fixed
2018-01-10 16:24:30 +03:00
Alexey Sedunov
9d1fbbd1c6 Move: Correctly determine target module for deferred files 2018-01-10 16:24:28 +03:00
Alexey Sedunov
253c5f2d9b Gradle: Compile Gradle models/model builders for plugins under JVM 1.6
This prevents imports failure in projects using older versions of Gradle
2018-01-10 16:24:27 +03:00
Alexey Sedunov
258bd1e8c0 Maven: Fix <args> parsing on import to the Kotlin facet
#KT-22153 Fixed
2018-01-10 16:24:25 +03:00
Ilya Chernikov
6f135e89d7 Make daemon starting more tolerant to the failures - retry
(cherry picked from commit 386cfec)
2018-01-10 13:38:20 +01:00
Ilya Gorbunov
c8bd623d69 Samples: add some operations to do with the constructed ranges 2018-01-10 15:32:51 +03:00
kenji tomita
4cb2b12f01 Add samples for range construction operators 2018-01-10 15:32:50 +03:00
Andre Perkins
31d650a041 Add sample for emptySet 2018-01-10 15:32:50 +03:00
Jake Wharton
11696ac4c0 Implement String.toBoolean() for JS.
#KT-16348
2018-01-10 15:32:49 +03:00
Dmitry Jemerov
86c10b635a Initial implementation of method separators
#KT-13029 Fixed
2018-01-10 13:17:33 +01:00
Dmitry Jemerov
fd01351740 Implement display of code construct start for Kotlin
#KT-20470 Fixed
2018-01-10 13:17:33 +01:00
Dmitry Jemerov
968e6ecde4 KotlinPairMatcher: convert to .kt
(cherry picked from commit 0bc4f26)
2018-01-10 13:17:33 +01:00
Dmitry Jemerov
0c429857de KotlinPairMatcher: rename to .kt
(cherry picked from commit e386c35)
2018-01-10 13:17:33 +01:00
Nicolay Mitropolsky
4a4bf5635d Uast: KtLightAnnotation converting support (KT-21702) 2018-01-10 15:12:12 +03:00
Dmitry Jemerov
99a9634609 Don't generate references to eap-1.1 and eap-1.2 repositories
Now all Kotlin EAP releases are published only to kotlin-eap on Bintray
2018-01-10 12:13:02 +01:00
Dmitry Petrov
5ffd6a737e Closures in scripts have outer expression
#KT-22029 Fixed Target versions 1.2.30
2018-01-10 14:08:56 +03:00
Dmitry Petrov
d25ebadf53 Minor: formatting 2018-01-10 14:08:56 +03:00
Dmitry Jemerov
e80dae1802 Update copyright in generated tests 2018-01-10 11:55:28 +01:00
Dmitry Jemerov
5ec5807399 TestGenerator: J2K 2018-01-10 11:20:57 +01:00
Dmitry Jemerov
993db696ec TestGenerator: rename to .kt 2018-01-10 11:19:25 +01:00
Dmitry Jemerov
da678a4be2 Use new JRE chooser in Kotlin script run configuration 2018-01-09 18:43:21 +01:00
Dmitry Jemerov
ebc9c217c1 Get rid of PluginJetFilesProvider, use a more sane impl instead 2018-01-09 18:43:20 +01:00
Dmitry Jemerov
685d38218d Extension point for detecting build system type used in project
Now we use a non-deprecated way to detect Maven modules
2018-01-09 18:43:19 +01:00
Dmitry Jemerov
0ca2117ac7 Remove the usages of some of the deprecated APIs 2018-01-09 18:43:11 +01:00
Dmitry Jemerov
361824e170 Fix HighlightingTestGenerated and LambdaImplicitHintsTest 2018-01-09 18:04:39 +01:00
Dmitry Jemerov
8c7f57ca83 Honor "Use continuation indent in argument lists" for indent by Enter
#KT-22121 Fixed
2018-01-09 15:41:21 +01:00
Dmitry Jemerov
d79ac58340 Refactoring: replace WrappingStrategy interface with lambda 2018-01-09 15:41:20 +01:00
Dmitry Jemerov
67897d9b3d Don't wrap argument list containing anonymous functions
Just like for objects and lambdas, don't consider line breaks inside
anonymous functions as line breaks inside argument list
2018-01-09 15:41:18 +01:00
Dmitry Jemerov
a5cc9809ac Improved logic for chained lambda indentation
#KT-22071 Fixed
2018-01-09 15:41:17 +01:00
Dmitry Jemerov
54c262c505 Use receiver type of extension members as qualifier in Goto Symbol
#KT-17217 Fixed
2018-01-09 15:41:15 +01:00
Dmitry Jemerov
0104ed7d44 Show line marker navigation actions in Alt-Enter menu
#KT-14951 Fixed
2018-01-09 15:41:09 +01:00
Dmitry Jemerov
63af3c8e03 Delegate Ctrl-Shift-Enter to plain handler if needed
#KT-11503 Fixed
2018-01-09 15:32:22 +01:00
Dmitry Jemerov
f36f85f55c Don't require documentation in test sources
#KT-21837 Fixed
2018-01-09 13:54:56 +01:00
Dmitry Jemerov
165ac97c4b SortModifiersInspection detects modifiers before annotations
#KT-22013 Fixed
2018-01-09 13:54:56 +01:00
Dmitry Jemerov
408c753837 Check that a file with .kt extension is actually a KtFile
#KT-22111 Fixed
2018-01-09 13:54:56 +01:00
Dmitry Jemerov
69c8da7403 Cleanup: apply all inspection quickfixes 2018-01-09 13:54:56 +01:00
Dmitry Jemerov
6f722d647f Reformat 2018-01-09 13:54:56 +01:00
Dmitry Jemerov
6299e0e941 Check correct element to determine if 'if' rbrace needs wrapping
#KT-22093 Fixed
2018-01-09 13:54:56 +01:00
Dmitry Jemerov
e9ca6a6038 Call arguments should not affect parameter names returned in MethodInfo
The parameter names are only used for blacklist filtering, and should
correspond only to the function being called; the order and number of
actually provided arguments does not matter.
2018-01-09 13:49:03 +01:00
Dmitry Jemerov
599bb878f1 Rename test to correspond to the name of code under test 2018-01-09 13:49:02 +01:00
Dmitry Jemerov
78682ac493 Respect imports when rendering class names in type hints
#KT-19524 Fixed
2018-01-09 13:49:01 +01:00
Dmitry Jemerov
45282af38b Prototype of inlay hints for suspending calls (KT-20187) 2018-01-09 13:48:31 +01:00
Dmitry Jemerov
d060203896 Don't show type hints for SAM constructors
#KT-22050 Fixed
2018-01-09 13:34:11 +01:00
Dmitry Jemerov
0991dba626 Better position of argument name hint for multiline varargs
#KT-20614 Fixed
2018-01-09 13:34:10 +01:00
Dmitry Jemerov
6c23d3a220 Show inlay hints for implicit parameters and receivers of lambdas
#KT-20533 Fixed
2018-01-09 13:34:09 +01:00
Dmitry Jemerov
da157fafdc Add inlay hints for values returned from lambdas
#KT-20067 Fixed
2018-01-09 13:34:01 +01:00
Dmitry Jemerov
e558837214 Cleanup: better function name 2018-01-08 14:41:49 +01:00
Toshiaki Kameyama
3b212558e2 KT-21949 Please add a separate Color Scheme settings for properties synthesized from Java accessors (#1458) 2018-01-08 13:04:43 +01:00
Toshiaki Kameyama
19c35ef48c KT-21213 multiline kdoc - intellij joins lines together without space (#1459)
* KT-21213 multiline kdoc - intellij joins lines together without space

* Use \n directly as a line separator #KT-21213

* Remove unused import #KT-21213
2018-01-05 15:29:11 +01:00
Dmitry Jemerov
d51dd97156 Avoid exception from DocumentImpl.setInBulkUpdate in reformat inspection
#KT-21036 Fixed
2018-01-04 19:03:55 +01:00
Toshiaki Kameyama
266b40b654 KT-21974 Editor color scheme option for Kotlin typealias names (#1457) 2018-01-04 17:39:39 +01:00
Sergey Igushkin
06903f803b (minor) Separate the Gradle annotations from CompilerArgumentAware 2018-01-03 22:14:23 +03:00
Sergey Igushkin
d881efdeb1 Improve disambiguation of subplugin option inputs
The original approach required evaluating the existing input properties
of the task. This led to evaluation of the property values, and could
execute incorrectly if the task was not properly initialized at that
moment.
The new approach fixes that by first grouping options from each
subplugin by key and then adding disambiguating index suffixes.
2018-01-03 22:14:23 +03:00
Sergey Igushkin
1be9e04797 Move conditional task caching setup into the task constructors;
Add 'kotlin.caching.enabled' flag to switch the caching for all tasks;
Rename and change semantics of cache support checks: make two instead
    of one, `isBuildCacheSupported` and `isBuildCacheEnabledForKotlin`;
Remove FileOptionKind entries that are redundant at the moment;
Improvements in BuildCacheIT.kt and other refactoring  suggestions from
    the review
    https://upsource.jetbrains.com/kotlin/review/KOTLIN-CR-1647
2018-01-03 22:14:22 +03:00
Sergey Igushkin
fd066ea4d5 Fix top-level property of an API-level-dependent class: move to the body 2018-01-03 22:14:22 +03:00
Sergey Igushkin
c5a88c5fb7 Add BuildCacheRelocationIT, remove same files testing as redundant. 2018-01-03 22:14:22 +03:00
Sergey Igushkin
6bea643176 Fix JS DCE classpath duplicated in two input properties
* Do not add the classpath elements to source to avoid them being
  treated as task inputs without proper classpath normalization
* Move resolution of the classpath configuration to execution time
2018-01-03 22:14:22 +03:00
Sergey Igushkin
67b5527c68 Fix Kotlin destination dir added to Java task without normalization.
Issue #KT-20604 Fixed
2018-01-03 22:14:22 +03:00
Sergey Igushkin
97edda44c8 Turn on relocatable build cache -- change PathSensitivity to RELATIVE 2018-01-03 22:14:22 +03:00
Sergey Igushkin
c852d0b6cb Subplugin options refactoring & Gradle input improvements
Introduce FilesSubpluginOption Special kind of SubpluginOption that
holds a list of files together with the kind of these files with respect
to the task.

Add a logic for handling such options and converting them into
task inputs.

Refactor CompilerPluginOptions: make it store subplugin options to be
able to add options from KotlinCompile to the kapt tasks.

Introduce WrapperSubpluginOption for encoded and complex options.

Remove pluginOptions from the Gradle inputs built from the
compiler args.

Do not cache Kotlin compilation with kapt1 enabled: since we are going
to drop kapt1 it anyway, there's no point in implementing
proper cache for it, so just disable the caching of the task in case
kapt1 is used.
2018-01-03 22:14:22 +03:00
Sergey Igushkin
93097014a0 Add integration tests for Gralde build cache support.
Add an up-to-date'ness test for subplugin options.
2018-01-03 22:14:21 +03:00
Sergey Igushkin
57f710c931 Explicit opt-in switch for Kapt caching. 2018-01-03 22:14:21 +03:00
Sergey Igushkin
7ee3b81939 Add Kotlin sources output as a separate output directory for kapt. 2018-01-03 22:14:21 +03:00
Sergey Igushkin
4a69d1545b Disable IC when IC cache is missing
Check task build directory for any files
2018-01-03 22:14:21 +03:00
Sergey Igushkin
14c80baec8 Make the tasks cacheable, add logic that decides whether to cache them 2018-01-03 22:14:21 +03:00
Sergey Igushkin
26c158cbae Annotate the properties with @PathSensitive (+ override source) 2018-01-03 22:14:21 +03:00
Sergey Igushkin
e46b56acbc Add @LocalState of buildServicesWorkingDir to KotlinCompile 2018-01-03 22:14:21 +03:00
Sergey Igushkin
627fe52858 Map compiler arguments to Gradle inputs. 2018-01-03 22:14:20 +03:00
Sergey Igushkin
a8ba8fbf77 Make pluginOptions.classpath a separate input in the Gradle tasks
(cherry picked from commit b03e758)
2018-01-03 22:14:20 +03:00
Sergey Igushkin
a752d30f12 Move CompilerArgumentAware to the <...>.internal package. 2018-01-03 22:14:20 +03:00
Sergey Igushkin
62f2876230 Refactor compiler arguments in Gradle tasks:
Pull create/setup args functions up to CompilerArgumentsAware interface
Remove diamond-shaped CompilerArgumentsAware inheritance
Provide the default implementation for serialization in the interface
Make KotlinJsDce implement CompilerArgumentsAware
Implement the compiler args logic for Kapt & GenerateStubs tasks
2018-01-03 22:14:20 +03:00
Toshiaki Kameyama
6b2c22aff1 Add intention to specify all types explicitly in destructuring assignment
#KT-16260 Fixed
2018-01-03 17:23:31 +01:00
Dmitry Jemerov
3529d61a7d Exclude generated test classes from language statistics 2018-01-03 14:57:01 +01:00
Toshiaki Kameyama
eb12cfd444 KT-18674 Join Lines should join strings (#1305)
* Join Lines should join strings #KT-18674 Fixed

* #KT-18674 Fixed
2018-01-03 11:27:16 +01:00
Toshiaki Kameyama
16695c1af5 KT-21929 Inappropriate quick fix for a sealed class instantiation (#1444) 2018-01-03 11:20:58 +01:00
Toshiaki Kameyama
de185b79d0 KT-21780 Wrong redundant setter inspection (#1453) 2018-01-03 11:14:23 +01:00
Toshiaki Kameyama
640c28ceaf KT-14670 Support kotlinPackageName() macro in live templates (#1455)
* KT-14670 Support kotlinPackageName() macro in live templates

* Use context.psiElementAtStartOffset.containingFile #KT-14670
2018-01-03 10:41:28 +01:00
Dmitry Jemerov
84d63051f9 Add a rule for invalid characters in names 2018-01-02 13:17:31 +01:00
Dmitry Jemerov
f83c5344d7 Apply same style for top-level and object properties
#KT-20437 Fixed
2018-01-02 12:46:03 +01:00
Dmitry Jemerov
1c7d97289b Naming convention inspection for test functions
#KT-21547 Fixed
2018-01-02 12:46:02 +01:00
Dmitry Jemerov
37d2ff2d4d Report more friendly messages from naming conventions inspection
#KT-19736 Fixed
2018-01-02 12:46:01 +01:00
Dmitry Jemerov
429bf5bb98 Reformat 2018-01-02 12:46:00 +01:00
Toshiaki Kameyama
79ff36592d KT-15320 Live templates: please add function which returns the "outer" class name 2018-01-02 12:35:20 +01:00
Ilya Gorbunov
e2306ecf94 Keep exception primary constructors for binary compatibility in JS
Resort to a workaround for KT-22053 in direct Throwable inheritors.
2017-12-29 21:21:20 +03:00
Ilya Gorbunov
3825187e93 Update expected reachable node count 2017-12-29 21:20:59 +03:00
Ilya Gorbunov
a1f67e347f Relax nullability of UninitializedPropertyAccessException constructor parameters
To make it consistent with other exception types
2017-12-29 21:16:17 +03:00
Ilya Gorbunov
4e26ca5659 Add missing exception constructors to common and JS declarations
Add test to validate exception properties after calling various constructors.

Make NumberFormatException a descendant of IllegalArgumentException in all platforms.

#KT-21861 Fixed
#KT-21191 Fixed
2017-12-29 21:16:17 +03:00
Ilya Gorbunov
496df371f4 Provide the guide for sample authoring 2017-12-29 20:42:46 +03:00
Pavel V. Talanov
03a8ce63b2 Scripts: fix any file deletion potentially leading to reindex 2017-12-29 20:14:59 +03:00
Dmitry Jemerov
25ea53457e Send source code in exceptions as attachments, not text (common cases)
#KT-17678 In Progress
2017-12-29 15:35:53 +01:00
Toshiaki Kameyama
817dadc120 Specify type: do not suggest nullable type if not null is overridden
So #KT-12814 Fixed
2017-12-29 17:28:44 +03:00
Mikhail Glukhikh
50eaca1ac4 Add modifier fix: improve style a bit 2017-12-29 17:17:38 +03:00
Toshiaki Kameyama
184651d366 Do not suggest "add inner" quick fix for interfaces etc. #KT-18396 Fixed 2017-12-29 16:43:47 +03:00
Toshiaki Kameyama
84a6ef6ac4 Add inspection to detect is checks for object types #KT-21741 Fixed 2017-12-29 16:24:18 +03:00
Dmitry Jemerov
247881baf9 Apply style guide and enable reformat inspection 2017-12-29 13:51:53 +01:00
Mikhail Glukhikh
0df3ffbe36 Build fix: convert reference to lambda
Related to KT-19283 (fixes mistake in 3f005924)
2017-12-29 14:36:10 +03:00
Dmitry Jemerov
896246a7f5 More cleanup after J2K 2017-12-29 10:19:50 +01:00
Dmitry Jemerov
d0e8e176c4 Catch exceptions from decompiler service
EA-108937 - RE: InvocationExprent.toJava
2017-12-29 10:19:50 +01:00
Dmitry Jemerov
9a61abfb9f Don't add null module info to list
EA-113650 - TCE: LazyModuleDependencies.getModulesWhoseInternalsAreVisible
2017-12-29 10:19:50 +01:00
Dmitry Jemerov
2c4180222a Check if containing file is KtFile
EA-109460 - CCE: KtElementImplStub.getContainingKtFile
2017-12-29 10:19:50 +01:00
Dmitry Jemerov
4b6efe3eb0 Take read action in KtLightParameter.isEquivalentTo()
EA-109775 - (OperatorReferencesSearcher) assert: PsiFileImpl.getStubTree
2017-12-29 10:19:50 +01:00
Dmitry Jemerov
7f1dd88600 KtLightParameter: convert to .kt and cleanup 2017-12-29 10:19:50 +01:00
Dmitry Jemerov
98d26ae59f KtLightElementParameter: rename to .kt 2017-12-29 10:19:50 +01:00
Dmitry Jemerov
cde84a7923 Handle I/O exceptions when updating library jars
EA-101940 - FNFE: FileUtil.openOutputStream
2017-12-29 10:19:50 +01:00
Dmitry Jemerov
254f766aaf Take longer read action in forEachKotlinOverride()
EA-114124 - assert: CompositeElement.getChildrenAsPsiElements
2017-12-29 10:19:50 +01:00
Dmitry Jemerov
768fce4722 Check for project disposed when reporting outdated libraries
EA-106858 - assert: ComponentManagerImpl.getPicoContainer
2017-12-29 10:19:50 +01:00
Dmitry Jemerov
cc2faa67f9 Don't pass null element to RefactoringFactory.createRename()
EA-114286 - IAE: RenameProcessor.$$$reportNull$$$
2017-12-29 10:19:50 +01:00
Dmitry Jemerov
9a156541c1 Don't try to read attribute for files with no ID
(EA-114351 - CCE: PersistentFSImpl.getFileId)
2017-12-29 10:19:50 +01:00
Toshiaki Kameyama
5e765c525e Do not suggest quickfix 'Specify type explicitly' with existing type
So #KT-15180 Fixed
2017-12-28 21:06:48 +03:00
Mikhail Glukhikh
5475f99cec Elvis -> if-then: handle case with safe cast separately #KT-17816 Fixed 2017-12-28 20:31:55 +03:00
Mikhail Glukhikh
ec60c92fe9 Lambda -> reference: build bound reference for complex qualified
So #KT-19073 Fixed
2017-12-28 20:31:53 +03:00
Mikhail Glukhikh
73bca21f94 Allow using add modifier quick-fixes in batch mode #KT-21950 Fixed 2017-12-28 20:31:47 +03:00
Mikhail Glukhikh
2e71691ab2 Fix potential leak in "unused lambda expression body" fix 2017-12-28 20:31:45 +03:00
Mikhail Glukhikh
8e23ca597d Add extra tests for KT-20429, simplify code a bit 2017-12-28 20:31:44 +03:00
Toshiaki Kameyama
a65304556c CFG: provide "used as expression" in enum constant constructor
This allows to avoid
"unused return value of a function with lambda expression body"
for such a situation
So #KT-20429 Fixed
2017-12-28 20:31:42 +03:00
Mikhail Glukhikh
e10fa218f5 Extend range of "use expression body" to left brace..end of return
Range is extended iff we are in DO_NOT_SHOW case,
otherwise just return is highlighted to avoid ugly highlighting
So #KT-19771 Fixed
2017-12-28 20:31:41 +03:00
Mikhail Glukhikh
95e7d29743 Minor: improve style in "operator to function" 2017-12-28 20:31:40 +03:00
Toshiaki Kameyama
52df70a576 Do not suggest replacing comparison to null with function call
So #KT-20620 Fixed
2017-12-28 20:31:38 +03:00
Mikhail Glukhikh
d7807b5ae3 Do not report "redundant Unit return type" on expression bodies
So #KT-21983 Fixed
2017-12-28 20:31:37 +03:00
Mikhail Glukhikh
232ec63121 Inline dialog: handle case with unknown occurrence number correctly
So #KT-21963 Fixed
2017-12-28 20:31:36 +03:00
Mikhail Glukhikh
947e853d9e Inline dialog: show "inline all and keep" for occurred once declarations
So #KT-21964 Fixed
2017-12-28 20:31:35 +03:00
Mikhail Glukhikh
d5bb7e457e Inline dialog: unify messages with each other #KT-21965 Fixed 2017-12-28 20:31:33 +03:00
Mikhail Glukhikh
3f00592443 Do not suggest "convert ref to lambda" for reflect types #KT-19283 Fixed 2017-12-28 20:31:27 +03:00
Mikhail Glukhikh
fc93e7a727 Do not report "redundant suspend" on override / open #KT-21938 Fixed 2017-12-28 20:31:24 +03:00
Sergey Igushkin
276a6acc3e Use .withDependencies { ... } to set up default versions with Gradle 4.4
+ Improve the test for omitted Kotlin module versions.

Issues: #KT-21806 Fixed, #KT-21203 Fixed
2017-12-28 19:47:02 +03:00
Vyacheslav Gerasimov
8b7a8f7bef Update changelog for 1.2.20 2017-12-28 16:15:54 +03:00
Dmitry Jemerov
fc51673c83 Update copyright profile 2017-12-28 10:47:43 +01:00
Ilya Chernikov
efc470df2b Reading KOTLIN_HOME only once
may fix #KT-21145, or at least make it less flaky
2017-12-28 09:43:44 +01:00
Ilya Chernikov
945da50b61 Add kotlin-compiler-client-embeddable to the plugin's lib since...
it's used in the `KotlinJsr223JvmScriptEngine4Idea`
Fixes #KT-18613
2017-12-28 09:43:43 +01:00
Vyacheslav Gerasimov
6116b5c497 Update coroutines version to 0.20 2017-12-28 00:35:15 +03:00
Ilya Gorbunov
042f81f23b Fix Volatile usages in common and JS code 2017-12-27 21:55:24 +03:00
Ilya Gorbunov
a33a3867b8 JS: Move declaration to match their packages in JVM and Common stdlib
Mostly internal, but also two public annotations
2017-12-27 21:55:24 +03:00
Ilya Gorbunov
d2eb8b4a3f Do not compile SynchronizedLazyImpl for platforms other than JVM 2017-12-27 21:55:24 +03:00
Ilya Gorbunov
b6595d661d Improve expect declarations in kotlin.text
- Replace overloads with default parameters in expect declarations by suppressing errors
- Remove meaningless inline modifier
2017-12-27 21:55:24 +03:00
Ilya Gorbunov
824b506abe Remove inheritance between LinkedHashSet/Map and HashSet/Map 2017-12-27 21:55:24 +03:00
Ilya Gorbunov
c5c6eed170 Make common ArrayList declaration not open and implementing RandomAccess 2017-12-27 21:55:24 +03:00
Ilya Gorbunov
fb13347864 Extract kotlin.collections expect classes into separate files
Add missing expect declarations for AbstractMutableMap/Set.
2017-12-27 21:55:24 +03:00
Ilya Gorbunov
93ef16deaf Move expect declarations to the appropriate packages
So that they match actual declarations in Kotlin/JVM stdlib.
2017-12-27 21:55:24 +03:00
Pavel V. Talanov
dd32c4e66a Revert minor semantic differences introduced in c030a047aa
Fix 'pull members up' and 'kotlin injected into kotlin' tests
2017-12-27 20:24:26 +03:00
Anton Bannykh
2df85ae4a9 kotlin-test-js: pass test function result to test framework (e.g. Promise) 2017-12-27 19:57:49 +03:00
Anton Bannykh
3e0d83b7d1 Make :js:npm a separate project to avoid calling update_dependencies 2017-12-27 17:35:34 +03:00
Alexander Udalov
129fad6ade Minor, merge two KotlinCoreEnvironment-creating functions 2017-12-27 14:50:04 +01:00
Alexander Udalov
613297ad60 Rename ModuleScriptData -> ModuleChunk and refactor related code
Use the term "build file" instead of the old "module"/"module script"
2017-12-27 14:50:03 +01:00
Alexander Udalov
f3f8db989a Fix test data for annotations on DefaultImpls members
After ea5505f80c, the annotations are now generated correctly
2017-12-27 14:12:14 +01:00
Chris Povirk
ac87ad422d Recognize Checker Framework declaration annotations.
We are migrating Guava to use these annotations rather than jsr305's
@Nullable. We can't use the Checker Framework's _@Nullable_ yet because
we promise compatibility with Java 7, which doesn't support type
annotations. This is related to but distinct from
https://youtrack.jetbrains.com/issue/KT-21408, which is about a
different jsr305 annotation we use, @ParametersAreNonnullByDefault.

I've also updated some docs to mention Kotlin's existing support for the
Checker Framework _@NonNull_.
2017-12-27 13:23:06 +01:00
Anton Bannykh
79359b7bc2 JS: test kotlin-test as box tests, support nested, fix mpp
Support tests inside nested classes and companion objects (KT-21850
fixed).
Don't launch multiplatform tests twice (KT-21567 fixed).
2017-12-27 15:22:26 +03:00
Nikolay Krasko
3bf8436895 Fix licence check after "jetbrains/kotlin/idea/copyright" package move 2017-12-27 13:44:55 +03:00
Nikolay Krasko
b7ff00ec34 Remove author tag from JavaSdkUtil to fix CodeConformanceTest 2017-12-27 13:27:59 +03:00
Nikolay Krasko
419abadcda Search for Kotlin sources in project too in fallback scope
When debugging in Gradle or Maven we may miss debug scope completely,
but still want to be responsible for building source positions for all
Kotlin source files (other PositionManagers may produce unexpected
results).
2017-12-27 01:09:53 +03:00
Ilya Gorbunov
f468990f97 Add racing version of each Lazy test
Run several concurrent accesses to a lazy value
many times and validate invariants.
2017-12-26 23:14:11 +03:00
Ilya Gorbunov
4827aadcfd Improve stability of lazy test, make some tests take less time 2017-12-26 23:14:09 +03:00
Ilya Gorbunov
934b3cc54e Do not read volatile _value field second time it is already initialized 2017-12-26 23:14:07 +03:00
Ilya Gorbunov
5d62277fa5 Make SafePublicationLazyImpl.initializer volatile
This establishes happens-before relation between nulling out the initializer and
checking whether it is null. This will prevent the subsequent _value reads
being reordered before the initializer reads.

#KT-21868 Fixed
2017-12-26 23:13:14 +03:00
Sergey Igushkin
685b138f79 (minor) Fix testAndroidExtensionsIncremental() ambiguous file operation 2017-12-26 21:38:15 +03:00
Sergey Igushkin
01931c2ae6 Fix Kotlin internal files created in 'build/' ignoring custom buildDir
Issue #KT-10537 Fixed
2017-12-26 21:38:15 +03:00
Ilya Chernikov
953a485fe7 Increment repl line generation on compilation error
fixes #KT-17921 and #KT-21141
Tests added to the JSR223 local eval example
2017-12-26 19:27:32 +01:00
Ilya Chernikov
2d8e73f3f6 Make JSR 223 examples compatible with embeddable compiler, strip ...
some dependencies.
Fixes #KT-17561 and related issues
Warning: API changed slightly
2017-12-26 19:27:31 +01:00
Sergey Igushkin
d51b17c1b2 Fix @OutputFile annotation on a String property outputFile. 2017-12-26 20:29:45 +03:00
Sergey Igushkin
9d1091cdaa Add java-gradle-plugin for kotlin-gradle-plugin tasks validation;
Make task properties validation fail on warnings; run it during IT
2017-12-26 20:29:45 +03:00
Sergey Igushkin
7031087a93 Mark Gradle task properties with input/output annotations. 2017-12-26 20:29:45 +03:00
Sergey Igushkin
d62ced3a82 Compile against gradleApi() 2017-12-26 20:29:45 +03:00
Mikhail Glukhikh
72ec55769b Improve wording for "change package" fix for source root case 2017-12-26 18:39:51 +03:00
Mikhail Glukhikh
429c31c010 Improve wording in some inspections 2017-12-26 18:39:51 +03:00
Mikhail Glukhikh
1534488dd1 Test minor: output all available fixes in local inspection tests 2017-12-26 18:39:51 +03:00
Mikhail Glukhikh
2f987f08fa Forbid word 'can' in local inspections with level > INFORMATION
Inspection texts were changed accordingly
2017-12-26 18:39:51 +03:00
Mikhail Glukhikh
56230420f8 AbstractApplicabilityBasedInspection: move visitor inside base class 2017-12-26 18:39:51 +03:00
Mikhail Glukhikh
3268189215 Cache intention inside IntentionBasedInspection
So intention is created only once.
Case with multiple intentions is no more allowed.
So #KT-21137 Fixed
2017-12-26 18:39:50 +03:00
Mikhail Glukhikh
5affb9a25c Refactoring: "package matching directory" is now an inspection 2017-12-26 18:39:50 +03:00
Mikhail Glukhikh
3f1a3dfeb2 Refactoring: make "loop to call chain" AbstractKotlinInspection 2017-12-26 18:39:50 +03:00
Mikhail Glukhikh
f44fba746e Refactoring: make "unnecessary variable" inspection applicability-based 2017-12-26 18:39:50 +03:00
Mikhail Glukhikh
221aac9820 J2K registerInspectionBasedProcessing: use correct target for applyTo 2017-12-26 18:39:50 +03:00
Mikhail Glukhikh
5a1a35bb35 Refactoring: "replace put with assignment" is now applicability-based 2017-12-26 18:39:49 +03:00
Mikhail Glukhikh
9e919829c8 Refactoring: "simplify assert not null" is now an inspection 2017-12-26 18:39:49 +03:00
Mikhail Glukhikh
8ebe16c9b2 Minor: reformat XML 2017-12-26 18:39:49 +03:00
Mikhail Glukhikh
bc361363d5 Refactoring: "simplify negated binary expression" is now an inspection 2017-12-26 18:39:49 +03:00
Mikhail Glukhikh
35d85ddd1f Refactoring: "replace with operator assignment" is now an inspection 2017-12-26 18:39:49 +03:00
Mikhail Glukhikh
c995f70631 J2K processing: simplify (minor) 2017-12-26 18:39:48 +03:00
Mikhail Glukhikh
6b5aeaa9a6 J2K inspection-based processing: use more accurate isApplicable
Information level is taken into account in both base and pre-fix
isApplicable calls
2017-12-26 18:39:48 +03:00
Mikhail Glukhikh
ada7287c66 Refactoring: make "replace call with binary operator" an inspection 2017-12-26 18:39:48 +03:00
Mikhail Glukhikh
6d4b5bc48f Refactoring: "introduce when subject" is now an inspection 2017-12-26 18:39:48 +03:00
Mikhail Glukhikh
a8b01a6b00 Refactoring: make "if-then to safe access" an inspection 2017-12-26 18:39:47 +03:00
Mikhail Glukhikh
91bcfb97c6 Refactoring: make "replace get or set" an inspection 2017-12-26 18:39:47 +03:00
Mikhail Glukhikh
756cb32eaf Refactoring: make "replace array equality ..." an inspection 2017-12-26 18:39:47 +03:00
Mikhail Glukhikh
33d94cd5e1 J2kPostProcessing: add inspection-based processing #KT-21635 Fixed 2017-12-26 18:39:46 +03:00
Mikhail Glukhikh
67b78bce39 Introduce AbstractApplicabilityBasedInspection
Related to KT-21635, KT-21137
2017-12-26 18:39:46 +03:00
Nikolay Krasko
bf393505a9 More nullability update in selectors for compatibility in 181 2017-12-26 17:37:38 +03:00
Nikolay Krasko
e66e8bcd07 Use platform types to prepare for nullability check in 181 2017-12-26 17:08:11 +03:00
Joscha Alisch
809cc220ed Select lambda after other args when it's outside argument list (KT-21214)
#KT-21214 Fixed
2017-12-26 13:09:17 +03:00
Nikolay Krasko
976a158ce1 Support alternative source popup for Kotlin files (KT-21958)
#KT-21958 Fixed
2017-12-26 12:49:27 +03:00
Nikolay Krasko
449fee74e8 Skip all same line locations when stepping over inline call (KT-20351)
#KT-20351
2017-12-26 12:46:45 +03:00
Nikolay Krasko
f39250c9a2 Fix irrelevant additional stops on breakpoint on line with inlines (KT-21945)
#KT-21945 Fixed
2017-12-26 12:46:45 +03:00
Nikolay Krasko
f38a4f509d Minor: code rearrange 2017-12-26 12:46:45 +03:00
Nikolay Krasko
c5886bc7a2 Remove sleep() from soSuspendableCallInEndOfFun and guarantee suspending 2017-12-26 12:46:45 +03:00
Ilya Gorbunov
10639eaf6a Add pattern and options properties to common Regex
And add a test that accesses them and checks they work as expected.
2017-12-26 05:40:37 +03:00
Ilya Gorbunov
d9edc5f221 Replace Regex constructor-like functions with secondary constructors
Historically secondary constructors were not supported in Kotlin/JS, so they had to
be emulated with constructor-like top level functions, now they can be rewritten
as true secondary constructors.

#KT-22003 Fixed
2017-12-26 05:40:35 +03:00
Ilya Gorbunov
053f3b6ac0 Tests: use helper function to assert compile-time and run-time type check
To cleanup warnings about useless cast or type check that is always true.
2017-12-26 04:55:44 +03:00
Ilya Gorbunov
ecd42f14b3 Compile common stdlib tests against common stdlib
Declare platform-specific test utilities as expect.
2017-12-26 04:55:40 +03:00
Pavel V. Talanov
c030a047aa Fix getting ModuleResolver by element for script files
Fixes EA-105435 (some isntances)
JavaResolveExtension: refactor API
2017-12-25 20:12:51 +03:00
Pavel V. Talanov
2af0bf4c71 Drop JsProjectDetector
It leads to undesired behaviour
    such as returning library source when only binaries are queried
It is redundant since js libraries do not include kotlin source files
    (real binary format is used for this purpose for along time now)
2017-12-25 20:12:48 +03:00
Pavel V. Talanov
6551ee5403 Test completion in script files
Test for 'JavaResolutionUtils.getJavaDescriptorResolver' failing with AE
Tests ebd3ac6dc8
See EA-105435
2017-12-25 20:12:46 +03:00
Sergey Igushkin
149b197b24 Fix unconditional warning in JS compilation with sourceMap disabled. 2017-12-25 15:30:01 +03:00
Sergey Igushkin
66d3c94193 Fix both moduleFile and destination passed to the compiler
when it is run not in daemon from Gradle; don't pass the destination in
such case.

Issue #KT-21637 Fixed
2017-12-25 15:29:34 +03:00
Sergey Igushkin
00d7150944 Fix warning check in tests:
* Fix the regex that could not actually find warnings
* Suppress an unused parameter warning in the test project
* Add allWarningsAsErrors to ExecutionStrategyIT
2017-12-25 15:28:33 +03:00
Sergey Igushkin
41086f26ae Fix duplicate classpath entry in JS Gradle compilation causing warnings
Issue #KT-21943 Fixed
2017-12-25 15:15:54 +03:00
Nikolay Krasko
93e7e9b28c Minor: regenerate tests 2017-12-22 17:06:12 +03:00
Alexey Tsvetkov
d7edbb8dfc Track changes in inline function when friend paths are disabled in JS 2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
a4d122478b Replace testCancelLongKotlinCompilation with less flaky test 2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
ee94a64718 Explicitly request rebuild when untracked java file is removed
Previously a rebuild was happenning because FileNotFoundException
was thrown when getting psiFile of removed file.
2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
61cb39a600 Include tests from incremental-compilation-impl in compiler tests 2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
50bf74b909 Turn off class redeclaration test for JS IC temporarily
So the tests could be run on TC.
Turn on after KT-19846 is fixed.
2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
5b646ba4fa Generate source maps in JS IC tests
#KT-21700 fixed
2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
0fee7883ed Recompile only files from last iteration after compile error 2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
3914c1b0e9 Allow to edit non-JPS build logs in "Show difference" window for non-JPS IC tests 2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
ff2e3ecfc4 Add JS specific IC build log in test
JS IC compares proto using a source file path as a key,
so moving file causes recompilation of its usages
unlike JVM IC that uses a class file path as a key.
2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
7712044146 Fix IC test build log diverged from JPS
JPS marks dirty direct usages of removed classes since 172.* before a build.
Generic IC also marks dirty all subclasses and their usages.
That is necessary because a method from a removed class could be used
through a subclass.
JPS and generic IC logs diverged in 172 branch, but non-JPS tests
were not run on CI.
2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
ad1978940b Recompile inline function usages in JS when offset is changed
Otherwise source maps would differ after rebuild
2017-12-22 16:12:20 +03:00
Alexey Tsvetkov
a31f503fa5 Recompile all subclasses of removed classes 2017-12-22 16:12:19 +03:00
Alexey Tsvetkov
e8162cd99d Unify processing of removed files for JS and JVM IC 2017-12-22 16:12:19 +03:00
Alexey Tsvetkov
d0ca0dca2b Avoid processing incremental changes after first build for JVM 2017-12-22 16:12:19 +03:00
Alexey Tsvetkov
91bb57c5a3 Make general IC logs similar to JPS IC logs 2017-12-22 16:12:19 +03:00
Alexey Tsvetkov
fec2d08d22 Compile actual and expected declarations together
#KT-20840 fixed
2017-12-22 16:12:19 +03:00
Alexey Tsvetkov
123fd64a34 Fix stdlib usages in IC tests
* Use stdlib from dist
* Check that stdlib exists
* Don't add stdlib for JS, because compiler adds one by default
(stdlib would be read twice which is slow)
2017-12-22 16:12:19 +03:00
Alexey Tsvetkov
e3a9ad5a74 Minor: remove unused variable 2017-12-22 16:12:19 +03:00
Alexey Tsvetkov
dfe176efca Avoid computing source files changes in IC for Gradle 2017-12-22 16:12:19 +03:00
Nikolay Krasko
5a8c0f8f42 Minor: fix compile error in test data 2017-12-22 15:27:11 +03:00
Toshiaki Kameyama
9fad40b586 KT-21928 Structure view doesn't show default constructor 2017-12-22 15:27:10 +03:00
Dmitry Jemerov
3178dee759 Insert line break before elvis when converting if to elvis
This ensures correct indentation
2017-12-22 10:35:23 +01:00
Dmitry Jemerov
6208c69c72 Add option for wrapping closing paren in multiline if conditions 2017-12-22 10:35:23 +01:00
Dmitry Jemerov
7711f8e3a7 Add predefined code style for Kotlin style guide 2017-12-22 10:35:23 +01:00
Dmitry Jemerov
d69382f129 Don't apply indent on Enter after modifier list
#KT-9562 Fixed
2017-12-22 10:35:23 +01:00
Dmitry Jemerov
43ef113b7a Correctly apply annotation wrap before modifier keyword
#KT-20314 Fixed
2017-12-22 10:35:22 +01:00
Dmitry Jemerov
fa19bd6d9b Apply indent of continuation call start to its children
#KT-15099 Fixed
2017-12-22 10:35:22 +01:00
Dmitry Jemerov
5652fa762f Force no line break after dot in chained calls
#KT-20362 Fixed
2017-12-22 10:35:22 +01:00
Dmitry Jemerov
06fa61bb6f Line breaks in objects and lambdas don't trigger call paren wrapping
#KT-19727 Fixed
2017-12-22 10:35:22 +01:00
Dmitry Jemerov
79a509df7b Option to apply normal indent to children of 'if' expressions 2017-12-22 10:35:21 +01:00
Dmitry Jemerov
640bf22e4f Refactoring: extract 'continuationIf' method 2017-12-22 10:35:21 +01:00
Dmitry Jemerov
44ee228ac9 Don't wrap parentheses in long argument list containing only object 2017-12-22 10:35:21 +01:00
Dmitry Jemerov
a2175c2ef5 KotlinFormattingModelBuilder: J2K 2017-12-22 10:35:21 +01:00
Dmitry Jemerov
57844968b0 KotlinFormattingModelBuilder: rename to .kt 2017-12-22 10:35:20 +01:00
Mikhael Bogdanov
ea5505f80c Generate annotations in proper order in DefaultImpls 2017-12-22 10:02:04 +01:00
Mikhael Bogdanov
c9d0ab38cf Generate proper java parameter names for DefaultImpls
#KT-21919 Fixed
2017-12-22 10:02:04 +01:00
Alexander Podkhalyuzin
12a8048bf7 Fixed exception reporting in Kotlin plugin and IDEA releases 2017-12-22 11:33:36 +03:00
Sergey Igushkin
a88206c5ea (minor) Fix platform-dependent line separators in source maps test 2017-12-21 20:49:58 +03:00
Ilya Gorbunov
94a0e508d9 Use empty array instead of presized for Collection.toArray
#KT-21918
2017-12-21 20:10:28 +03:00
Alexander Podkhalyuzin
8203d1c3fe Extracted Kotlin.JVM IDE into separate module
This change is required to have possibility to build plugin against
minor IDEs, which don't have Java. So we want to extract idea-jvm
2017-12-21 18:34:02 +03:00
Alexander Podkhalyuzin
2bb02beb84 Do not report exceptions/errors in very specific case
In IDEA special property can be used for that, Kotlin plugin should honor that
2017-12-21 18:34:00 +03:00
Alexander Podkhalyuzin
5e21dc5560 Removed non ASCII char to reduce pain in compilation. 2017-12-21 18:34:00 +03:00
Ilmir Usmanov
c8904b1c7c Replace POP with ARETURN if it pops Unit and ARETURN shall return Unit
#KT-16880: Fixed
2017-12-21 18:08:39 +03:00
Toshiaki Kameyama
2cdc246a27 Inspection to highlight usages of Collections.sort() and replace them with .sort() method from Kotlin stdlib
#KT-11023 Fixed
2017-12-21 15:05:48 +01:00
Alexey Sedunov
4ac870500f Minor: Fix test data 2017-12-21 16:01:29 +03:00
Emmanuel Duchastenier
a8ddf03b53 README: IntelliJ IDEA 2017.3 is not early access anymore
update README.md with direct download link to IntelliJ IDEA latest version
2017-12-21 13:51:24 +01:00
Nikolay Krasko
e6aeb66875 Sort files according to given scope in debugger (KT-21931)
#KT-21931 Fixed
2017-12-21 15:46:28 +03:00
Nikolay Krasko
7c73356893 Early exit from getSourcePosition() for non-kotlin source files 2017-12-21 15:46:28 +03:00
Mikhael Bogdanov
50608d0844 Don't delete nested default lambda classes during inline transformation 2017-12-21 12:52:29 +01:00
Mikhael Bogdanov
b65dcf27ee Provide test source mapping data for separate and non-separate compilation
Compilation in same module or in separate ones
2017-12-21 12:52:28 +01:00
Mikhael Bogdanov
f4f7c83eeb Copy nested objects of default lambda during inline 2017-12-21 12:52:28 +01:00
Mikhael Bogdanov
3513f1a86a Properly process default lambda source mapping
#KT-21827 Fixed
2017-12-21 12:52:27 +01:00
Nicolay Mitropolsky
657123f2c0 LightClassUtil.extractPropertyAccessors refactoring to fix KotlinShortNamesCacheTest.testGetMethodsByNameWithCustomPropertyAccessors test
After light classes caching the test started to fail.
 Also refer Simon Ogorodnik.
2017-12-21 12:25:51 +03:00
Sergey Igushkin
710c726c9a Improve kapt arguments & javac options usability with Kotlin DSL
Issue #KT-21596 Fixed
2017-12-20 20:49:30 +03:00
Toshiaki Kameyama
411feab9ae KT-21698 Create interface shouldn't suggest to declare it inside a class which implements it 2017-12-20 18:14:55 +01:00
Vyacheslav Gerasimov
1deed28464 Add missing changelog for [1.2.20 - 1.1.60] versions 2017-12-20 19:10:26 +03:00
Pavel V. Talanov
aec893180e Minor, JvmAnalyzerFacade: drop logging
Prevent log spam
2017-12-20 17:19:09 +03:00
Dmitry Jemerov
78a87ac0cf Regenerate test 2017-12-20 15:03:25 +01:00
Mikhail Glukhikh
484bf0115f Fix "fake JVM field" inspection test XML 2017-12-20 16:31:10 +03:00
Kirill
7842fa4796 Support callable references in "implicit this" inspection
Second part of #KT-21510
2017-12-20 14:16:39 +03:00
Kirill
74e5a9425a Support callable references in "explicit this" inspection
So #KT-21510 Fixed
2017-12-20 14:16:33 +03:00
Dmitry Jemerov
d3adf57145 Don't apply highlighting to zero-length elements
#KT-19820 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
52ccfcecfc Fix highlighting of TODO calls in lambdas
#KT-19915 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
0159d19539 Apply rainbow highlighting in anonymous initializers
#KT-18839 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
94a7673c2d Don't show type hints for destructuring declarations with explicit type
#KT-21833 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
b0b69b2ad0 Put argument name hint before spread element
#KT-21645 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
c336159b2b Don't show argument name hints for dynamic calls.
Mark function descriptors created for dynamic calls as having
synthesized parameter names.

 #KT-21275 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
3e7e01dc4d Add mapOf() to default parameter name hints blacklist
#KT-18829 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
fd7aaa1579 Add single-arg 'assert' method to parameter name hints blacklist
#KT-17965 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
cf6b71aa05 Don't show type hint for local variable initialized with object
#KT-17964 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
77c186442a Don't show parameter name hints when calling Java methods with unknown
parameter names

 #KT-17843 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
6d63dd9d83 Enable "Configure Kotlin plugin updates" with no open project
#KT-20380 Fixed
2017-12-20 12:02:04 +01:00
Dmitry Jemerov
1a9d2ab4ee Fix name of inspection description file 2017-12-20 11:56:04 +01:00
kenji tomita
3cd4d90bf8 Use BodyResolveMode.PARTIAL and ProblemHighlightType.GENERIC_ERROR_OR_WARNING 2017-12-20 11:56:04 +01:00
kenji tomita
37351c344f code style inspection: to -> Pair function used not in infix form 2017-12-20 11:56:04 +01:00
Mikhail Glukhikh
41739602bc Inline handler: fix reference detection for properties 2017-12-20 13:54:36 +03:00
Mikhail Glukhikh
ce441e2163 Extract common class from two KotlinInline<...>Dialogs #KT-17212 Fixed 2017-12-20 13:54:30 +03:00
Mikhael Bogdanov
3e1f471121 Rollback change in 'usesDefaultArguments' 2017-12-20 10:58:35 +01:00
Mikhael Bogdanov
32b90a1cae Generate type checker barriers in bridges 2017-12-20 10:48:52 +01:00
Mikhael Bogdanov
be18cb9b16 Fix default methods visibility 2017-12-20 10:48:51 +01:00
Mikhael Bogdanov
9365d1d859 Remove redundant extra default mask for function with N*32 parameters 2017-12-20 10:48:51 +01:00
Mikhael Bogdanov
ef5c3512cd Skip FAKE_OVERRIDE fields 2017-12-20 10:48:50 +01:00
Mikhael Bogdanov
aeb74f7e70 Skip bridge generation for non real declaration on first step they would be processed later
~

~
2017-12-20 10:48:50 +01:00
Mikhael Bogdanov
4657ae06f4 Don't cast receiver to super type on super calls 2017-12-20 10:48:49 +01:00
Mikhael Bogdanov
a936f75423 Fix empty vararg processing in intrinsics 2017-12-20 10:48:49 +01:00
Mikhael Bogdanov
420b9fdaa9 Support interface companion object lowering 2017-12-20 10:48:48 +01:00
Mikhael Bogdanov
24336113a2 Support class companion object lowering 2017-12-20 10:48:48 +01:00
Mikhael Bogdanov
224adfabc5 Support synthetic accessors for constructors 2017-12-20 10:48:47 +01:00
Mikhael Bogdanov
5cbfdf6024 SyntheticAccessorLowering refactoring 2017-12-20 10:48:47 +01:00
Mikhael Bogdanov
7da847e943 Fix coercion after call 2017-12-20 10:48:46 +01:00
Mikhael Bogdanov
4df0a1bb1f Fix parameter indices on lowering 2017-12-20 10:48:46 +01:00
Mikhael Bogdanov
0729566458 Support javaClass for Void type 2017-12-20 10:48:45 +01:00
Mikhael Bogdanov
f7968e1b61 Fix inner class lowering: don't try to process nested classes on processing outer 2017-12-20 10:48:45 +01:00
Mikhael Bogdanov
dde0535c5a Fix cast for IMPLICIT_NOTNULL 2017-12-20 10:48:44 +01:00
Mikhael Bogdanov
05b56b0c4a Update ArrayConstructor to support inline 2017-12-20 10:48:44 +01:00
Mikhael Bogdanov
665a697093 Support simple function inlining in ir 2017-12-20 10:48:43 +01:00
Mikhael Bogdanov
54dc828c8e Rename ExpressionLambda to PsiExpressionLambda 2017-12-20 10:48:43 +01:00
Mikhael Bogdanov
0e2bd46124 Remove cycle check and resolvedCall from 'preformInline' method 2017-12-20 10:48:42 +01:00
Mikhael Bogdanov
4711e2f9da Don't use kind for static check
Lowers should perform proper transformations
2017-12-20 10:48:42 +01:00
Mikhael Bogdanov
3432014971 Add 'generateModule' method to CodegenFactory 2017-12-20 10:48:41 +01:00
Mikhael Bogdanov
06fd996266 Switch LocalFunctionLowering to LocalDeclarationLowering 2017-12-20 10:48:41 +01:00
Mikhael Bogdanov
1f053be289 Support default function lowering 2017-12-20 10:48:40 +01:00
Mikhael Bogdanov
83710a8ed6 HACK: process unbound symbols 2017-12-20 10:48:40 +01:00
Mikhael Bogdanov
5032064bf0 Enable tailrec lower 2017-12-20 10:48:39 +01:00
Mikhael Bogdanov
84e960b3a4 Enable lateinit lowering 2017-12-20 10:48:39 +01:00
Mikhael Bogdanov
039e036e22 Support IrExpressionBody in codegen 2017-12-20 10:48:38 +01:00
Mikhael Bogdanov
4017195ff1 Always include stdlib in IrTests 2017-12-20 10:48:38 +01:00
Mikhael Bogdanov
e16bdd4287 Switch JvmBackendContext to CommonBackendContext
(cherry picked from commit 5d4736c)
2017-12-20 10:48:37 +01:00
Nikolay Krasko
f963b8bd42 Fix QuickFixTestGenerated$DeprecatedSymbolUsage$TypeAliases
Revert asking super isAvailable in DeprecatedSymbolUsageInWholeProjectFix
2017-12-20 12:27:36 +03:00
Nikolay Krasko
b80403cf13 Consistency for replace string quick fix message
https://youtrack.jetbrains.com/issue/KT-21746#comment=27-2634335
2017-12-20 12:27:36 +03:00
Vyacheslav Gerasimov
95cc3fe1b7 Fix availability of AddFunctionParametersFix
fixes RenameTestGenerated.testAutomaticVariableRenamerWithQuotation_AutomaticVariableRenamerWithQuotation
2017-12-19 21:23:38 +03:00
Nicolay Mitropolsky
bb4d6d1059 LightClassEqualsTest fix by creating lightclasses with createNoCache 2017-12-19 20:03:59 +03:00
Nicolay Mitropolsky
4c5cf0f7e7 *kapt3-idea* added to test-dependencies in *uast-kotlin* 2017-12-19 18:22:14 +03:00
Mikhael Bogdanov
ef433d163e Apply common header directives to second file in AbstractCompileKotlinAgainstKotlinTest 2017-12-19 16:11:39 +01:00
Mikhael Bogdanov
819a3a95b3 Add support for contract feature in inliner 2017-12-19 16:11:39 +01:00
Pavel V. Talanov
4890979476 ScriptDefinitionsManager: ignore reloadDefinitionsBy calls
If definitions are not loaded yet
2017-12-19 17:15:39 +03:00
Pavel V. Talanov
106f571814 scriptTemplatesFromCompilerSettings: fix ScriptDefinitionsManager access
#KT-21545 Fixed
2017-12-19 17:15:36 +03:00
Mikhail Glukhikh
4bff0fb338 Unused symbol: revert entry point check optimization to fix regression
E.g. JUnit 3 tests was highlighted as unused after it
2017-12-19 15:59:30 +03:00
Mikhail Zarechenskiy
9eca8cd451 [NI] Fix hierarchy of resolution atoms for lambda with non-local return 2017-12-19 15:11:04 +03:00
Mikhail Zarechenskiy
c6d8b39b4f [NI] Prioritize type variables related to output type for fixation 2017-12-19 15:11:04 +03:00
Mikhail Zarechenskiy
d818af5287 [NI] Don't forget to analyze whole block for last postponed expression 2017-12-19 15:11:03 +03:00
Anton Bannykh
8ed8e05a68 JS: honor ignoreTestFailures flag and report failures to TC (KT-20735
fixed)
2017-12-19 14:38:15 +03:00
Alexey Sedunov
0ab924a298 Change Signature: Fix overrider search for suspend functions
#KT-21288 Fixed
2017-12-19 13:47:02 +03:00
Alexey Sedunov
b5bd5942e7 Kotlin Facet: Do not auto-advance version in imported projects
#KT-21879 Fixed
2017-12-19 13:47:02 +03:00
Alexey Sedunov
88540360b4 Misc: Fix NPE on external project import 2017-12-19 13:47:02 +03:00
Nicolay Mitropolsky
4a6cc3913d Fix for "safe delete" after caching added to light elements 2017-12-19 13:32:23 +03:00
Alexey Tsvetkov
18fae9e16d Allow override removing temporary module files after build
For debug purposes
2017-12-18 21:19:15 +03:00
Alexey Tsvetkov
5bffef6de7 Allow customizing directory for temporary module files 2017-12-18 21:19:15 +03:00
Alexey Tsvetkov
37b00b91fc Avoid generating too long path for temp module file
#KT-21841 fixed
2017-12-18 21:19:15 +03:00
Toshiaki Kameyama
a4fbe95112 KT-21770 Pasting into an interpolated string shouldn't escape $ 2017-12-18 18:25:43 +01:00
Toshiaki Kameyama
eb25ac44e6 KT-17928 Support code folding for primary constructors 2017-12-18 18:14:27 +01:00
Dmitry Jemerov
18cb9593c8 Add 'reformat' flag to DeprecatedSymbolUsageFixBase 2017-12-18 18:10:36 +01:00
Dmitry Jemerov
48021ce5a1 Disallow formatting in KotlinQuickFix.isAvailable() 2017-12-18 18:10:34 +01:00
Dmitry Jemerov
64f01e53af Check that add() method is in fact MutableCollection.add()
#KT-18881 Fixed
2017-12-18 18:10:33 +01:00
Dmitry Jemerov
94b8614fb8 Don't suggest mapTo() transformation over range literals
#KT-18816 Fixed
2017-12-18 18:10:32 +01:00
Dmitry Jemerov
09d27ca61c Don't generate .forEach { return } when converting loop to call chain
#KT-17161 Fixed
2017-12-18 18:10:31 +01:00
Dmitry Jemerov
b775b901cc Fix incorrect replacement with 'any' instead of 'all'
#KT-17730 Fixed
2017-12-18 18:10:24 +01:00
Dmitry Jemerov
ba4cf4dcc6 Delete unused class 2017-12-18 18:10:21 +01:00
Dmitry Jemerov
d0a8dd7dc8 Update EAP channel names in plugin update check dialog 2017-12-18 18:10:14 +01:00
Ilya Chernikov
3e2003e60d Do not log daemon connection errors as exceptions - may reduce number of ...
redundant report if the problem is corrected on retry

(cherry picked from commit 260fe36)
2017-12-18 17:08:15 +01:00
Ilya Chernikov
f83dc0a067 Make daemon session retrieval more robust to the daemon failures 2017-12-18 16:49:53 +01:00
Ilya Chernikov
1101bb7fb4 Treat "daemon is dying" state as a case for fallback compilation strategy in jps 2017-12-18 16:49:52 +01:00
Ilya Chernikov
6e34f57acf Retry socket connection on connection errors, number of retries and...
retry interval are configurable via the system props
2017-12-18 16:49:51 +01:00
Ilya Chernikov
1cd14f00eb Ignore connection error on the (optional) daemon.clearJarCache call
May fix issues with NoSuchObjectException and UnmarshalException - the
stacktraces often point to this place
2017-12-18 16:49:50 +01:00
Mikhail Glukhikh
0d64ab4846 Fix corner cases (override/script/null/etc.) in "might be const"
Related to KT-20644
2017-12-18 17:23:41 +03:00
Alexey Tsvetkov
3f082346ae Do not set api version to language version when language version is null
#KT-21852 fixed
    #KT-21574 fixed
2017-12-18 16:22:07 +03:00
Dmitry Petrov
17b4d4a973 Differentiate accessors by FieldAccessorKind
Otherwise accessors for backing fields (as in '{ field }') clash with
accessors for properties (as in '{ prop }').

 #KT-21258 Fixed Target versions 1.2.30
2017-12-18 16:15:52 +03:00
Ilya Gorbunov
d8cd926a8c Do not leak primitiveness of an array wrapped with asList
A primitive array wrapped in a List with asList had incorrect implementation of toArray method:
while it declares that an object array is returned, it returned a primitive array.
Therefore the methods such as `Collection.toTypedArray()` and its dependents
`ArrayList(collection)`, `Collection + Iterable` might behave incorrectly
having relied on `toTypedArray` returned an object array.

#KT-21828 Fixed
2017-12-18 15:50:15 +03:00
Sergey Igushkin
c55f08a166 Optimize embeddable JARs
Exclude the compiler dummy JAR from the resulting shadow JAR
2017-12-18 15:46:23 +03:00
Alexander Udalov
3a807cb39b Support Void.TYPE as underlying Class object for KClass
#KT-20875 Fixed
2017-12-18 11:57:05 +01:00
Anton Bannykh
46a631a654 Ignore license in the downloaded node_modules and nodejs 2017-12-18 13:46:25 +03:00
Yan Zhulanow
1692d1a087 Kapt: Add missing 'flush()', otherwise the serialized data can be empty 2017-12-18 18:57:38 +09:00
Nikolay Krasko
f67eb90dfb Don't show file root if it's same as the only declaration (KT-21200)
#KT-21200 Fixed
2017-12-18 11:50:50 +03:00
Nikolay Krasko
a3028beca9 Fix smart step into to Kotlin SAM adapter (KT-21538)
#KT-21538 Fixed
2017-12-18 11:50:49 +03:00
Denis Zharkov
adfee2086a Update bootstrap to 1.2.20-dev-814 2017-12-16 18:56:26 +03:00
Yan Zhulanow
d4be55df0e Kapt, Minor: Fix empty option parsing 2017-12-16 02:17:24 +09:00
Simon Ogorodnik
7c5897c1ab Skip deprecated for org.junit package in kotlin.test 2017-12-15 20:09:51 +03:00
Simon Ogorodnik
c2e706db6c Enable generation of docs for deprecated declarations 2017-12-15 20:09:49 +03:00
Simon Ogorodnik
c5c52dbda5 Fix annotations docs for kotlin.test 2017-12-15 20:09:48 +03:00
Simon Ogorodnik
430aad3651 Set LV = 1.2 in Dokka for generating stdlib docs 2017-12-15 20:09:47 +03:00
Simon Ogorodnik
3c78156f0f Suppress kotlin.reflect.jvm.internal 2017-12-15 20:09:46 +03:00
Simon Ogorodnik
fb3cf212ce Suppress docs for org.junit.Test header in kotlin.test 2017-12-15 20:09:45 +03:00
Simon Ogorodnik
99951db7e3 Add module docs for kotlin.test 2017-12-15 20:09:44 +03:00
Simon Ogorodnik
978a7fdfaa Add stdlib to kotlin.test docs classpath 2017-12-15 20:09:43 +03:00
Simon Ogorodnik
773fca5245 Use correct task to build builtins.jar 2017-12-15 20:09:42 +03:00
Simon Ogorodnik
640ce213cf Compile stdlib builtins ant pass it to Dokka
We need builtins to allow linking to type-aliased classes
such as Exception
2017-12-15 20:09:41 +03:00
Simon Ogorodnik
697b358293 Make local dokka run easier 2017-12-15 20:09:40 +03:00
Simon Ogorodnik
9ab48d8374 Suppress whole org.w3c 2017-12-15 20:09:38 +03:00
Simon Ogorodnik
99af2372c3 Suppress undocumented warnings for third-party js packages 2017-12-15 20:09:37 +03:00
Simon Ogorodnik
17106d6546 Use makeurl to create package-list URL in ant 2017-12-15 20:09:36 +03:00
Ilya Gorbunov
cc139856c8 List all source folders instead of project folder 2017-12-15 20:09:34 +03:00
Ilya Gorbunov
9b1867ce64 Docs: run gradle project and wrapper from the root dir
Build docs for kotlin-stdlib-jdk7/8 instead of jre7/8.
2017-12-15 20:09:33 +03:00
Simon Ogorodnik
a19e229a72 Minor: prepare for documentation generation 2017-12-15 20:09:32 +03:00
Ilya Chernikov
775eeb75c9 Treat daemon startup timeout/error exceptions the same way as RMI errors
will result on regular retry cycle on them, hopefully eliminating or
reducing appropriate exception reports
2017-12-15 15:24:38 +01:00
Mikhail Glukhikh
ea5a52f918 Restrict search scope in some inspections to avoid testData search
Affected inspections: can be private, can be parameter, unused symbol.
Related to KT-21756. May fix EA-113712.
2017-12-15 17:07:37 +03:00
Mikhail Glukhikh
2b5bbf0fdd Fix tests for "may be constant" inspection 2017-12-15 17:07:35 +03:00
Sergey Igushkin
3b4f82c9b9 Advance Gradle version -> 4.4
(cherry picked from commit 2fc7628)
2017-12-15 16:59:37 +03:00
Nikolay Krasko
6456f4ed98 Test step into for Java constructor with SAM conversion
Additional test for KT-21538

 #KT-21538 Fixed
2017-12-15 16:14:50 +03:00
Nikolay Krasko
d6cface66f Make isFromJava check work for SAM adapter extension descriptors (KT-21538)
Consider all callable descriptor in JavaClassDescriptor to be from Java.

This is used to check if smart step into should be intercepted by Kotlin
handler or delegated to Java.

 #KT-21538 Fixed
2017-12-15 16:14:50 +03:00
Nikolay Krasko
26413acf33 Refactoring: introduce method for reuse file for single class logic 2017-12-15 16:14:50 +03:00
Nikolay Krasko
5c33e4a32d Minor: remove warnings in KotlinStructureViewFactory 2017-12-15 16:14:49 +03:00
Nikolay Krasko
c79386594d Don't show useless fold icon in structure view (KT-17254, KT-21200)
#KT-21200 In Progress
 #KT-17254 Fixed
2017-12-15 16:14:49 +03:00
Nikolay Krasko
1688f6fdbd Minor: inline method in KotlinStructureViewElement and rewrite with when 2017-12-15 16:14:49 +03:00
Nikolay Krasko
7bf071b69f Precount 'isPublic' property if descriptor available 2017-12-15 16:14:49 +03:00
Nikolay Krasko
c28a7d8f6d Fix structure view auto-update (KT-21733, KT-19519)
- Fixed by subclassing PsiTreeElementBase instead of StructureViewTreeElement
- Warnings cleanup

 #KT-19519 Fixed
 #KT-21733 Fixed
2017-12-15 16:14:48 +03:00
Nikolay Krasko
b133189309 Rename: MyFunctionDescriptor -> SamAdapterExtensionFunctionDescriptorImpl 2017-12-15 16:14:48 +03:00
Toshiaki Kameyama
d719d06020 Don't suggest "convert to array literal" for *arrayOf #KT-21726 Fixed 2017-12-15 15:01:22 +03:00
Anton Bannykh
f68d639c63 Add @Target's to kotlin.test annotations 2017-12-15 14:14:00 +03:00
Toshiaki Kameyama
5680405531 "Redundant spread operator" inspection: support array literal
So #KT-21727 Fixed
2017-12-15 13:50:53 +03:00
Mikhail Glukhikh
df4bf73033 Convert lambda to reference: minor cleanup 2017-12-15 13:37:00 +03:00
Toshiaki Kameyama
0071ca64c7 Convert lambda to reference produces: fix case with qualified this
So #KT-19977 Fixed
2017-12-15 13:36:32 +03:00
Mikhail Glukhikh
50dc9a14a6 May be constant: fix corner case with getter & initializer 2017-12-15 13:31:49 +03:00
Mikhail Glukhikh
7358980cbc Add inspection to detect non-const vals used as Java annotation args
So #KT-20615 Fixed
2017-12-15 13:31:41 +03:00
Mikhail Glukhikh
70b7e5eb68 Introduce inspection to detect vals might be marked as const
So #KT-20644 Fixed
2017-12-15 13:05:50 +03:00
Yan Zhulanow
4ec20ad595 Minor: Fix build, remove inline function usage 2017-12-15 17:39:17 +09:00
Nicolay Mitropolsky
da98b7e07b Uast: type-mapper checks deeper for local classes (KT-21546, EA-100195) 2017-12-15 09:16:46 +03:00
Yan Zhulanow
f9813e3276 Kapt, Minor: Add kapt-runtime to sources for kotlin-annotation-processing-maven 2017-12-15 02:35:17 +09:00
Yan Zhulanow
187182e46f Noarg, Minor: Include IDEA 'testRuntime' dependency as in other compiler plugins 2017-12-15 02:35:16 +09:00
Yan Zhulanow
db4c441573 Kapt, Maven: Fix path for kapt3 compiler plugin sources 2017-12-15 02:35:16 +09:00
Yan Zhulanow
4d067ab9ce Kapt, Maven: Support passing javac/annotation processor options (KT-21565, KT-21566) 2017-12-15 02:35:15 +09:00
Yan Zhulanow
1af93b8342 Kapt: Consider all 'kapt' configuration dependencies as KaptTask dependencies. 2017-12-15 02:35:14 +09:00
Yan Zhulanow
6941065e2c Fix EA-1005833: Try to find a field using also the receiver type (KT-21820) 2017-12-15 02:35:13 +09:00
Yan Zhulanow
d58665b5a8 Kapt: Remove duplicating check, this also removes the senseless warning (KT-21425) 2017-12-15 02:35:12 +09:00
Yan Zhulanow
4c96453a4b Kapt: Annotations on enum constants are not kept on the generated stub (KT-21433) 2017-12-15 02:35:12 +09:00
Yan Zhulanow
c6f922fb64 EA-110813: Resolve the parent directory safely 2017-12-15 02:08:03 +09:00
Yan Zhulanow
e5a2be4f3c EA-96041: Make error message more user-friendly 2017-12-15 02:08:00 +09:00
Denis Zharkov
fa6285d32a Fix NPE in JavaNullabilityChecker when checking equals-calls
This NPE was introduced in ce41b5745a
Prior to the latter change there was a synthetic PSI element for each
equals-related call, thus callOperationNode was not null here.

== are intentionally treated as safe calls, but for nullability checker
it's not relevant, it only should report warnings on real safe-calls
2017-12-14 19:15:41 +03:00
Denis Zharkov
d64e8e3b33 Revert "Update bootstrap to 1.2.20-dev-732"
This reverts commit f7ccc4144c.
2017-12-14 19:15:41 +03:00
Nicolay Mitropolsky
6ac345df51 Caching KtLightClassForSourceDeclaration (KT-21701)
to make their UserData survive for longer, because otherwise a new LightClass with empty UserData comes to Spring every time, but Spring stores a lot of important things in UserData
2017-12-14 18:05:47 +03:00
Anton Bannykh
6bee5699a0 Migrate node_utils.xml to Gradle 2017-12-14 17:41:20 +03:00
Dmitry Jemerov
40184f053e Don't invoke formatter while checking availability of intentions
#KT-21632 Fixed
2017-12-14 12:02:39 +01:00
Dmitry Jemerov
54d626fe7d Change vendor to JetBrains to always enable exception reporting
#KT-17838 Fixed
2017-12-14 12:02:39 +01:00
Dmitry Jemerov
ba21bae653 Get rid of forced index rebuild on version change
#KT-17367 Fixed
2017-12-14 12:02:39 +01:00
Denis Vnukov
52ccd67ec1 Remove duplicate parameter null checks in JvmStatic delegate methods.
Remove unnecessary non-null parameter checks inside static delegate methods
created for @JvmStatic companion object methods. Allows function generation
strategy decide if such checks need to be injected.

 #KT-7188 Fixed
2017-12-14 13:48:50 +03:00
Alexander Udalov
9e82ab38f0 Fix lookup tracker tests after 2be7116b0b
Standard library is no longer automatically added to the classpath when
-Xbuild-file is used. Before 2be7116b0b, these tests worked because no
matter whether -Xbuild-file was used or not, the automatically computed
classpath (which erroneously was used to populate content roots in the
compiler) contained the standard library (see
K2JVMCompiler.configureContentRoots)
2017-12-14 11:37:56 +01:00
Alexander Udalov
46fa5cfae0 Add dependency on compiler dist from jps-tests
Otherwise, because there's no explicit dependency and the JPS plugin
loads the compiler from dist, the compiler jar is not rebuilt between
changes in compiler code and running jps-tests
2017-12-14 11:37:56 +01:00
Yan Zhulanow
5116f598df Kapt: Fix error message when no annotation processors were found (KT-21729)
Error message says "androidProcessor", it should be "annotationProcessor"
2017-12-14 19:28:51 +09:00
Denis Zharkov
f7ccc4144c Update bootstrap to 1.2.20-dev-732 2017-12-14 11:11:23 +03:00
Dmitry Petrov
1aab4e643c Add overflow-related tests for 'reversed' 2017-12-14 10:41:51 +03:00
Dmitry Petrov
65b5cdbb8d Maintain bounds evaluation order in intrinsics for 'reversed'
Makes sense for 'rangeTo', 'downTo', and 'until' with non-const bounds.
2017-12-14 10:41:51 +03:00
Dmitry Petrov
9fa9a8748b Check that qualified const expressions are recognized properly in 'for' 2017-12-14 10:41:51 +03:00
Dmitry Petrov
bf97b332cf Support const-bounded for loop generation for reversed 'until' 2017-12-14 10:41:51 +03:00
Dmitry Petrov
54cceac99b Intrinsics for 'reversed': until 2017-12-14 10:41:51 +03:00
Dmitry Petrov
5f7460a8c7 Support const-bound counter loop generation for 'downTo' 2017-12-14 10:41:51 +03:00
Dmitry Petrov
2f0df832c0 Minor: pull up helper methods for const-bounded for-in-range generation 2017-12-14 10:41:51 +03:00
Dmitry Petrov
a4c29b3587 Support Long and Char in const-bounded counter loop generation
If the loop end value is a compile-time constant (best we can do now),
and it is safe to iterate over a given range using "naive" for loop
(using '<=' or '>=' in loop condition),
generate such loops for Longs and Chars as well Ints (Bytes, Shorts).
2017-12-14 10:41:51 +03:00
Dmitry Petrov
df2b8d01d8 Extract common code in PrimitiveNumberRangeLiteralRangeValue 2017-12-14 10:41:51 +03:00
Dmitry Petrov
455a1c0f53 Intrinsics for 'reversed': downTo
#KT-21323 In Progress
2017-12-14 10:41:51 +03:00
Dmitry Petrov
64ba811b7f Intrinsics for 'reversed': CharSequence.indices
#KT-21323 In Progress
2017-12-14 10:41:51 +03:00
Dmitry Petrov
7ba73c1635 Intrinsics for 'reversed': collection.indices
#KT-21323 In Progress
2017-12-14 10:41:51 +03:00
Dmitry Petrov
5bcbe25469 Intrinsics for 'reversed': array.indices
#KT-21323 In Progress
2017-12-14 10:41:51 +03:00
Dmitry Petrov
beff4a1b92 Intrinsics for 'reversed': support non-literal range expressions
#KT-21323 In Progress
2017-12-14 10:41:51 +03:00
Dmitry Petrov
1493805f8e Take into account step sign in pre-condition for simple progression
So far, all non-end-inclusive progressions had step > 0.
With intrinsics for 'reversed' this will change.
2017-12-14 10:41:51 +03:00
Dmitry Petrov
821843e13f Intrinsics for 'reversed': generate in-const-bound ranges as countable
#KT-21323 In Progress
2017-12-14 10:41:51 +03:00
Dmitry Petrov
1775f294f4 Intrinsics for 'reversed': infrastructure & primitive range support
#KT-21323 In Progress
2017-12-14 10:41:51 +03:00
Mikhail Glukhikh
83ae34bb29 Fix leak in matchAndConvert (loopToCallChain) 2017-12-14 10:38:28 +03:00
Ilya Gorbunov
479f293edc Expose internal getProgressionLastElement to public api
To be used in compiler loop optimizations.
#KT-18869 Fixed
2017-12-14 07:22:08 +03:00
Ilya Chernikov
c453ff01cd Increase daemon socket queue size, make it controllable via system prop
Hopefully fixes #KT-15562
Also some minor refactoring
2017-12-13 17:34:13 +01:00
Ilya Chernikov
8f42aa1eda Improve parallel daemon start test:
- move asserts to the end to collect all diagnostics before it
  - disable compilation by default for better testing the startup logic
  - minor refactorings
2017-12-13 17:34:12 +01:00
Alexander Udalov
c5c4c9cfcc Support "-module-name" argument for common code compiler
#KT-20892 Fixed
2017-12-13 11:49:58 +01:00
Alexander Udalov
3ede503042 Minor, remove empty K2JSCompilerArguments.java 2017-12-13 11:49:58 +01:00
Alexander Udalov
cc9ebb26de Minor, improve "-module-name" argument description 2017-12-13 11:49:58 +01:00
Alexander Udalov
dc23a53116 Enumerate module roots directly in ModuleHighlightUtil2.getModuleDescriptor
This is faster than going through FilenameIndex which would call
GlobalSearchScope.accept for all "module-info.java" files in the
project, and there can be many of those.

Also see https://github.com/JetBrains/intellij-community/pull/670
2017-12-13 11:49:51 +01:00
Alexey Sedunov
38d3362bcb Configuration: Support selection of "Latest stable" version vs specific one
#KT-21229 Fixed
2017-12-12 20:48:26 +03:00
Mikhail Glukhikh
5252cd4da4 Lift return or assignment: use register...WithoutOfflineInformation 2017-12-12 19:47:52 +03:00
Mikhail Glukhikh
a375500a33 Spelling: MemberVisibilityCanPrivate > MemberVisibilityCanBePrivate 2017-12-12 19:47:46 +03:00
Dmitry Jemerov
db8147bd79 Regenerate test 2017-12-12 17:13:35 +01:00
Denis Zharkov
e24e711208 Avoid rebuilds after changes of layouts xml-files
This commit makes IC react more granularly on these changes
Precisely, it marks dirty only kt-files that having lookups into
synthetic package built upon a changed layout-file

 #KT-21622 Fixed
2017-12-12 16:17:58 +03:00
Denis Zharkov
58123f2103 Enable kotlin.incremental.usePreciseJavaTracking in gradle.properties 2017-12-12 16:17:58 +03:00
Denis Zharkov
a079b92ea0 Add property for precise version of Java tracking in Gradle IC
The flag name is kotlin.incremental.usePreciseJavaTracking
By default precise version is disabled

 #KT-17621 Fixed
2017-12-12 16:17:58 +03:00
Denis Zharkov
a978c6be35 Fix precise Java IC for multi-module projects
The problem may happen in case of multi-module projects:
If a Java class was effectively unused in one module (A),
but it's used in kt-files from the dependent module (B) then
we wouldn't track the changes of the class while compiling A
and don't recompile its usages in B.

It happens because now we track only Java classes that were
resolved by out frontend instead of all classes in the module
that would be more correct but it might be rather slow.

The idea is that whenever we see change in an untracked Java file
we start tracking the classes in it and for the first time we mark
all its content as changed.
2017-12-12 16:17:58 +03:00
Denis Zharkov
d9cfdf2f63 Add assertion to JavaClassesTrackerImpl::onCompletedAnalysis 2017-12-12 16:17:58 +03:00
Denis Zharkov
8dd5c2f895 Avoid serlialization for unrelated Java source-based classes
There is no need to track unknown (not being tracked before)
classes content of which we didn't request

 #KT-17621 Fixed
2017-12-12 16:17:58 +03:00
Denis Zharkov
f33255c990 Add jetbrains annotations to javac classpath in IncrementalJvmCompilerRunnerTest
Before this change some of these tests were failing
2017-12-12 16:17:58 +03:00
Denis Zharkov
df533053f9 Record special name lookup when trying use interface as a SAM
It was already working in JPS, because it see our synthetic classes
as subclasses for SAM's, but with non-JPS build we have to manually
tracking places that should be recompiled after SAM members are changed
2017-12-12 16:17:58 +03:00
Denis Zharkov
ae6421476d Refine dirty files computation in case of Java source changes
#KT-17621 In Progress
2017-12-12 16:17:58 +03:00
Denis Zharkov
26393d738f Drop IncrementalCompilerRunner::markDirty and its override 2017-12-12 16:17:58 +03:00
Denis Zharkov
1702775738 Introduce JavaClassesSerializerExtension
It will be used to track java classes changes for incremental compilation

 #KT-17621 In Progress
2017-12-12 16:17:58 +03:00
Denis Zharkov
c86dc0d7af Add protobuf extensions to serialized Java descriptors
#KT-17621 In Progress
2017-12-12 16:17:58 +03:00
Denis Zharkov
34452f4f4a Introduce JavaClassesTracker interface into java resolution components
It's purpose is passing java classes being used during analysis
to incremental compilation to let it track diffs

Potentially it might be done the other way:
incremental compilation could build a separate container to analyze
necessary classes, but it's rather hard to implement now

 #KT-17621 In Progress
2017-12-12 16:17:58 +03:00
Alexey Sedunov
9ed0b49746 Gradle: Compile Gradle models/model builders under JVM 1.6
This prevents imports failure in projects using older versions of Gradle

 #KT-21610 Fixed
2017-12-12 15:38:40 +03:00
Dmitry Petrov
a1a1972a04 Provide DescriptorUtils.isAnonymousFunction (for IR-based BE) 2017-12-12 15:29:45 +03:00
Anton Bannykh
0566366895 Make project wizards produce kotlin-test-js testDependency in all Kotlin/JS projects 2017-12-12 14:25:24 +03:00
Alexander Udalov
3c98274006 Move -Xjsr-305 argument parsing out of K2JVMCompilerArguments
To simplify K2JVMCompilerArguments, which is mostly a data holder
2017-12-11 18:02:37 +01:00
Alexander Udalov
5092758acb Improve help message on -Xjsr305 CLI argument 2017-12-11 18:02:04 +01:00
Dmitry Jemerov
900ec82614 Fix indent of expressions following elvis operator 2017-12-11 17:58:02 +01:00
Dmitry Jemerov
87d2d16cda "Use continuation indent for expression body" for prop initializers 2017-12-11 17:58:02 +01:00
Dmitry Jemerov
eacd010e7e Option to wrap elvis expressions
#KT-21720 Fixed
2017-12-11 17:58:02 +01:00
Dmitry Jemerov
d1daca2560 No line break before = in property initializer and function expr body 2017-12-11 17:58:02 +01:00
Dmitry Jemerov
ab99bf843a Implement option for wrapping assignment statements
#KT-21718 Fixed
2017-12-11 17:58:02 +01:00
Dmitry Jemerov
947833cad6 Add wrap option for expression body functions
#KT-21470 Fixed
2017-12-11 17:58:02 +01:00
Dmitry Jemerov
3394d675e5 Option to use continuation indent in argument lists 2017-12-11 17:58:02 +01:00
Dmitry Jemerov
3038f87105 Move two continuation indent wrapping options to wrapping page 2017-12-11 17:58:02 +01:00
Dmitry Jemerov
dc4e673fb1 Initial support for chained call wrapping options
#KT-21529 Fixed
2017-12-11 17:58:02 +01:00
Dmitry Jemerov
1a93d10697 Refactoring: use more specific block type in signatures 2017-12-11 17:58:02 +01:00
Dmitry Jemerov
3233d650c1 Refactoring: cleanup access to code style settings 2017-12-11 17:58:02 +01:00
Dmitry Jemerov
ff99b921b7 Refactoring: work with ASTNodes in functional style 2017-12-11 17:58:02 +01:00
Dmitry Jemerov
389729cc50 Option for normal indent in supertype lists
#KT-21527 Fixed
2017-12-11 17:58:02 +01:00
Dmitry Jemerov
67cd4ed17a Don't indent closing parenthesis in conditions
#KT-21485 Fixed
2017-12-11 17:58:02 +01:00
Dmitry Jemerov
26d47a034e Don't indent closing parenthesis of a destructuring declaration
#KT-20758 Fixed
2017-12-11 17:58:02 +01:00
Dmitry Jemerov
4068b3d9b9 Add continuation indent for wrapped type aliases
#KT-21078 Fixed

fixup type alias
2017-12-11 17:58:02 +01:00
Nikolay Krasko
1ada284a03 Better folding for mulitline strings (KT-21441)
#KT-21441 Fixed
2017-12-11 18:28:01 +03:00
Nikolay Krasko
ab7ba3ae46 Add exit point highlighting for accessors (KT-21318)
#KT-21318 Fixed
2017-12-11 18:28:00 +03:00
Alexey Andreev
93f8542fc4 JS: serialize location of JsCase/JsDefault
See KT-21699
2017-12-11 17:20:15 +03:00
Alexey Andreev
25e56874c1 JS: readable error when source maps change in IC tests 2017-12-11 17:20:15 +03:00
Alexey Tsvetkov
c13b2a6bbc Test incremental recompilation of enum usage in JS 2017-12-11 17:20:14 +03:00
Andrey Mischenko
e1dbb90fdd KT-21729 Error message says "androidProcessor" should be "annotationProcessor" 2017-12-11 09:29:06 +08:00
Toshiaki Kameyama
4563cf250d "Add type" quick fix incorrectly processes vararg modifier with primitive type array initializer #KT-21544 Fixed 2017-12-08 15:46:45 +01:00
Dmitry Jemerov
846e50dcaa Wording fix 2017-12-08 15:44:18 +01:00
Toshiaki Kameyama
270b41dc66 KT-13378 Provide ability to configure highlighting for !! in expressions and ? in types 2017-12-08 15:44:18 +01:00
Dmitry Jemerov
ab619c5655 Improve wording; mark inspection as cleanup tool 2017-12-08 15:41:22 +01:00
Toshiaki Kameyama
0e2bdf8995 Add inspection to sort modifiers #KT-21560 Fixed 2017-12-08 15:41:22 +01:00
Alexander Udalov
2be7116b0b Deduplicate classpath roots in compiler when -Xbuild-file is used
In kotlin-gradle-plugin, the compiler is invoked with a
K2JVMCompilerArguments instance where both the classpath is set, and the
buildFile is used (containing the same classpath entries in XML).
Previously, the compiler concatenated those two classpaths, which
resulted in duplicated entries, which could slow down compilation. Now,
if buildFile is used, the classpath passed explicitly is ignored
(exactly as, for example, destination ("-d"), which is also stored in
the XML build file).

No test added because there doesn't seem to be any change in
user-visible behavior
2017-12-08 12:07:22 +01:00
Alexander Udalov
d65b999c2c Minor, rename variable for clarity 2017-12-08 12:07:22 +01:00
Ilya Gorbunov
0b9830248d Restore original accessor signature as deprecated
The deprecated function is not operator because it covers cases where it was used in explicit form.

#KT-18789
2017-12-07 20:26:53 +03:00
Ilya Gorbunov
7efaa7cabc Allow delegating val properties to out-projected MutableMap
Change generic signature of MutableMap.getValue, use 'out @Exact V' and `V1: V` types instead of single `in V`.
Fix affected IR generation tests.

#KT-18789 Fixed
2017-12-07 20:26:53 +03:00
Mikhail Glukhikh
e503c1d411 Suspend call detector: fix delegated properties checking 2017-12-07 15:54:47 +03:00
Mikhail Glukhikh
24bd31457c Has suspend calls: fix suspend iterator case 2017-12-07 15:54:47 +03:00
Mikhail Glukhikh
4404439521 Introduce "redundant suspend" inspection #KT-19103 Fixed 2017-12-07 15:54:47 +03:00
Mikhael Bogdanov
edefb45585 Copy sam wrappers during inline
#KT-21671 Fixed
2017-12-07 12:57:43 +01:00
Mikhael Bogdanov
4eb30b6626 Code clean 2017-12-07 12:57:42 +01:00
4602 changed files with 83994 additions and 54093 deletions

1
.gitattributes vendored
View File

@@ -1,3 +1,4 @@
**/testData/** linguist-vendored
*Generated.java linguist-generated=true
compiler/cli/bin/* eol=lf
compiler/cli/bin/*.bat eol=crlf

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@
/confluence/target
/dependencies
/dist
/local
/gh-pages
/ideaSDK
/clionSDK

5
.idea/ant.xml generated
View File

@@ -2,10 +2,6 @@
<project version="4">
<component name="AntConfiguration">
<buildFile url="file://$PROJECT_DIR$/compiler/frontend/buildLexer.xml" />
<buildFile url="file://$PROJECT_DIR$/build.xml">
<antCommandLine value="-J-ea" />
<maximumHeapSize value="1024" />
</buildFile>
<buildFile url="file://$PROJECT_DIR$/update_dependencies.xml" />
<buildFile url="file://$PROJECT_DIR$/TeamCityBuild.xml">
<maximumHeapSize value="512" />
@@ -18,6 +14,5 @@
</properties>
</buildFile>
<buildFile url="file://$PROJECT_DIR$/TeamCityRelay.xml" />
<buildFile url="file://$PROJECT_DIR$/node_utils.xml" />
</component>
</project>

View File

@@ -55,6 +55,15 @@
</value>
</option>
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="CONTINUATION_INDENT_IN_PARAMETER_LISTS" value="false" />
<option name="CONTINUATION_INDENT_IN_ARGUMENT_LISTS" value="false" />
<option name="CONTINUATION_INDENT_FOR_EXPRESSION_BODIES" value="false" />
<option name="CONTINUATION_INDENT_FOR_CHAINED_CALLS" value="false" />
<option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="false" />
<option name="CONTINUATION_INDENT_IN_IF_CONDITIONS" value="false" />
<option name="WRAP_EXPRESSION_BODY_FUNCTIONS" value="1" />
</JetCodeStyleSettings>
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
@@ -228,7 +237,6 @@
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<option name="ELSE_ON_NEW_LINE" value="true" />
@@ -261,12 +269,16 @@
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="5" />
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,9 +1,7 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright 2010-&amp;#36;today.year JetBrains s.r.o.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
<option name="keyword" value="Copyright" />
<option name="allowReplaceKeyword" value="JetBrains" />
<option name="allowReplaceRegexp" value="JetBrains" />
<option name="myName" value="apache" />
<option name="myLocal" value="true" />
<option name="notice" value="Copyright 2000-&amp;#36;today.year JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license &#10;that can be found in the license/LICENSE.txt file." />
</copyright>
</component>

View File

@@ -2,6 +2,7 @@
<dictionary name="Nikolay.Krasko">
<words>
<w>accessors</w>
<w>coroutines</w>
<w>crossinline</w>
<w>fqname</w>
<w>goto</w>
@@ -12,6 +13,7 @@
<w>memoize</w>
<w>memoized</w>
<w>multiline</w>
<w>navigatable</w>
<w>preload</w>
<w>preloader</w>
<w>preloading</w>

View File

@@ -5,6 +5,7 @@
<w>impls</w>
<w>kapt</w>
<w>parceler</w>
<w>repl</w>
<w>uast</w>
</words>
</dictionary>

View File

@@ -56,7 +56,7 @@
<option name="ignoreOnVolatileVariables" value="true" />
</inspection_tool>
<inspection_tool class="DuplicateCondition" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreMethodCalls" value="false" />
<option name="ignoreSideEffectConditions" value="true" />
</inspection_tool>
<inspection_tool class="EmptyStatementBody" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_reportEmptyBlocks" value="false" />
@@ -281,6 +281,7 @@
<option name="fromVersion" value="2.4" />
<option name="toVersion" value="3.1" />
</inspection_tool>
<inspection_tool class="Reformat" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="ReplaceAssignmentWithOperatorAssignment" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreLazyOperators" value="true" />
<option name="ignoreObscureOperators" value="true" />
@@ -402,8 +403,10 @@
<inspection_tool class="UnnecessaryFullyQualifiedName" enabled="true" level="WARNING" enabled_by_default="true">
<scope name="IDEA Test Sources" level="WARNING" enabled="false">
<option name="m_ignoreJavadoc" value="true" />
<option name="ignoreInModuleStatements" value="true" />
</scope>
<option name="m_ignoreJavadoc" value="true" />
<option name="ignoreInModuleStatements" value="true" />
</inspection_tool>
<inspection_tool class="UnnecessaryLabelOnBreakStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryLabelOnContinueStatement" enabled="false" level="WARNING" enabled_by_default="false" />

File diff suppressed because it is too large Load Diff

View File

@@ -46,11 +46,7 @@ You also can use [Gradle properties](https://docs.gradle.org/current/userguide/b
## Building
To build this project, first time you try to build you need to run this:
ant -f update_dependencies.xml
which will setup the dependencies on
On the first project configuration gradle will download and setup the dependencies on
* `intellij-core` is a part of command line compiler and contains only necessary APIs.
* `idea-full` is a full blown IntelliJ IDEA Community Edition to be used in the plugin module.
@@ -85,7 +81,7 @@ Refer to [libraries/ReadMe.md](libraries/ReadMe.md) for details.
## Working with the project in IntelliJ IDEA
Working with the Kotlin project requires IntelliJ IDEA 2017.3. You can download an Early Access Preview version of IntelliJ IDEA 2017.3 [here](https://www.jetbrains.com/idea/nextversion/).
Working with the Kotlin project requires IntelliJ IDEA 2017.3. You can download IntelliJ IDEA 2017.3 [here](https://www.jetbrains.com/idea/download).
To import the project in Intellij choose project directory in Open project dialog. Then, after project opened, Select
`File` -> `New...` -> `Module from Existing Sources` in the menu, and select `build.gradle.kts` file in the project's root folder.

View File

@@ -1,12 +1,13 @@
<project name="Kotlin CI Steps" default="none">
<import file="build.xml" optional="false"/>
<import file="common.xml" optional="false"/>
<property name="kotlin-home" value="${output}/kotlinc"/>
<property name="build.number" value="snapshot"/>
<property name="fail.on.plugin.verifier.error" value="true"/>
<property name="version_substitute_dir" value="${basedir}/versions_temp/"/>
<property name="artifact.output.path" value="${basedir}/dist/artifacts"/>
<property name="artifact.output.path" value="${basedir}/dist/artifacts/ideaPlugin"/>
<property name="plugin.xml" value="idea/src/META-INF/plugin.xml"/>
<property name="plugin.xml.bk" value="${version_substitute_dir}/plugin.xml.bk"/>
<property name="plugin.xml.versioned" value="${plugin.xml}.versioned"/>
@@ -38,84 +39,49 @@
<echoprop prop="user.home"/>
<echoprop prop="user.dir"/>
<target name="cleanupArtifacts">
<delete dir="${artifact.output.path}" includes="*"/>
</target>
<macrodef name="substituteVersionInFile">
<attribute name="target.file"/>
<attribute name="test.string"/>
<attribute name="target.file.bk" default="@{target.file}.bk"/>
<attribute name="target.file.versioned" default="@{target.file}.versioned"/>
<attribute name="token.key" default="snapshot"/>
<attribute name="version" default="${build.number}"/>
<macrodef name="run-gradle">
<attribute name="tasks" />
<attribute name="args" default="" />
<sequential>
<!-- Create backup. Backup will be restored after build end. This will allow to rebuild project without renew
plugin.xml from repository. -->
<copy file="@{target.file}" tofile="@{target.file.bk}"/>
<!-- Check that version has correct pattern for substitution -->
<copy todir="">
<fileset file="@{target.file.bk}">
<contains text="@{test.string}"/>
</fileset>
<filterchain>
<replacetokens>
<token key="@{token.key}" value="@{version}"/>
</replacetokens>
</filterchain>
<mergemapper to="@{target.file.versioned}"/>
</copy>
<!-- If file doesn't exist - there's a problem with original plugin.xml. Probably there's a bad pattern used for version -->
<copy file="@{target.file.versioned}" tofile="@{target.file}" overwrite="true"/>
<delete file="@{target.file.versioned}" quiet="true"/>
<java classname="org.gradle.wrapper.GradleWrapperMain"
fork="true"
dir="${basedir}"
failonerror="true"
timeout="4000000"
maxmemory="400m"
taskname="gradle">
<classpath>
<pathelement location="${basedir}/gradle/wrapper/gradle-wrapper.jar"/>
</classpath>
<arg line="--no-daemon" />
<arg line="@{tasks}" />
<arg line="@{args}" />
</java>
</sequential>
</macrodef>
<target name="cleanupArtifacts">
<run-gradle tasks="cleanupArtifacts" />
</target>
<target name="zip-compiler">
<run-gradle tasks="zipCompiler" args="-PdeployVersion=${build.number}" />
</target>
<target name="zip-test-data">
<run-gradle tasks="zipTestData" />
</target>
<target name="writeCompilerVersionToTemplateFile">
<!-- empty, version is written in gradle build -->
</target>
<target name="writePluginVersionToTemplateFile">
<mkdir dir="${version_substitute_dir}"/>
<substituteVersionInFile
target.file="${plugin.xml}"
target.file.bk="${plugin.xml.bk}"
target.file.versioned="${plugin.xml.versioned}"
test.string="&lt;version&gt;@snapshot@&lt;/version&gt;"
version="${plugin.xml.version.number}"/>
<run-gradle tasks="writePluginVersion" args="-PpluginVersion=${plugin.xml.version.number}" />
</target>
<target name="revertTemplateFiles">
<copy file="${plugin.xml.bk}" tofile="${plugin.xml}" overwrite="true"/>
<copy file="${compiler.version.java.bk}" tofile="${compiler.version.java}" overwrite="true"/>
<delete dir="${version_substitute_dir}" quiet="true"/>
</target>
<target name="pre_build" depends="writeCompilerVersionToTemplateFile, writePluginVersionToTemplateFile, cleanupArtifacts"/>
<target name="zipArtifacts">
<macrodef name="zipPlugin">
<attribute name="filename"/>
<attribute name="prefix" />
<attribute name="dir"/>
<sequential>
<zip destfile="@{filename}">
<zipfileset prefix="@{prefix}" dir="@{dir}" excludes="kotlinc/bin/*"/>
<zipfileset prefix="@{prefix}/kotlinc/bin" dir="@{dir}/kotlinc/bin" includes="*.bat"
filemode="644"/>
<zipfileset prefix="@{prefix}/kotlinc/bin" dir="@{dir}/kotlinc/bin" excludes="*.bat"
filemode="755"/>
</zip>
</sequential>
</macrodef>
<zipPlugin filename="${plugin.zip}" prefix="Kotlin" dir="${artifact.output.path}/${pluginArtifactDir}"/>
<run-gradle tasks="zipPlugin" args="-PpluginArtifactDir=${pluginArtifactDir} -PpluginZipPath=${plugin.zip}"/>
</target>
<macrodef name="print-statistic">
@@ -148,42 +114,8 @@
<print-file-size-statistic path="${basedir}/libraries/stdlib/js/build/classes/main" file-name="kotlin.meta.js"/>
</target>
<target name="post_build" depends="zipArtifacts, revertTemplateFiles, printStatistics, remove_internal_artifacts, dont_remove_internal_artifacts"/>
<target name="none">
<fail message="Either specify pre_build or post_build"/>
</target>
<property name="teamcity.build.branch" value=""/>
<condition property="need.remove.artifacts" value="true">
<and>
<matches pattern="rri?/.*" string="${teamcity.build.branch}"/>
<not>
<matches pattern="rri?/internal/.*" string="${teamcity.build.branch}"/>
</not>
</and>
</condition>
<target name="remove_internal_artifacts"
description="Remove internal artifacts for rri?/* branches, but store them for rri?/internal/*"
if="need.remove.artifacts">
<echo message="Remove internal artifacts" />
<delete failonerror="false" verbose="true">
<fileset dir="dist">
<include name="kotlin-compiler-before-shrink.jar"/>
<include name="kotlin-for-upsource.jar"/>
<include name="kotlin-for-upsource-sources.jar"/>
<include name="kotlin-test-data.zip"/>
</fileset>
<fileset dir="out/artifacts/internal">
<include name="kotlin-ide-common.jar"/>
</fileset>
</delete>
</target>
<target name="dont_remove_internal_artifacts" unless="need.remove.artifacts">
<echo message="Internal artifacts left untouched"/>
</target>
</project>

View File

@@ -10,15 +10,17 @@ dependencies {
compileOnly(project(":compiler:frontend.java"))
compileOnly(project(":js:js.serializer"))
compileOnly(project(":js:js.frontend"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeJars("annotations", "asm-all", "trove4j", "util") }
compileOnly(project(":kotlin-reflect-api"))
compileOnly(ideaSdkDeps("util"))
testCompileOnly(project(":compiler:cli-common"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(commonDep("junit:junit"))
testCompile(protobufFull())
testCompile(projectDist(":kotlin-stdlib"))
testCompileOnly(ideaSdkDeps("openapi"))
testRuntime(projectDist(":kotlin-compiler"))
testCompileOnly(intellijDep()) { includeJars("openapi") }
testRuntime(projectDist(":kotlin-reflect"))
}

View File

@@ -14,17 +14,27 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.configuration;
package org.jetbrains.kotlin.serialization.java;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
import "core/deserialization/src/descriptors.proto";
public abstract class KotlinModuleTypeManager {
public static KotlinModuleTypeManager getInstance() {
return ServiceManager.getService(KotlinModuleTypeManager.class);
}
option java_outer_classname = "JavaClassProtoBuf";
option optimize_for = LITE_RUNTIME;
public abstract boolean isAndroidGradleModule(@NotNull Module module);
public abstract boolean isGradleModule(@NotNull Module module);
extend Function {
optional bool is_static_method = 1000;
optional bool is_package_private_method = 1001;
}
extend Property {
optional bool is_static_field = 1000;
optional bool is_package_private_field = 1001;
}
extend Class {
optional bool is_package_private_class = 1000;
}
extend Constructor {
optional bool is_package_private_constructor = 1000;
}

View File

@@ -72,13 +72,13 @@ class ChangesCollector {
}
}
fun collectProtoChanges(oldData: ProtoData?, newData: ProtoData?) {
fun collectProtoChanges(oldData: ProtoData?, newData: ProtoData?, collectAllMembersForNewClass: Boolean = false) {
if (oldData == null && newData == null) {
throw IllegalStateException("Old and new value are null")
}
if (oldData == null) {
newData!!.collectAll(isRemoved = false)
newData!!.collectAll(isRemoved = false, collectAllMembersForNewClass = collectAllMembersForNewClass)
return
}
@@ -120,10 +120,10 @@ class ChangesCollector {
private fun <T> T.getNonPrivateNames(nameResolver: NameResolver, vararg members: T.() -> List<MessageLite>): Set<String> =
members.flatMap { this.it().filterNot { it.isPrivate }.names(nameResolver) }.toSet()
private fun ProtoData.collectAll(isRemoved: Boolean) =
private fun ProtoData.collectAll(isRemoved: Boolean, collectAllMembersForNewClass: Boolean = false) =
when (this) {
is PackagePartProtoData -> collectAllFromPackage(isRemoved)
is ClassProtoData -> collectAllFromClass(isRemoved)
is ClassProtoData -> collectAllFromClass(isRemoved, collectAllMembersForNewClass)
}
private fun PackagePartProtoData.collectAllFromPackage(isRemoved: Boolean) {
@@ -142,28 +142,36 @@ class ChangesCollector {
}
}
private fun ClassProtoData.collectAllFromClass(isRemoved: Boolean) {
private fun ClassProtoData.collectAllFromClass(isRemoved: Boolean, collectAllMembersForNewClass: Boolean = false) {
val classFqName = nameResolver.getClassId(proto.fqName).asSingleFqName()
val kind = Flags.CLASS_KIND.get(proto.flags)
if (kind == ProtoBuf.Class.Kind.COMPANION_OBJECT) {
val memberNames =
proto.getNonPrivateNames(
nameResolver,
ProtoBuf.Class::getConstructorList,
ProtoBuf.Class::getFunctionList,
ProtoBuf.Class::getPropertyList
) + proto.enumEntryList.map { nameResolver.getString(it.name) }
val memberNames = getNonPrivateMemberNames()
val collectMember = if (isRemoved) this@ChangesCollector::collectRemovedMember else this@ChangesCollector::collectChangedMember
collectMember(classFqName.parent(), classFqName.shortName().asString())
memberNames.forEach { collectMember(classFqName, it) }
}
else {
if (!isRemoved && collectAllMembersForNewClass) {
val memberNames = getNonPrivateMemberNames()
memberNames.forEach { this@ChangesCollector.collectChangedMember(classFqName, it) }
}
collectSignature(classFqName, areSubclassesAffected = true)
}
}
private fun ClassProtoData.getNonPrivateMemberNames(): Set<String> {
return proto.getNonPrivateNames(
nameResolver,
ProtoBuf.Class::getConstructorList,
ProtoBuf.Class::getFunctionList,
ProtoBuf.Class::getPropertyList
) + proto.enumEntryList.map { nameResolver.getString(it.name) }
}
fun collectMemberIfValueWasChanged(scope: FqName, name: String, oldValue: Any?, newValue: Any?) {
if (oldValue == null && newValue == null) {
throw IllegalStateException("Old and new value are null for $scope#$name")
@@ -186,4 +194,4 @@ class ChangesCollector {
val prevValue = this.areSubclassesAffected[fqName] ?: false
this.areSubclassesAffected[fqName] = prevValue || areSubclassesAffected
}
}
}

View File

@@ -28,18 +28,20 @@ import java.io.File
/**
* Incremental cache common for JVM and JS
*/
abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(workingDir) {
abstract class IncrementalCacheCommon<ClassName>(workingDir: File) : BasicMapsOwner(workingDir) {
companion object {
private val SUBTYPES = "subtypes"
private val SUPERTYPES = "supertypes"
private val CLASS_FQ_NAME_TO_SOURCE = "class-fq-name-to-source"
@JvmStatic protected val SOURCE_TO_CLASSES = "source-to-classes"
@JvmStatic protected val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
}
private val dependents = arrayListOf<IncrementalCacheCommon>()
fun addDependentCache(cache: IncrementalCacheCommon) {
private val dependents = arrayListOf<IncrementalCacheCommon<ClassName>>()
fun addDependentCache(cache: IncrementalCacheCommon<ClassName>) {
dependents.add(cache)
}
val thisWithDependentCaches: Iterable<IncrementalCacheCommon> by lazy {
val thisWithDependentCaches: Iterable<IncrementalCacheCommon<ClassName>> by lazy {
val result = arrayListOf(this)
result.addAll(dependents)
result
@@ -48,6 +50,8 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(working
private val subtypesMap = registerMap(SubtypesMap(SUBTYPES.storageFile))
private val supertypesMap = registerMap(SupertypesMap(SUPERTYPES.storageFile))
protected val classFqNameToSourceMap = registerMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile))
internal abstract val sourceToClassesMap: AbstractSourceToOutputMap<ClassName>
internal abstract val dirtyOutputClassesMap: AbstractDirtyClassesMap<ClassName>
fun getSubtypesOf(className: FqName): Sequence<FqName> =
subtypesMap[className].asSequence()
@@ -55,7 +59,16 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(working
fun getSourceFileIfClass(fqName: FqName): File? =
classFqNameToSourceMap[fqName]
abstract fun markDirty(removedAndCompiledSources: List<File>)
open fun markDirty(removedAndCompiledSources: List<File>) {
for (sourceFile in removedAndCompiledSources) {
val classes = sourceToClassesMap[sourceFile]
classes.forEach {
dirtyOutputClassesMap.markDirty(it)
}
sourceToClassesMap.clearOutputsForSource(sourceFile)
}
}
protected fun addToClassStorage(proto: ProtoBuf.Class, nameResolver: NameResolver, srcFile: File) {
val supertypes = proto.supertypes(TypeTable(proto.typeTable))
@@ -73,11 +86,19 @@ abstract class IncrementalCacheCommon(workingDir: File) : BasicMapsOwner(working
classFqNameToSourceMap[child] = srcFile
}
protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>) {
abstract fun clearCacheForRemovedClasses(changesCollector: ChangesCollector)
protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>, changesCollector: ChangesCollector) {
if (removedClasses.isEmpty()) return
val removedFqNames = removedClasses.toSet()
for (removedClass in removedFqNames) {
for (affectedClass in withSubtypes(removedClass, thisWithDependentCaches)) {
changesCollector.collectSignature(affectedClass, areSubclassesAffected = false)
}
}
for (cache in thisWithDependentCaches) {
val parentsFqNames = hashSetOf<FqName>()
val childrenFqNames = hashSetOf<FqName>()

View File

@@ -31,19 +31,20 @@ import java.io.DataInput
import java.io.DataOutput
import java.io.File
open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDir) {
open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon<FqName>(cachesDir) {
companion object {
private val TRANSLATION_RESULT_MAP = "translation-result"
private val SOURCES_TO_CLASSES_FQNS = "sources-to-classes"
private val INLINE_FUNCTIONS = "inline-functions"
private val HEADER_FILE_NAME = "header.meta"
}
private val dirtySources = arrayListOf<File>()
override val sourceToClassesMap = registerMap(SourceToFqNameMap(SOURCE_TO_CLASSES.storageFile))
override val dirtyOutputClassesMap = registerMap(DirtyClassesFqNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile))
private val sourcesToClasses = registerMap(SourceToClassesMap(SOURCES_TO_CLASSES_FQNS.storageFile))
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
private val dirtySources = hashSetOf<File>()
private val headerFile: File
get() = File(cachesDir, HEADER_FILE_NAME)
@@ -55,30 +56,23 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDi
}
override fun markDirty(removedAndCompiledSources: List<File>) {
super.markDirty(removedAndCompiledSources)
dirtySources.addAll(removedAndCompiledSources)
}
fun compareAndUpdate(incrementalResults: IncrementalResultsConsumerImpl, changesCollector: ChangesCollector) {
val translatedFiles = incrementalResults.packageParts
dirtySources.forEach {
if (it !in translatedFiles) {
translationResults.remove(it, changesCollector)
inlineFunctions.remove(it)
}
removeAllFromClassStorage(sourcesToClasses[it])
sourcesToClasses.clearOutputsForSource(it)
}
dirtySources.clear()
for ((srcFile, data) in translatedFiles) {
dirtySources.remove(srcFile)
val (binaryMetadata, binaryAst) = data
val oldProtoMap = translationResults[srcFile]?.metadata?.let { getProtoData(srcFile, it) } ?: emptyMap()
val newProtoMap = getProtoData(srcFile, binaryMetadata)
for (protoData in newProtoMap.values) {
for ((classId, protoData) in newProtoMap) {
registerOutputForFile(srcFile, classId.asSingleFqName())
if (protoData is ClassProtoData) {
addToClassStorage(protoData.proto, protoData.nameResolver, srcFile)
}
@@ -96,6 +90,21 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDi
}
}
private fun registerOutputForFile(srcFile: File, name: FqName) {
sourceToClassesMap.add(srcFile, name)
dirtyOutputClassesMap.notDirty(name)
}
override fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
dirtySources.forEach {
translationResults.remove(it, changesCollector)
inlineFunctions.remove(it)
}
removeAllFromClassStorage(dirtyOutputClassesMap.getDirtyOutputClasses(), changesCollector)
dirtySources.clear()
dirtyOutputClassesMap.clean()
}
fun nonDirtyPackageParts(): Map<File, TranslationResultValue> =
hashMapOf<File, TranslationResultValue>().apply {
for (path in translationResults.keys()) {
@@ -107,25 +116,6 @@ open class IncrementalJsCache(cachesDir: File) : IncrementalCacheCommon(cachesDi
}
}
private class SourceToClassesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
fun clearOutputsForSource(sourceFile: File) {
remove(sourceFile.canonicalPath)
}
fun add(sourceFile: File, className: FqName) {
storage.append(sourceFile.canonicalPath, className.asString())
}
operator fun get(sourceFile: File): Collection<FqName> =
storage[sourceFile.canonicalPath].orEmpty().map { FqName(it) }
override fun dumpValue(value: Collection<String>) = value.dumpCollection()
private fun remove(path: String) {
storage.remove(path)
}
}
private object TranslationResultValueExternalizer : DataExternalizer<TranslationResultValue> {
override fun save(output: DataOutput, value: TranslationResultValue) {
output.writeInt(value.metadata.size)

View File

@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
@@ -43,46 +44,38 @@ val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
open class IncrementalJvmCache(
private val targetDataRoot: File,
targetOutputDir: File?
) : IncrementalCacheCommon(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
) : IncrementalCacheCommon<JvmClassName>(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
companion object {
private val PROTO_MAP = "proto"
private val CONSTANTS_MAP = "constants"
private val PACKAGE_PARTS = "package-parts"
private val MULTIFILE_CLASS_FACADES = "multifile-class-facades"
private val MULTIFILE_CLASS_PARTS = "multifile-class-parts"
private val SOURCE_TO_CLASSES = "source-to-classes"
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
private val INLINE_FUNCTIONS = "inline-functions"
private val INTERNAL_NAME_TO_SOURCE = "internal-name-to-source"
private val JAVA_SOURCES_PROTO_MAP = "java-sources-proto-map"
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
}
override val sourceToClassesMap = registerMap(SourceToJvmNameMap(SOURCE_TO_CLASSES.storageFile))
override val dirtyOutputClassesMap = registerMap(DirtyClassesJvmNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
private val multifileFacadeToParts = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
private val partToMultifileFacade = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
// todo: try to use internal names only?
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile))
private val javaSourcesProtoMap = registerMap(JavaSourcesProtoMap(JAVA_SOURCES_PROTO_MAP.storageFile))
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory" } }
protected open fun debugLog(message: String) {}
override fun markDirty(removedAndCompiledSources: List<File>) {
for (sourceFile in removedAndCompiledSources) {
val classes = sourceToClassesMap[sourceFile]
classes.forEach {
dirtyOutputClassesMap.markDirty(it.internalName)
}
sourceToClassesMap.clearOutputsForSource(sourceFile)
}
}
fun isTrackedFile(file: File) = sourceToClassesMap.contains(file)
// used in gradle
@Suppress("unused")
@@ -93,7 +86,7 @@ open class IncrementalJvmCache(
internalNameToSource[internalName]
fun isMultifileFacade(className: JvmClassName): Boolean =
className.internalName in multifileFacadeToParts
className in multifileFacadeToParts
override fun getClassFilePath(internalClassName: String): String {
return toSystemIndependentName(File(outputDir, "$internalClassName.class").canonicalPath)
@@ -102,7 +95,7 @@ open class IncrementalJvmCache(
fun saveModuleMappingToCache(sourceFiles: Collection<File>, file: File) {
val jvmClassName = JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME)
protoMap.storeModuleMapping(jvmClassName, file.readBytes())
dirtyOutputClassesMap.notDirty(MODULE_MAPPING_FILE_NAME)
dirtyOutputClassesMap.notDirty(jvmClassName)
sourceFiles.forEach { sourceToClassesMap.add(it, jvmClassName) }
}
@@ -111,7 +104,7 @@ open class IncrementalJvmCache(
val kotlinClass: LocalFileKotlinClass = generatedClass.outputClass
val className = kotlinClass.className
dirtyOutputClassesMap.notDirty(className.internalName)
dirtyOutputClassesMap.notDirty(className)
sourceFiles.forEach {
sourceToClassesMap.add(it, className)
}
@@ -169,22 +162,46 @@ open class IncrementalJvmCache(
}
}
fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
val dirtyClasses = dirtyOutputClassesMap
.getDirtyOutputClasses()
.map(JvmClassName::byInternalName)
.toList()
fun saveJavaClassProto(source: File, serializedJavaClass: SerializedJavaClass, collector: ChangesCollector) {
val jvmClassName = JvmClassName.byClassId(serializedJavaClass.classId)
javaSourcesProtoMap.process(jvmClassName, serializedJavaClass, collector)
sourceToClassesMap.add(source, jvmClassName)
val (proto, nameResolver) = serializedJavaClass.toProtoData()
addToClassStorage(proto, nameResolver, source)
dirtyOutputClassesMap.notDirty(jvmClassName)
}
fun getObsoleteJavaClasses(): Collection<ClassId> =
dirtyOutputClassesMap.getDirtyOutputClasses()
.mapNotNull {
javaSourcesProtoMap[it]?.classId
}
fun isJavaClassToTrack(classId: ClassId): Boolean {
val jvmClassName = JvmClassName.byClassId(classId)
return dirtyOutputClassesMap.isDirty(jvmClassName) ||
jvmClassName !in javaSourcesProtoMap
}
fun isJavaClassAlreadyInCache(classId: ClassId): Boolean {
val jvmClassName = JvmClassName.byClassId(classId)
return jvmClassName in javaSourcesProtoMap
}
override fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
val dirtyClasses = dirtyOutputClassesMap.getDirtyOutputClasses()
val facadesWithRemovedParts = hashMapOf<JvmClassName, MutableSet<String>>()
for (dirtyClass in dirtyClasses) {
val facade = partToMultifileFacade.get(dirtyClass.internalName) ?: continue
val facade = partToMultifileFacade.get(dirtyClass) ?: continue
val facadeClassName = JvmClassName.byInternalName(facade)
val removedParts = facadesWithRemovedParts.getOrPut(facadeClassName) { hashSetOf() }
removedParts.add(dirtyClass.internalName)
}
for ((facade, removedParts) in facadesWithRemovedParts.entries) {
val allParts = multifileFacadeToParts[facade.internalName] ?: continue
val allParts = multifileFacadeToParts[facade] ?: continue
val notRemovedParts = allParts.filter { it !in removedParts }
if (notRemovedParts.isEmpty()) {
@@ -203,18 +220,17 @@ open class IncrementalJvmCache(
constantsMap.remove(it)
inlineFunctionsMap.remove(it)
internalNameToSource.remove(it.internalName)
javaSourcesProtoMap.remove(it, changesCollector)
}
removeAllFromClassStorage(dirtyClasses.map { it.fqNameForClassNameWithoutDollars })
removeAllFromClassStorage(dirtyClasses.map { it.fqNameForClassNameWithoutDollars }, changesCollector)
dirtyOutputClassesMap.clean()
}
override fun getObsoletePackageParts(): Collection<String> {
val obsoletePackageParts =
dirtyOutputClassesMap.getDirtyOutputClasses().filter { packagePartMap.isPackagePart(JvmClassName.byInternalName(it)) }
val obsoletePackageParts = dirtyOutputClassesMap.getDirtyOutputClasses().filter(packagePartMap::isPackagePart)
debugLog("Obsolete package parts: $obsoletePackageParts")
return obsoletePackageParts
return obsoletePackageParts.map { it.internalName }
}
override fun getPackagePartData(partInternalName: String): JvmPackagePartProto? {
@@ -234,8 +250,9 @@ open class IncrementalJvmCache(
}
override fun getStableMultifileFacadeParts(facadeInternalName: String): Collection<String>? {
val partNames = multifileFacadeToParts.get(facadeInternalName) ?: return null
return partNames.filter { !dirtyOutputClassesMap.isDirty(it) }
val jvmClassName = JvmClassName.byInternalName(facadeInternalName)
val partNames = multifileFacadeToParts[jvmClassName] ?: return null
return partNames.filter { !dirtyOutputClassesMap.isDirty(JvmClassName.byInternalName(it)) }
}
override fun getModuleMappingData(): ByteArray? {
@@ -298,6 +315,36 @@ open class IncrementalJvmCache(
}
}
private inner class JavaSourcesProtoMap(storageFile: File) : BasicStringMap<SerializedJavaClass>(storageFile, JavaClassProtoMapValueExternalizer) {
fun process(jvmClassName: JvmClassName, newData: SerializedJavaClass, changesCollector: ChangesCollector) {
val key = jvmClassName.internalName
val oldData = storage[key]
storage[key] = newData
changesCollector.collectProtoChanges(
oldData?.toProtoData(), newData.toProtoData(),
collectAllMembersForNewClass = true
)
}
fun remove(className: JvmClassName, changesCollector: ChangesCollector) {
val key = className.internalName
val oldValue = storage[key] ?: return
storage.remove(key)
changesCollector.collectProtoChanges(oldValue.toProtoData(), newData = null)
}
operator fun get(className: JvmClassName): SerializedJavaClass? =
storage[className.internalName]
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
override fun dumpValue(value: SerializedJavaClass): String =
java.lang.Long.toHexString(value.proto.toByteArray().md5())
}
// todo: reuse code with InlineFunctionsMap?
private inner class ConstantsMap(storageFile: File) : BasicStringMap<Map<String, Any>>(storageFile, ConstantsMapExternalizer) {
private fun getConstantsMap(bytes: ByteArray): Map<String, Any> {
@@ -360,13 +407,15 @@ open class IncrementalJvmCache(
}
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
operator fun set(facadeName: JvmClassName, partNames: Collection<String>) {
storage[facadeName.internalName] = partNames
operator fun set(className: JvmClassName, partNames: Collection<String>) {
storage[className.internalName] = partNames
}
operator fun get(internalName: String): Collection<String>? = storage[internalName]
operator fun get(className: JvmClassName): Collection<String>? =
storage[className.internalName]
operator fun contains(internalName: String): Boolean = internalName in storage
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
@@ -380,9 +429,8 @@ open class IncrementalJvmCache(
storage[partName] = facadeName
}
fun get(partName: String): String? {
return storage.get(partName)
}
fun get(partName: JvmClassName): String? =
storage[partName.internalName]
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
@@ -391,25 +439,6 @@ open class IncrementalJvmCache(
override fun dumpValue(value: String): String = value
}
inner class SourceToClassesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
fun clearOutputsForSource(sourceFile: File) {
remove(sourceFile.absolutePath)
}
fun add(sourceFile: File, className: JvmClassName) {
storage.append(sourceFile.absolutePath, className.internalName)
}
operator fun get(sourceFile: File): Collection<JvmClassName> =
storage[sourceFile.absolutePath].orEmpty().map { JvmClassName.byInternalName(it) }
override fun dumpValue(value: Collection<String>) = value.dumpCollection()
private fun remove(path: String) {
storage.remove(path)
}
}
inner class InternalNameToSourcesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, EnumeratorStringDescriptor(), PathCollectionExternalizer) {
operator fun set(internalName: String, sourceFiles: Iterable<File>) {
storage[internalName] = sourceFiles.map { it.canonicalPath }
@@ -431,24 +460,6 @@ open class IncrementalJvmCache(
addToClassStorage(proto, nameResolver, srcFile)
}
private inner class DirtyOutputClassesMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
fun markDirty(className: String) {
storage[className] = true
}
fun notDirty(className: String) {
storage.remove(className)
}
fun getDirtyOutputClasses(): Collection<String> =
storage.keys
fun isDirty(className: String): Boolean =
storage.contains(className)
override fun dumpValue(value: Boolean) = ""
}
private inner class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray): Map<String, Long> {
val inlineFunctions = inlineFunctionsJvmNames(header)

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2010-2017 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.incremental
import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf
// It uses BuiltInSerializerProtocol for annotations serialization
class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
super.serializeClass(descriptor, proto)
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
proto.setExtension(JavaClassProtoBuf.isPackagePrivateClass, true)
}
}
override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder) {
super.serializeConstructor(descriptor, proto)
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
proto.setExtension(JavaClassProtoBuf.isPackagePrivateConstructor, true)
}
}
override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) {
super.serializeFunction(descriptor, proto)
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
proto.setExtension(JavaClassProtoBuf.isPackagePrivateMethod, true)
}
if (descriptor.dispatchReceiverParameter == null) {
proto.setExtension(JavaClassProtoBuf.isStaticMethod, true)
}
}
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) {
super.serializeProperty(descriptor, proto)
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
proto.setExtension(JavaClassProtoBuf.isPackagePrivateField, true)
}
if (descriptor.dispatchReceiverParameter == null) {
proto.setExtension(JavaClassProtoBuf.isStaticField, true)
}
}
override fun shouldUseNormalizedVisibility() = true
override val customClassMembersProducer =
object : ClassMembersProducer {
override fun getCallableMembers(classDescriptor: ClassDescriptor) =
arrayListOf<CallableMemberDescriptor>().apply {
addAll(classDescriptor.unsubstitutedMemberScope.getSortedCallableDescriptors())
addAll(classDescriptor.staticScope.getSortedCallableDescriptors())
}
}
private fun MemberScope.getSortedCallableDescriptors(): Collection<CallableMemberDescriptor> =
DescriptorUtils.getAllDescriptors(this).filterIsInstance<CallableMemberDescriptor>()
.let { DescriptorSerializer.sort(it) }
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright 2010-2017 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.incremental
import com.intellij.psi.PsiJavaFile
import com.intellij.util.io.DataExternalizer
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
import org.jetbrains.kotlin.load.java.JavaClassesTracker
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
import org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf
import org.jetbrains.kotlin.util.PerformanceCounter
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.sure
import java.io.DataInput
import java.io.DataOutput
import java.io.File
val CONVERTING_JAVA_CLASSES_TO_PROTO = PerformanceCounter.create("Converting Java sources to proto")
class JavaClassesTrackerImpl(
private val cache: IncrementalJvmCache,
private val untrackedJavaClasses: Set<ClassId>
) : JavaClassesTracker {
private val classToSourceSerialized: MutableMap<ClassId, SerializedJavaClassWithSource> = hashMapOf()
val javaClassesUpdates: Collection<SerializedJavaClassWithSource>
get() = classToSourceSerialized.values
private val classDescriptors: MutableList<JavaClassDescriptor> = mutableListOf()
override fun reportClass(classDescriptor: JavaClassDescriptor) {
val classId = classDescriptor.classId!!
if (!cache.isJavaClassToTrack(classId) || classDescriptor.javaSourceFile == null) return
classDescriptors.add(classDescriptor)
}
override fun onCompletedAnalysis(module: ModuleDescriptor) {
for (classId in cache.getObsoleteJavaClasses() + untrackedJavaClasses) {
// Just force the loading obsolete classes
// We assume here that whenever an LazyJavaClassDescriptor instances is created
// it's being passed to JavaClassesTracker::reportClass
module.findClassAcrossModuleDependencies(classId)
}
for (classDescriptor in classDescriptors.toList()) {
val classId = classDescriptor.classId!!
if (cache.isJavaClassAlreadyInCache(classId) || classId in untrackedJavaClasses || classDescriptor.wasContentRequested()) {
assert(classId !in classToSourceSerialized) {
"Duplicated JavaClassDescriptor $classId reported to IC"
}
classToSourceSerialized[classId] = CONVERTING_JAVA_CLASSES_TO_PROTO.time {
classDescriptor.convertToProto()
}
}
}
}
private fun JavaClassDescriptor.wasContentRequested() =
this.safeAs<LazyJavaClassDescriptor>()?.wasScopeContentRequested() != false
}
private val JavaClassDescriptor.javaSourceFile: File?
get() = source.safeAs<PsiSourceElement>()
?.psi?.containingFile?.takeIf { it is PsiJavaFile }
?.virtualFile?.path?.let(::File)
fun JavaClassDescriptor.convertToProto(): SerializedJavaClassWithSource {
val file = javaSourceFile.sure { "convertToProto should only be called for source based classes" }
val extension = JavaClassesSerializerExtension()
val serializer = DescriptorSerializer.createTopLevel(extension)
val classProto = serializer.classProto(this).build()
val (stringTable, qualifiedNameTable) = extension.stringTable.buildProto()
return SerializedJavaClassWithSource(file, SerializedJavaClass(classProto, stringTable, qualifiedNameTable))
}
class SerializedJavaClass(
val proto: ProtoBuf.Class,
val stringTable: ProtoBuf.StringTable,
val qualifiedNameTable: ProtoBuf.QualifiedNameTable
) {
val classId: ClassId
get() = NameResolverImpl(stringTable, qualifiedNameTable).getClassId(proto.fqName)
}
data class SerializedJavaClassWithSource(
val source: File,
val proto: SerializedJavaClass
)
fun SerializedJavaClass.toProtoData() = ClassProtoData(proto, NameResolverImpl(stringTable, qualifiedNameTable))
val JAVA_CLASS_PROTOBUF_REGISTRY =
ExtensionRegistryLite.newInstance()
.also(JavaClassProtoBuf::registerAllExtensions)
// Built-ins extensions are used for annotations' serialization
.also(BuiltInsProtoBuf::registerAllExtensions)
object JavaClassProtoMapValueExternalizer : DataExternalizer<SerializedJavaClass> {
override fun save(output: DataOutput, value: SerializedJavaClass) {
output.writeBytesWithSize(value.proto.toByteArray())
output.writeBytesWithSize(value.stringTable.toByteArray())
output.writeBytesWithSize(value.qualifiedNameTable.toByteArray())
}
private fun DataOutput.writeBytesWithSize(bytes: ByteArray) {
writeInt(bytes.size)
write(bytes)
}
private fun DataInput.readBytesWithSize(): ByteArray {
val bytesLength = readInt()
return ByteArray(bytesLength).also {
readFully(it, 0, bytesLength)
}
}
override fun read(input: DataInput): SerializedJavaClass {
val proto = ProtoBuf.Class.parseFrom(input.readBytesWithSize(), JAVA_CLASS_PROTOBUF_REGISTRY)
val stringTable = ProtoBuf.StringTable.parseFrom(input.readBytesWithSize(), JAVA_CLASS_PROTOBUF_REGISTRY)
val qualifiedNameTable = ProtoBuf.QualifiedNameTable.parseFrom(input.readBytesWithSize(), JAVA_CLASS_PROTOBUF_REGISTRY)
return SerializedJavaClass(proto, stringTable, qualifiedNameTable)
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
* Copyright 2010-2018 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.
@@ -19,8 +19,10 @@ package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
import org.jetbrains.kotlin.serialization.js.JsProtoBuf
import org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf
import org.jetbrains.kotlin.utils.Interner
import java.util.*
@@ -71,6 +73,11 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (old.getExtension(JsProtoBuf.packageFqName) != new.getExtension(JsProtoBuf.packageFqName)) return false
}
if (old.hasExtension(BuiltInsProtoBuf.packageFqName) != new.hasExtension(BuiltInsProtoBuf.packageFqName)) return false
if (old.hasExtension(BuiltInsProtoBuf.packageFqName)) {
if (old.getExtension(BuiltInsProtoBuf.packageFqName) != new.getExtension(BuiltInsProtoBuf.packageFqName)) return false
}
return true
}
enum class ProtoBufPackageKind {
@@ -81,7 +88,8 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
VERSION_REQUIREMENT_TABLE,
JVM_EXT_PACKAGE_MODULE_NAME,
JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST,
JS_EXT_PACKAGE_FQ_NAME
JS_EXT_PACKAGE_FQ_NAME,
BUILT_INS_EXT_PACKAGE_FQ_NAME
}
fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
@@ -122,6 +130,11 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (old.getExtension(JsProtoBuf.packageFqName) != new.getExtension(JsProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.JS_EXT_PACKAGE_FQ_NAME)
}
if (old.hasExtension(BuiltInsProtoBuf.packageFqName) != new.hasExtension(BuiltInsProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.BUILT_INS_EXT_PACKAGE_FQ_NAME)
if (old.hasExtension(BuiltInsProtoBuf.packageFqName)) {
if (old.getExtension(BuiltInsProtoBuf.packageFqName) != new.getExtension(BuiltInsProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.BUILT_INS_EXT_PACKAGE_FQ_NAME)
}
return result
}
@@ -201,6 +214,20 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (old.getExtension(JsProtoBuf.classContainingFileId) != new.getExtension(JsProtoBuf.classContainingFileId)) return false
}
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateClass) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) return false
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) {
if (old.getExtension(JavaClassProtoBuf.isPackagePrivateClass) != new.getExtension(JavaClassProtoBuf.isPackagePrivateClass)) return false
}
if (old.getExtensionCount(BuiltInsProtoBuf.classAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.classAnnotation)) {
return false
}
else {
for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.classAnnotation) - 1) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.classAnnotation, i), new.getExtension(BuiltInsProtoBuf.classAnnotation, i))) return false
}
}
return true
}
enum class ProtoBufClassKind {
@@ -223,7 +250,9 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
JVM_EXT_CLASS_MODULE_NAME,
JVM_EXT_CLASS_LOCAL_VARIABLE_LIST,
JS_EXT_CLASS_ANNOTATION_LIST,
JS_EXT_CLASS_CONTAINING_FILE_ID
JS_EXT_CLASS_CONTAINING_FILE_ID,
JAVA_EXT_IS_PACKAGE_PRIVATE_CLASS,
BUILT_INS_EXT_CLASS_ANNOTATION_LIST
}
fun difference(old: ProtoBuf.Class, new: ProtoBuf.Class): EnumSet<ProtoBufClassKind> {
@@ -304,6 +333,20 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (old.getExtension(JsProtoBuf.classContainingFileId) != new.getExtension(JsProtoBuf.classContainingFileId)) result.add(ProtoBufClassKind.JS_EXT_CLASS_CONTAINING_FILE_ID)
}
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateClass) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) result.add(ProtoBufClassKind.JAVA_EXT_IS_PACKAGE_PRIVATE_CLASS)
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) {
if (old.getExtension(JavaClassProtoBuf.isPackagePrivateClass) != new.getExtension(JavaClassProtoBuf.isPackagePrivateClass)) result.add(ProtoBufClassKind.JAVA_EXT_IS_PACKAGE_PRIVATE_CLASS)
}
if (old.getExtensionCount(BuiltInsProtoBuf.classAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.classAnnotation)) {
result.add(ProtoBufClassKind.BUILT_INS_EXT_CLASS_ANNOTATION_LIST)
}
else {
for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.classAnnotation) - 1) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.classAnnotation, i), new.getExtension(BuiltInsProtoBuf.classAnnotation, i))) result.add(ProtoBufClassKind.BUILT_INS_EXT_CLASS_ANNOTATION_LIST)
}
}
return result
}
@@ -378,6 +421,25 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (old.getExtension(JsProtoBuf.functionContainingFileId) != new.getExtension(JsProtoBuf.functionContainingFileId)) return false
}
if (old.hasExtension(JavaClassProtoBuf.isStaticMethod) != new.hasExtension(JavaClassProtoBuf.isStaticMethod)) return false
if (old.hasExtension(JavaClassProtoBuf.isStaticMethod)) {
if (old.getExtension(JavaClassProtoBuf.isStaticMethod) != new.getExtension(JavaClassProtoBuf.isStaticMethod)) return false
}
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateMethod) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateMethod)) return false
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateMethod)) {
if (old.getExtension(JavaClassProtoBuf.isPackagePrivateMethod) != new.getExtension(JavaClassProtoBuf.isPackagePrivateMethod)) return false
}
if (old.getExtensionCount(BuiltInsProtoBuf.functionAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.functionAnnotation)) {
return false
}
else {
for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.functionAnnotation) - 1) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.functionAnnotation, i), new.getExtension(BuiltInsProtoBuf.functionAnnotation, i))) return false
}
}
return true
}
@@ -460,6 +522,30 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (old.getExtension(JsProtoBuf.propertyContainingFileId) != new.getExtension(JsProtoBuf.propertyContainingFileId)) return false
}
if (old.hasExtension(JavaClassProtoBuf.isStaticField) != new.hasExtension(JavaClassProtoBuf.isStaticField)) return false
if (old.hasExtension(JavaClassProtoBuf.isStaticField)) {
if (old.getExtension(JavaClassProtoBuf.isStaticField) != new.getExtension(JavaClassProtoBuf.isStaticField)) return false
}
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateField) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateField)) return false
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateField)) {
if (old.getExtension(JavaClassProtoBuf.isPackagePrivateField) != new.getExtension(JavaClassProtoBuf.isPackagePrivateField)) return false
}
if (old.getExtensionCount(BuiltInsProtoBuf.propertyAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.propertyAnnotation)) {
return false
}
else {
for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.propertyAnnotation) - 1) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.propertyAnnotation, i), new.getExtension(BuiltInsProtoBuf.propertyAnnotation, i))) return false
}
}
if (old.hasExtension(BuiltInsProtoBuf.compileTimeValue) != new.hasExtension(BuiltInsProtoBuf.compileTimeValue)) return false
if (old.hasExtension(BuiltInsProtoBuf.compileTimeValue)) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.compileTimeValue), new.getExtension(BuiltInsProtoBuf.compileTimeValue))) return false
}
return true
}
@@ -557,6 +643,15 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
}
}
if (old.getExtensionCount(BuiltInsProtoBuf.typeParameterAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.typeParameterAnnotation)) {
return false
}
else {
for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.typeParameterAnnotation) - 1) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.typeParameterAnnotation, i), new.getExtension(BuiltInsProtoBuf.typeParameterAnnotation, i))) return false
}
}
return true
}
@@ -651,6 +746,15 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
}
}
if (old.getExtensionCount(BuiltInsProtoBuf.typeAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.typeAnnotation)) {
return false
}
else {
for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.typeAnnotation) - 1) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.typeAnnotation, i), new.getExtension(BuiltInsProtoBuf.typeAnnotation, i))) return false
}
}
return true
}
@@ -681,6 +785,20 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
}
}
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateConstructor) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateConstructor)) return false
if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateConstructor)) {
if (old.getExtension(JavaClassProtoBuf.isPackagePrivateConstructor) != new.getExtension(JavaClassProtoBuf.isPackagePrivateConstructor)) return false
}
if (old.getExtensionCount(BuiltInsProtoBuf.constructorAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.constructorAnnotation)) {
return false
}
else {
for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.constructorAnnotation) - 1) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.constructorAnnotation, i), new.getExtension(BuiltInsProtoBuf.constructorAnnotation, i))) return false
}
}
return true
}
@@ -699,6 +817,15 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
}
}
if (old.getExtensionCount(BuiltInsProtoBuf.enumEntryAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.enumEntryAnnotation)) {
return false
}
else {
for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.enumEntryAnnotation) - 1) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.enumEntryAnnotation, i), new.getExtension(BuiltInsProtoBuf.enumEntryAnnotation, i))) return false
}
}
return true
}
@@ -747,6 +874,15 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
}
}
if (old.getExtensionCount(BuiltInsProtoBuf.parameterAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.parameterAnnotation)) {
return false
}
else {
for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.parameterAnnotation) - 1) {
if (!checkEquals(old.getExtension(BuiltInsProtoBuf.parameterAnnotation, i), new.getExtension(BuiltInsProtoBuf.parameterAnnotation, i))) return false
}
}
return true
}
@@ -1335,6 +1471,10 @@ fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
hashCode = 31 * hashCode + getExtension(JsProtoBuf.packageFqName)
}
if (hasExtension(BuiltInsProtoBuf.packageFqName)) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.packageFqName)
}
return hashCode
}
@@ -1419,6 +1559,14 @@ fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) ->
hashCode = 31 * hashCode + getExtension(JsProtoBuf.classContainingFileId)
}
if (hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) {
hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isPackagePrivateClass).hashCode()
}
for(i in 0..getExtensionCount(BuiltInsProtoBuf.classAnnotation) - 1) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.classAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
@@ -1483,6 +1631,18 @@ fun ProtoBuf.Function.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
hashCode = 31 * hashCode + getExtension(JsProtoBuf.functionContainingFileId)
}
if (hasExtension(JavaClassProtoBuf.isStaticMethod)) {
hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isStaticMethod).hashCode()
}
if (hasExtension(JavaClassProtoBuf.isPackagePrivateMethod)) {
hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isPackagePrivateMethod).hashCode()
}
for(i in 0..getExtensionCount(BuiltInsProtoBuf.functionAnnotation) - 1) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.functionAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
@@ -1551,6 +1711,22 @@ fun ProtoBuf.Property.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
hashCode = 31 * hashCode + getExtension(JsProtoBuf.propertyContainingFileId)
}
if (hasExtension(JavaClassProtoBuf.isStaticField)) {
hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isStaticField).hashCode()
}
if (hasExtension(JavaClassProtoBuf.isPackagePrivateField)) {
hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isPackagePrivateField).hashCode()
}
for(i in 0..getExtensionCount(BuiltInsProtoBuf.propertyAnnotation) - 1) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.propertyAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
if (hasExtension(BuiltInsProtoBuf.compileTimeValue)) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.compileTimeValue).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
@@ -1649,6 +1825,10 @@ fun ProtoBuf.TypeParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes:
hashCode = 31 * hashCode + getExtension(JsProtoBuf.typeParameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..getExtensionCount(BuiltInsProtoBuf.typeParameterAnnotation) - 1) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.typeParameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
@@ -1723,6 +1903,10 @@ fun ProtoBuf.Type.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) ->
hashCode = 31 * hashCode + getExtension(JsProtoBuf.typeAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..getExtensionCount(BuiltInsProtoBuf.typeAnnotation) - 1) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.typeAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
@@ -1749,6 +1933,14 @@ fun ProtoBuf.Constructor.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (I
hashCode = 31 * hashCode + getExtension(JsProtoBuf.constructorAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
if (hasExtension(JavaClassProtoBuf.isPackagePrivateConstructor)) {
hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isPackagePrivateConstructor).hashCode()
}
for(i in 0..getExtensionCount(BuiltInsProtoBuf.constructorAnnotation) - 1) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.constructorAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
@@ -1763,6 +1955,10 @@ fun ProtoBuf.EnumEntry.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int
hashCode = 31 * hashCode + getExtension(JsProtoBuf.enumEntryAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..getExtensionCount(BuiltInsProtoBuf.enumEntryAnnotation) - 1) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.enumEntryAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
@@ -1807,6 +2003,10 @@ fun ProtoBuf.ValueParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes:
hashCode = 31 * hashCode + getExtension(JsProtoBuf.parameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
for(i in 0..getExtensionCount(BuiltInsProtoBuf.parameterAnnotation) - 1) {
hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.parameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}

View File

@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.synthetic.SAM_LOOKUP_NAME
import java.io.File
import java.util.*
@@ -79,7 +80,8 @@ fun makeCompileServices(
fun updateIncrementalCache(
generatedFiles: Iterable<GeneratedFile>,
cache: IncrementalJvmCache,
changesCollector: ChangesCollector
changesCollector: ChangesCollector,
javaChangesTracker: JavaClassesTrackerImpl?
) {
for (generatedFile in generatedFiles) {
when {
@@ -88,6 +90,11 @@ fun updateIncrementalCache(
}
}
javaChangesTracker?.javaClassesUpdates?.forEach {
(source, serializedJavaClass) ->
cache.saveJavaClassProto(source, serializedJavaClass, changesCollector)
}
cache.clearCacheForRemovedClasses(changesCollector)
}
@@ -109,7 +116,7 @@ data class DirtyData(
)
fun ChangesCollector.getDirtyData(
caches: Iterable<IncrementalCacheCommon>,
caches: Iterable<IncrementalCacheCommon<*>>,
reporter: ICReporter
): DirtyData {
val dirtyLookupSymbols = HashSet<LookupSymbol>()
@@ -135,10 +142,10 @@ fun ChangesCollector.getDirtyData(
dirtyClassesFqNames.addAll(fqNames)
for (name in change.names) {
for (fqName in fqNames) {
dirtyLookupSymbols.add(LookupSymbol(name, fqName.asString()))
}
fqNames.mapTo(dirtyLookupSymbols) { LookupSymbol(name, it.asString()) }
}
fqNames.mapTo(dirtyLookupSymbols) { LookupSymbol(SAM_LOOKUP_NAME.asString(), it.asString()) }
}
}
@@ -163,7 +170,7 @@ fun mapLookupSymbolsToFiles(
}
fun mapClassesFqNamesToFiles(
caches: Iterable<IncrementalCacheCommon>,
caches: Iterable<IncrementalCacheCommon<*>>,
classesFqNames: Iterable<FqName>,
reporter: ICReporter,
excludes: Set<File> = emptySet()
@@ -173,7 +180,7 @@ fun mapClassesFqNamesToFiles(
for (cache in caches) {
for (dirtyClassFqName in classesFqNames) {
val srcFile = cache.getSourceFileIfClass(dirtyClassFqName)
if (srcFile == null || srcFile in excludes) continue
if (srcFile == null || srcFile in excludes || srcFile.isJavaFile()) continue
reporter.report { ("Class $dirtyClassFqName caused recompilation of: ${reporter.pathsAsString(srcFile)}") }
dirtyFiles.add(srcFile)
@@ -185,7 +192,7 @@ fun mapClassesFqNamesToFiles(
fun withSubtypes(
typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon>
caches: Iterable<IncrementalCacheCommon<*>>
): Set<FqName> {
val types = LinkedList(listOf(typeFqName))
val subtypes = hashSetOf<FqName>()

View File

@@ -244,6 +244,13 @@ class DifferenceCalculatorForClass(
ProtoBufClassKind.JVM_EXT_CLASS_LOCAL_VARIABLE_LIST -> {
// Not affected, local variables are not accessible outside of a file
}
ProtoBufClassKind.JAVA_EXT_IS_PACKAGE_PRIVATE_CLASS -> {
isClassAffected = true
areSubclassesAffected = true
}
ProtoBufClassKind.BUILT_INS_EXT_CLASS_ANNOTATION_LIST -> {
isClassAffected = true
}
}
}
@@ -289,6 +296,9 @@ class DifferenceCalculatorForPackageFacade(
ProtoBufPackageKind.JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST -> {
// Not affected, local variables are not accessible outside of a file
}
ProtoBufPackageKind.BUILT_INS_EXT_PACKAGE_FQ_NAME -> {
// Not affected
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2010-2017 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.incremental.storage
import com.intellij.util.io.BooleanDataDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import java.io.File
internal class DirtyClassesJvmNameMap(storageFile: File) : AbstractDirtyClassesMap<JvmClassName>(JvmClassNameTransformer, storageFile)
internal class DirtyClassesFqNameMap(storageFile: File) : AbstractDirtyClassesMap<FqName>(FqNameTransformer, storageFile)
internal abstract class AbstractDirtyClassesMap<Name>(
private val nameTransformer: NameTransformer<Name>,
storageFile: File
) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
fun markDirty(className: Name) {
storage[nameTransformer.asString(className)] = true
}
fun notDirty(className: Name) {
storage.remove(nameTransformer.asString(className))
}
fun getDirtyOutputClasses(): Collection<Name> =
storage.keys.map { nameTransformer.asName(it) }
fun isDirty(className: Name): Boolean =
storage.contains(nameTransformer.asString(className))
override fun dumpValue(value: Boolean) = ""
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2010-2017 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.incremental.storage
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
internal interface NameTransformer<Name> {
fun asString(name: Name): String
fun asName(string: String): Name
}
internal object FqNameTransformer : NameTransformer<FqName> {
override fun asString(name: FqName): String =
name.asString()
override fun asName(string: String): FqName =
FqName(string)
}
internal object JvmClassNameTransformer : NameTransformer<JvmClassName> {
override fun asString(name: JvmClassName): String =
name.internalName
override fun asName(string: String): JvmClassName =
JvmClassName.byInternalName(string)
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2010-2017 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.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import java.io.File
internal class SourceToJvmNameMap(storageFile: File) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile)
internal class SourceToFqNameMap(storageFile: File) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile)
internal abstract class AbstractSourceToOutputMap<Name>(
private val nameTransformer: NameTransformer<Name>,
storageFile: File
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
fun clearOutputsForSource(sourceFile: File) {
remove(sourceFile.absolutePath)
}
fun add(sourceFile: File, className: Name) {
storage.append(sourceFile.absolutePath, nameTransformer.asString(className))
}
fun contains(sourceFile: File): Boolean =
sourceFile.absolutePath in storage
operator fun get(sourceFile: File): Collection<Name> =
storage[sourceFile.absolutePath].orEmpty().map(nameTransformer::asName)
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
private fun remove(path: String) {
storage.remove(path)
}
}

View File

@@ -0,0 +1,118 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: build-common/src/java_descriptors.proto
package org.jetbrains.kotlin.serialization.java;
public final class JavaClassProtoBuf {
private JavaClassProtoBuf() {}
public static void registerAllExtensions(
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite registry) {
registry.add(org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf.isStaticMethod);
registry.add(org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf.isPackagePrivateMethod);
registry.add(org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf.isStaticField);
registry.add(org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf.isPackagePrivateField);
registry.add(org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf.isPackagePrivateClass);
registry.add(org.jetbrains.kotlin.serialization.java.JavaClassProtoBuf.isPackagePrivateConstructor);
}
public static final int IS_STATIC_METHOD_FIELD_NUMBER = 1000;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Function { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension<
org.jetbrains.kotlin.serialization.ProtoBuf.Function,
java.lang.Boolean> isStaticMethod = org.jetbrains.kotlin.protobuf.GeneratedMessageLite
.newSingularGeneratedExtension(
org.jetbrains.kotlin.serialization.ProtoBuf.Function.getDefaultInstance(),
false,
null,
null,
1000,
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.BOOL,
java.lang.Boolean.class);
public static final int IS_PACKAGE_PRIVATE_METHOD_FIELD_NUMBER = 1001;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Function { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension<
org.jetbrains.kotlin.serialization.ProtoBuf.Function,
java.lang.Boolean> isPackagePrivateMethod = org.jetbrains.kotlin.protobuf.GeneratedMessageLite
.newSingularGeneratedExtension(
org.jetbrains.kotlin.serialization.ProtoBuf.Function.getDefaultInstance(),
false,
null,
null,
1001,
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.BOOL,
java.lang.Boolean.class);
public static final int IS_STATIC_FIELD_FIELD_NUMBER = 1000;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Property { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension<
org.jetbrains.kotlin.serialization.ProtoBuf.Property,
java.lang.Boolean> isStaticField = org.jetbrains.kotlin.protobuf.GeneratedMessageLite
.newSingularGeneratedExtension(
org.jetbrains.kotlin.serialization.ProtoBuf.Property.getDefaultInstance(),
false,
null,
null,
1000,
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.BOOL,
java.lang.Boolean.class);
public static final int IS_PACKAGE_PRIVATE_FIELD_FIELD_NUMBER = 1001;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Property { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension<
org.jetbrains.kotlin.serialization.ProtoBuf.Property,
java.lang.Boolean> isPackagePrivateField = org.jetbrains.kotlin.protobuf.GeneratedMessageLite
.newSingularGeneratedExtension(
org.jetbrains.kotlin.serialization.ProtoBuf.Property.getDefaultInstance(),
false,
null,
null,
1001,
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.BOOL,
java.lang.Boolean.class);
public static final int IS_PACKAGE_PRIVATE_CLASS_FIELD_NUMBER = 1000;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Class { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension<
org.jetbrains.kotlin.serialization.ProtoBuf.Class,
java.lang.Boolean> isPackagePrivateClass = org.jetbrains.kotlin.protobuf.GeneratedMessageLite
.newSingularGeneratedExtension(
org.jetbrains.kotlin.serialization.ProtoBuf.Class.getDefaultInstance(),
false,
null,
null,
1000,
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.BOOL,
java.lang.Boolean.class);
public static final int IS_PACKAGE_PRIVATE_CONSTRUCTOR_FIELD_NUMBER = 1000;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Constructor { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension<
org.jetbrains.kotlin.serialization.ProtoBuf.Constructor,
java.lang.Boolean> isPackagePrivateConstructor = org.jetbrains.kotlin.protobuf.GeneratedMessageLite
.newSingularGeneratedExtension(
org.jetbrains.kotlin.serialization.ProtoBuf.Constructor.getDefaultInstance(),
false,
null,
null,
1000,
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.BOOL,
java.lang.Boolean.class);
static {
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@@ -28,6 +28,9 @@ data class BuildLogFinder(
private const val GRADLE_LOG = "gradle-build.log"
private const val DATA_CONTAINER_LOG = "data-container-version-build.log"
private const val SIMPLE_LOG = "build.log"
fun isJpsLogFile(file: File): Boolean =
file.name.let { it == SIMPLE_LOG || it == DATA_CONTAINER_LOG }
}
fun findBuildLog(dir: File): File? {

View File

@@ -11047,7 +11047,7 @@ public final class DebugProtoBuf {
if (((bitField0_ & 0x00000020) == 0x00000020)) {
output.writeMessage(32, versionRequirementTable_);
}
extensionWriter.writeUntil(200, output);
extensionWriter.writeUntil(19000, output);
getUnknownFields().writeTo(output);
}
@@ -17077,7 +17077,7 @@ public final class DebugProtoBuf {
if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeInt32(31, versionRequirement_);
}
extensionWriter.writeUntil(200, output);
extensionWriter.writeUntil(19000, output);
getUnknownFields().writeTo(output);
}
@@ -18497,7 +18497,7 @@ public final class DebugProtoBuf {
if (((bitField0_ & 0x00000200) == 0x00000200)) {
output.writeMessage(32, contract_);
}
extensionWriter.writeUntil(200, output);
extensionWriter.writeUntil(19000, output);
getUnknownFields().writeTo(output);
}
@@ -20974,7 +20974,7 @@ public final class DebugProtoBuf {
if (((bitField0_ & 0x00000400) == 0x00000400)) {
output.writeInt32(31, versionRequirement_);
}
extensionWriter.writeUntil(200, output);
extensionWriter.writeUntil(19000, output);
getUnknownFields().writeTo(output);
}
@@ -33479,7 +33479,7 @@ public final class DebugProtoBuf {
"ter.Variance:\003INV\022=\n\013upper_bound\030\005 \003(\0132(" +
".org.jetbrains.kotlin.serialization.Type" +
"\022\026\n\016upper_bound_id\030\006 \003(\005\"$\n\010Variance\022\006\n\002" +
"IN\020\000\022\007\n\003OUT\020\001\022\007\n\003INV\020\002*\005\010d\020\350\007\"\320\007\n\005Class\022" +
"IN\020\000\022\007\n\003OUT\020\001\022\007\n\003INV\020\002*\005\010d\020\350\007\"\321\007\n\005Class\022" +
"\020\n\005flags\030\001 \001(\005:\0016\022\025\n\007fq_name\030\003 \002(\005B\004\220\265\030\001",
"\022#\n\025companion_object_name\030\004 \001(\005B\004\210\265\030\001\022I\n" +
"\016type_parameter\030\005 \003(\01321.org.jetbrains.ko" +
@@ -33504,118 +33504,118 @@ public final class DebugProtoBuf {
"x\n\004Kind\022\t\n\005CLASS\020\000\022\r\n\tINTERFACE\020\001\022\016\n\nENU" +
"M_CLASS\020\002\022\016\n\nENUM_ENTRY\020\003\022\024\n\020ANNOTATION_" +
"CLASS\020\004\022\n\n\006OBJECT\020\005\022\024\n\020COMPANION_OBJECT\020" +
"\006*\005\010d\020\310\001\"\366\002\n\007Package\022>\n\010function\030\003 \003(\0132," +
".org.jetbrains.kotlin.serialization.Func" +
"tion\022>\n\010property\030\004 \003(\0132,.org.jetbrains.k" +
"otlin.serialization.Property\022A\n\ntype_ali" +
"as\030\005 \003(\0132-.org.jetbrains.kotlin.serializ" +
"ation.TypeAlias\022A\n\ntype_table\030\036 \001(\0132-.or" +
"g.jetbrains.kotlin.serialization.TypeTab",
"le\022^\n\031version_requirement_table\030 \001(\0132;." +
"org.jetbrains.kotlin.serialization.Versi" +
"onRequirementTable*\005\010d\020\310\001\"_\n\tTypeTable\0226" +
"\n\004type\030\001 \003(\0132(.org.jetbrains.kotlin.seri" +
"alization.Type\022\032\n\016first_nullable\030\002 \001(\005:\002" +
"-1\"\220\001\n\013Constructor\022\020\n\005flags\030\001 \001(\005:\0016\022K\n\017" +
"value_parameter\030\002 \003(\01322.org.jetbrains.ko" +
"tlin.serialization.ValueParameter\022\033\n\023ver" +
"sion_requirement\030\037 \001(\005*\005\010d\020\310\001\"\267\004\n\010Functi" +
"on\022\020\n\005flags\030\t \001(\005:\0016\022\024\n\told_flags\030\001 \001(\005:",
"\0016\022\022\n\004name\030\002 \002(\005B\004\210\265\030\001\022=\n\013return_type\030\003 " +
"\001(\0132(.org.jetbrains.kotlin.serialization" +
".Type\022\026\n\016return_type_id\030\007 \001(\005\022I\n\016type_pa" +
"rameter\030\004 \003(\01321.org.jetbrains.kotlin.ser" +
"ialization.TypeParameter\022?\n\rreceiver_typ" +
"e\030\005 \001(\0132(.org.jetbrains.kotlin.serializa" +
"tion.Type\022\030\n\020receiver_type_id\030\010 \001(\005\022K\n\017v" +
"alue_parameter\030\006 \003(\01322.org.jetbrains.kot" +
"lin.serialization.ValueParameter\022A\n\ntype" +
"_table\030\036 \001(\0132-.org.jetbrains.kotlin.seri",
"alization.TypeTable\022\033\n\023version_requireme" +
"nt\030\037 \001(\005\022>\n\010contract\030 \001(\0132,.org.jetbrai" +
"ns.kotlin.serialization.Contract*\005\010d\020\310\001\"" +
"\354\003\n\010Property\022\022\n\005flags\030\013 \001(\005:\003518\022\027\n\told_" +
"flags\030\001 \001(\005:\0042054\022\022\n\004name\030\002 \002(\005B\004\210\265\030\001\022=\n" +
"\013return_type\030\003 \001(\0132(.org.jetbrains.kotli" +
"n.serialization.Type\022\026\n\016return_type_id\030\t" +
" \001(\005\022I\n\016type_parameter\030\004 \003(\01321.org.jetbr" +
"ains.kotlin.serialization.TypeParameter\022" +
"?\n\rreceiver_type\030\005 \001(\0132(.org.jetbrains.k",
"otlin.serialization.Type\022\030\n\020receiver_typ" +
"e_id\030\n \001(\005\022R\n\026setter_value_parameter\030\006 \001" +
"(\01322.org.jetbrains.kotlin.serialization." +
"ValueParameter\022\024\n\014getter_flags\030\007 \001(\005\022\024\n\014" +
"setter_flags\030\010 \001(\005\022\033\n\023version_requiremen" +
"t\030\037 \001(\005*\005\010d\020\310\001\"\355\001\n\016ValueParameter\022\020\n\005fla" +
"gs\030\001 \001(\005:\0010\022\022\n\004name\030\002 \002(\005B\004\210\265\030\001\0226\n\004type\030" +
"\006*\006\010d\020\270\224\001\"\366\002\n\007Package\022>\n\010function\030\003 \003(\0132" +
",.org.jetbrains.kotlin.serialization.Fun" +
"ction\022>\n\010property\030\004 \003(\0132,.org.jetbrains." +
"kotlin.serialization.Property\022A\n\ntype_al" +
"ias\030\005 \003(\0132-.org.jetbrains.kotlin.seriali" +
"zation.TypeAlias\022A\n\ntype_table\030\036 \001(\0132-.o" +
"rg.jetbrains.kotlin.serialization.TypeTa",
"ble\022^\n\031version_requirement_table\030 \001(\0132;" +
".org.jetbrains.kotlin.serialization.Vers" +
"ionRequirementTable*\005\010d\020\310\001\"_\n\tTypeTable\022" +
"6\n\004type\030\001 \003(\0132(.org.jetbrains.kotlin.ser" +
"ialization.Type\022\032\n\016first_nullable\030\002 \001(\005:" +
"\002-1\"\221\001\n\013Constructor\022\020\n\005flags\030\001 \001(\005:\0016\022K\n" +
"\017value_parameter\030\002 \003(\01322.org.jetbrains.k" +
"otlin.serialization.ValueParameter\022\033\n\023ve" +
"rsion_requirement\030\037 \001(\005*\006\010d\020\270\224\001\"\270\004\n\010Func" +
"tion\022\020\n\005flags\030\t \001(\005:\0016\022\024\n\told_flags\030\001 \001(",
"\005:\0016\022\022\n\004name\030\002 \002(\005B\004\210\265\030\001\022=\n\013return_type\030" +
"\003 \001(\0132(.org.jetbrains.kotlin.serializati" +
"on.Type\022\017\n\007type_id\030\005 \001(\005\022E\n\023vararg_eleme" +
"nt_type\030\004 \001(\0132(.org.jetbrains.kotlin.ser",
"ialization.Type\022\036\n\026vararg_element_type_i" +
"d\030\006 \001(\005*\005\010d\020\310\001\"\236\003\n\tTypeAlias\022\020\n\005flags\030\001 " +
"\001(\005:\0016\022\022\n\004name\030\002 \002(\005B\004\210\265\030\001\022I\n\016type_param" +
"eter\030\003 \003(\01321.org.jetbrains.kotlin.serial" +
"ization.TypeParameter\022A\n\017underlying_type" +
"\030\004 \001(\0132(.org.jetbrains.kotlin.serializat" +
"ion.Type\022\032\n\022underlying_type_id\030\005 \001(\005\022?\n\r" +
"expanded_type\030\006 \001(\0132(.org.jetbrains.kotl" +
"in.serialization.Type\022\030\n\020expanded_type_i" +
"d\030\007 \001(\005\022B\n\nannotation\030\010 \003(\0132..org.jetbra",
"ins.kotlin.serialization.Annotation\022\033\n\023v" +
"ersion_requirement\030\037 \001(\005*\005\010d\020\310\001\"&\n\tEnumE" +
"ntry\022\022\n\004name\030\001 \001(\005B\004\210\265\030\001*\005\010d\020\310\001\"\237\003\n\022Vers" +
"ionRequirement\022\017\n\007version\030\001 \001(\005\022\024\n\014versi" +
"on_full\030\002 \001(\005\022R\n\005level\030\003 \001(\0162<.org.jetbr" +
"ains.kotlin.serialization.VersionRequire" +
"ment.Level:\005ERROR\022\022\n\nerror_code\030\004 \001(\005\022\025\n" +
"\007message\030\005 \001(\005B\004\230\265\030\001\022j\n\014version_kind\030\006 \001" +
"(\0162B.org.jetbrains.kotlin.serialization." +
"VersionRequirement.VersionKind:\020LANGUAGE",
"_VERSION\"+\n\005Level\022\013\n\007WARNING\020\000\022\t\n\005ERROR\020" +
"\001\022\n\n\006HIDDEN\020\002\"J\n\013VersionKind\022\024\n\020LANGUAGE" +
"_VERSION\020\000\022\024\n\020COMPILER_VERSION\020\001\022\017\n\013API_" +
"VERSION\020\002\"f\n\027VersionRequirementTable\022K\n\013" +
"requirement\030\001 \003(\01326.org.jetbrains.kotlin" +
".serialization.VersionRequirement\"\243\002\n\017Pa" +
"ckageFragment\022@\n\007strings\030\001 \001(\0132/.org.jet" +
"brains.kotlin.serialization.StringTable\022" +
"O\n\017qualified_names\030\002 \001(\01326.org.jetbrains" +
".kotlin.serialization.QualifiedNameTable",
"\022<\n\007package\030\003 \001(\0132+.org.jetbrains.kotlin" +
".serialization.Package\0228\n\005class\030\004 \003(\0132)." +
"org.jetbrains.kotlin.serialization.Class" +
"*\005\010d\020\310\001\"F\n\010Contract\022:\n\006effect\030\001 \003(\0132*.or" +
"g.jetbrains.kotlin.serialization.Effect\"" +
"\332\003\n\006Effect\022J\n\013effect_type\030\001 \001(\01625.org.je" +
"tbrains.kotlin.serialization.Effect.Effe" +
"ctType\022S\n\033effect_constructor_argument\030\002 " +
"\003(\0132..org.jetbrains.kotlin.serialization" +
".Expression\022X\n conclusion_of_conditional",
"_effect\030\003 \001(\0132..org.jetbrains.kotlin.ser" +
"ialization.Expression\022G\n\004kind\030\004 \001(\01629.or" +
"on.Type\022\026\n\016return_type_id\030\007 \001(\005\022I\n\016type_" +
"parameter\030\004 \003(\01321.org.jetbrains.kotlin.s" +
"erialization.TypeParameter\022?\n\rreceiver_t" +
"ype\030\005 \001(\0132(.org.jetbrains.kotlin.seriali" +
"zation.Type\022\030\n\020receiver_type_id\030\010 \001(\005\022K\n" +
"\017value_parameter\030\006 \003(\01322.org.jetbrains.k" +
"otlin.serialization.ValueParameter\022A\n\nty" +
"pe_table\030\036 \001(\0132-.org.jetbrains.kotlin.se",
"rialization.TypeTable\022\033\n\023version_require" +
"ment\030\037 \001(\005\022>\n\010contract\030 \001(\0132,.org.jetbr" +
"ains.kotlin.serialization.Contract*\006\010d\020\270" +
"\224\001\"\355\003\n\010Property\022\022\n\005flags\030\013 \001(\005:\003518\022\027\n\to" +
"ld_flags\030\001 \001(\005:\0042054\022\022\n\004name\030\002 \002(\005B\004\210\265\030\001" +
"\022=\n\013return_type\030\003 \001(\0132(.org.jetbrains.ko" +
"tlin.serialization.Type\022\026\n\016return_type_i" +
"d\030\t \001(\005\022I\n\016type_parameter\030\004 \003(\01321.org.je" +
"tbrains.kotlin.serialization.TypeParamet" +
"er\022?\n\rreceiver_type\030\005 \001(\0132(.org.jetbrain",
"s.kotlin.serialization.Type\022\030\n\020receiver_" +
"type_id\030\n \001(\005\022R\n\026setter_value_parameter\030" +
"\006 \001(\01322.org.jetbrains.kotlin.serializati" +
"on.ValueParameter\022\024\n\014getter_flags\030\007 \001(\005\022" +
"\024\n\014setter_flags\030\010 \001(\005\022\033\n\023version_require" +
"ment\030\037 \001(\005*\006\010d\020\270\224\001\"\355\001\n\016ValueParameter\022\020\n" +
"\005flags\030\001 \001(\005:\0010\022\022\n\004name\030\002 \002(\005B\004\210\265\030\001\0226\n\004t" +
"ype\030\003 \001(\0132(.org.jetbrains.kotlin.seriali" +
"zation.Type\022\017\n\007type_id\030\005 \001(\005\022E\n\023vararg_e" +
"lement_type\030\004 \001(\0132(.org.jetbrains.kotlin",
".serialization.Type\022\036\n\026vararg_element_ty" +
"pe_id\030\006 \001(\005*\005\010d\020\310\001\"\236\003\n\tTypeAlias\022\020\n\005flag" +
"s\030\001 \001(\005:\0016\022\022\n\004name\030\002 \002(\005B\004\210\265\030\001\022I\n\016type_p" +
"arameter\030\003 \003(\01321.org.jetbrains.kotlin.se" +
"rialization.TypeParameter\022A\n\017underlying_" +
"type\030\004 \001(\0132(.org.jetbrains.kotlin.serial" +
"ization.Type\022\032\n\022underlying_type_id\030\005 \001(\005" +
"\022?\n\rexpanded_type\030\006 \001(\0132(.org.jetbrains." +
"kotlin.serialization.Type\022\030\n\020expanded_ty" +
"pe_id\030\007 \001(\005\022B\n\nannotation\030\010 \003(\0132..org.je",
"tbrains.kotlin.serialization.Annotation\022" +
"\033\n\023version_requirement\030\037 \001(\005*\005\010d\020\310\001\"&\n\tE" +
"numEntry\022\022\n\004name\030\001 \001(\005B\004\210\265\030\001*\005\010d\020\310\001\"\237\003\n\022" +
"VersionRequirement\022\017\n\007version\030\001 \001(\005\022\024\n\014v" +
"ersion_full\030\002 \001(\005\022R\n\005level\030\003 \001(\0162<.org.j" +
"etbrains.kotlin.serialization.VersionReq" +
"uirement.Level:\005ERROR\022\022\n\nerror_code\030\004 \001(" +
"\005\022\025\n\007message\030\005 \001(\005B\004\230\265\030\001\022j\n\014version_kind" +
"\030\006 \001(\0162B.org.jetbrains.kotlin.serializat" +
"ion.VersionRequirement.VersionKind:\020LANG",
"UAGE_VERSION\"+\n\005Level\022\013\n\007WARNING\020\000\022\t\n\005ER" +
"ROR\020\001\022\n\n\006HIDDEN\020\002\"J\n\013VersionKind\022\024\n\020LANG" +
"UAGE_VERSION\020\000\022\024\n\020COMPILER_VERSION\020\001\022\017\n\013" +
"API_VERSION\020\002\"f\n\027VersionRequirementTable" +
"\022K\n\013requirement\030\001 \003(\01326.org.jetbrains.ko" +
"tlin.serialization.VersionRequirement\"\243\002" +
"\n\017PackageFragment\022@\n\007strings\030\001 \001(\0132/.org" +
".jetbrains.kotlin.serialization.StringTa" +
"ble\022O\n\017qualified_names\030\002 \001(\01326.org.jetbr" +
"ains.kotlin.serialization.QualifiedNameT",
"able\022<\n\007package\030\003 \001(\0132+.org.jetbrains.ko" +
"tlin.serialization.Package\0228\n\005class\030\004 \003(" +
"\0132).org.jetbrains.kotlin.serialization.C" +
"lass*\005\010d\020\310\001\"F\n\010Contract\022:\n\006effect\030\001 \003(\0132" +
"*.org.jetbrains.kotlin.serialization.Eff" +
"ect\"\332\003\n\006Effect\022J\n\013effect_type\030\001 \001(\01625.or" +
"g.jetbrains.kotlin.serialization.Effect." +
"InvocationKind\"C\n\nEffectType\022\024\n\020RETURNS_" +
"CONSTANT\020\000\022\t\n\005CALLS\020\001\022\024\n\020RETURNS_NOT_NUL" +
"L\020\002\"G\n\016InvocationKind\022\020\n\014AT_MOST_ONCE\020\000\022" +
"\020\n\014EXACTLY_ONCE\020\001\022\021\n\rAT_LEAST_ONCE\020\002\"\260\003\n" +
"\nExpression\022\r\n\005flags\030\001 \001(\005\022!\n\031value_para" +
"meter_reference\030\002 \001(\005\022T\n\016constant_value\030" +
"\003 \001(\0162<.org.jetbrains.kotlin.serializati",
"on.Expression.ConstantValue\022B\n\020is_instan" +
"ce_type\030\004 \001(\0132(.org.jetbrains.kotlin.ser" +
"ialization.Type\022\033\n\023is_instance_type_id\030\005" +
" \001(\005\022D\n\014and_argument\030\006 \003(\0132..org.jetbrai" +
"ns.kotlin.serialization.Expression\022C\n\013or" +
"_argument\030\007 \003(\0132..org.jetbrains.kotlin.s" +
"erialization.Expression\".\n\rConstantValue" +
"\022\010\n\004TRUE\020\000\022\t\n\005FALSE\020\001\022\010\n\004NULL\020\002*9\n\010Modal" +
"ity\022\t\n\005FINAL\020\000\022\010\n\004OPEN\020\001\022\014\n\010ABSTRACT\020\002\022\n" +
"\n\006SEALED\020\003*b\n\nVisibility\022\014\n\010INTERNAL\020\000\022\013",
"\n\007PRIVATE\020\001\022\r\n\tPROTECTED\020\002\022\n\n\006PUBLIC\020\003\022\023" +
"\n\017PRIVATE_TO_THIS\020\004\022\t\n\005LOCAL\020\005*Q\n\nMember" +
"Kind\022\017\n\013DECLARATION\020\000\022\021\n\rFAKE_OVERRIDE\020\001" +
"\022\016\n\nDELEGATION\020\002\022\017\n\013SYNTHESIZED\020\003B\017B\rDeb" +
"ugProtoBuf"
"EffectType\022S\n\033effect_constructor_argumen" +
"t\030\002 \003(\0132..org.jetbrains.kotlin.serializa" +
"tion.Expression\022X\n conclusion_of_conditi",
"onal_effect\030\003 \001(\0132..org.jetbrains.kotlin" +
".serialization.Expression\022G\n\004kind\030\004 \001(\0162" +
"9.org.jetbrains.kotlin.serialization.Eff" +
"ect.InvocationKind\"C\n\nEffectType\022\024\n\020RETU" +
"RNS_CONSTANT\020\000\022\t\n\005CALLS\020\001\022\024\n\020RETURNS_NOT" +
"_NULL\020\002\"G\n\016InvocationKind\022\020\n\014AT_MOST_ONC" +
"E\020\000\022\020\n\014EXACTLY_ONCE\020\001\022\021\n\rAT_LEAST_ONCE\020\002" +
"\"\260\003\n\nExpression\022\r\n\005flags\030\001 \001(\005\022!\n\031value_" +
"parameter_reference\030\002 \001(\005\022T\n\016constant_va" +
"lue\030\003 \001(\0162<.org.jetbrains.kotlin.seriali",
"zation.Expression.ConstantValue\022B\n\020is_in" +
"stance_type\030\004 \001(\0132(.org.jetbrains.kotlin" +
".serialization.Type\022\033\n\023is_instance_type_" +
"id\030\005 \001(\005\022D\n\014and_argument\030\006 \003(\0132..org.jet" +
"brains.kotlin.serialization.Expression\022C" +
"\n\013or_argument\030\007 \003(\0132..org.jetbrains.kotl" +
"in.serialization.Expression\".\n\rConstantV" +
"alue\022\010\n\004TRUE\020\000\022\t\n\005FALSE\020\001\022\010\n\004NULL\020\002*9\n\010M" +
"odality\022\t\n\005FINAL\020\000\022\010\n\004OPEN\020\001\022\014\n\010ABSTRACT" +
"\020\002\022\n\n\006SEALED\020\003*b\n\nVisibility\022\014\n\010INTERNAL",
"\020\000\022\013\n\007PRIVATE\020\001\022\r\n\tPROTECTED\020\002\022\n\n\006PUBLIC" +
"\020\003\022\023\n\017PRIVATE_TO_THIS\020\004\022\t\n\005LOCAL\020\005*Q\n\nMe" +
"mberKind\022\017\n\013DECLARATION\020\000\022\021\n\rFAKE_OVERRI" +
"DE\020\001\022\016\n\nDELEGATION\020\002\022\017\n\013SYNTHESIZED\020\003B\017B" +
"\rDebugProtoBuf"
};
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {

View File

@@ -0,0 +1,132 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: build-common/src/java_descriptors.debug.proto
package org.jetbrains.kotlin.serialization.java;
public final class DebugJavaClassProtoBuf {
private DebugJavaClassProtoBuf() {}
public static void registerAllExtensions(
org.jetbrains.kotlin.protobuf.ExtensionRegistry registry) {
registry.add(org.jetbrains.kotlin.serialization.java.DebugJavaClassProtoBuf.isStaticMethod);
registry.add(org.jetbrains.kotlin.serialization.java.DebugJavaClassProtoBuf.isPackagePrivateMethod);
registry.add(org.jetbrains.kotlin.serialization.java.DebugJavaClassProtoBuf.isStaticField);
registry.add(org.jetbrains.kotlin.serialization.java.DebugJavaClassProtoBuf.isPackagePrivateField);
registry.add(org.jetbrains.kotlin.serialization.java.DebugJavaClassProtoBuf.isPackagePrivateClass);
registry.add(org.jetbrains.kotlin.serialization.java.DebugJavaClassProtoBuf.isPackagePrivateConstructor);
}
public static final int IS_STATIC_METHOD_FIELD_NUMBER = 1000;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Function { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.serialization.DebugProtoBuf.Function,
java.lang.Boolean> isStaticMethod = org.jetbrains.kotlin.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
java.lang.Boolean.class,
null);
public static final int IS_PACKAGE_PRIVATE_METHOD_FIELD_NUMBER = 1001;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Function { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.serialization.DebugProtoBuf.Function,
java.lang.Boolean> isPackagePrivateMethod = org.jetbrains.kotlin.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
java.lang.Boolean.class,
null);
public static final int IS_STATIC_FIELD_FIELD_NUMBER = 1000;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Property { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property,
java.lang.Boolean> isStaticField = org.jetbrains.kotlin.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
java.lang.Boolean.class,
null);
public static final int IS_PACKAGE_PRIVATE_FIELD_FIELD_NUMBER = 1001;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Property { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property,
java.lang.Boolean> isPackagePrivateField = org.jetbrains.kotlin.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
java.lang.Boolean.class,
null);
public static final int IS_PACKAGE_PRIVATE_CLASS_FIELD_NUMBER = 1000;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Class { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.serialization.DebugProtoBuf.Class,
java.lang.Boolean> isPackagePrivateClass = org.jetbrains.kotlin.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
java.lang.Boolean.class,
null);
public static final int IS_PACKAGE_PRIVATE_CONSTRUCTOR_FIELD_NUMBER = 1000;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Constructor { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.serialization.DebugProtoBuf.Constructor,
java.lang.Boolean> isPackagePrivateConstructor = org.jetbrains.kotlin.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
java.lang.Boolean.class,
null);
public static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
getDescriptor() {
return descriptor;
}
private static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
descriptor;
static {
java.lang.String[] descriptorData = {
"\n-build-common/src/java_descriptors.debu" +
"g.proto\022\'org.jetbrains.kotlin.serializat" +
"ion.java\0320core/deserialization/src/descr" +
"iptors.debug.proto:G\n\020is_static_method\022," +
".org.jetbrains.kotlin.serialization.Func" +
"tion\030\350\007 \001(\010:P\n\031is_package_private_method" +
"\022,.org.jetbrains.kotlin.serialization.Fu" +
"nction\030\351\007 \001(\010:F\n\017is_static_field\022,.org.j" +
"etbrains.kotlin.serialization.Property\030\350" +
"\007 \001(\010:O\n\030is_package_private_field\022,.org.",
"jetbrains.kotlin.serialization.Property\030" +
"\351\007 \001(\010:L\n\030is_package_private_class\022).org" +
".jetbrains.kotlin.serialization.Class\030\350\007" +
" \001(\010:X\n\036is_package_private_constructor\022/" +
".org.jetbrains.kotlin.serialization.Cons" +
"tructor\030\350\007 \001(\010B\030B\026DebugJavaClassProtoBuf"
};
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
public org.jetbrains.kotlin.protobuf.ExtensionRegistry assignDescriptors(
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor root) {
descriptor = root;
return null;
}
};
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor[] {
org.jetbrains.kotlin.serialization.DebugProtoBuf.getDescriptor(),
}, assigner);
isStaticMethod.internalInit(descriptor.getExtensions().get(0));
isPackagePrivateMethod.internalInit(descriptor.getExtensions().get(1));
isStaticField.internalInit(descriptor.getExtensions().get(2));
isPackagePrivateField.internalInit(descriptor.getExtensions().get(3));
isPackagePrivateClass.internalInit(descriptor.getExtensions().get(4));
isPackagePrivateConstructor.internalInit(descriptor.getExtensions().get(5));
org.jetbrains.kotlin.serialization.DebugProtoBuf.getDescriptor();
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@@ -32582,6 +32582,28 @@ public final class DebugJsAstProtoBuf {
*/
org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
int index);
/**
* <code>optional int32 fileId = 3;</code>
*/
boolean hasFileId();
/**
* <code>optional int32 fileId = 3;</code>
*/
int getFileId();
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
boolean hasLocation();
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation();
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder();
}
/**
* Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.SwitchEntry}
@@ -32656,6 +32678,24 @@ public final class DebugJsAstProtoBuf {
statement_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry));
break;
}
case 24: {
bitField0_ |= 0x00000002;
fileId_ = input.readInt32();
break;
}
case 34: {
org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder subBuilder = null;
if (((bitField0_ & 0x00000004) == 0x00000004)) {
subBuilder = location_.toBuilder();
}
location_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.PARSER, extensionRegistry);
if (subBuilder != null) {
subBuilder.mergeFrom(location_);
location_ = subBuilder.buildPartial();
}
bitField0_ |= 0x00000004;
break;
}
}
}
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
@@ -32755,9 +32795,47 @@ public final class DebugJsAstProtoBuf {
return statement_.get(index);
}
public static final int FILEID_FIELD_NUMBER = 3;
private int fileId_;
/**
* <code>optional int32 fileId = 3;</code>
*/
public boolean hasFileId() {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>optional int32 fileId = 3;</code>
*/
public int getFileId() {
return fileId_;
}
public static final int LOCATION_FIELD_NUMBER = 4;
private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_;
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public boolean hasLocation() {
return ((bitField0_ & 0x00000004) == 0x00000004);
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
return location_;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
return location_;
}
private void initFields() {
label_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
statement_ = java.util.Collections.emptyList();
fileId_ = 0;
location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -32777,6 +32855,12 @@ public final class DebugJsAstProtoBuf {
return false;
}
}
if (hasLocation()) {
if (!getLocation().isInitialized()) {
memoizedIsInitialized = 0;
return false;
}
}
memoizedIsInitialized = 1;
return true;
}
@@ -32790,6 +32874,12 @@ public final class DebugJsAstProtoBuf {
for (int i = 0; i < statement_.size(); i++) {
output.writeMessage(2, statement_.get(i));
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeInt32(3, fileId_);
}
if (((bitField0_ & 0x00000004) == 0x00000004)) {
output.writeMessage(4, location_);
}
getUnknownFields().writeTo(output);
}
@@ -32807,6 +32897,14 @@ public final class DebugJsAstProtoBuf {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeMessageSize(2, statement_.get(i));
}
if (((bitField0_ & 0x00000002) == 0x00000002)) {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeInt32Size(3, fileId_);
}
if (((bitField0_ & 0x00000004) == 0x00000004)) {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeMessageSize(4, location_);
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
@@ -32918,6 +33016,7 @@ public final class DebugJsAstProtoBuf {
if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
getLabelFieldBuilder();
getStatementFieldBuilder();
getLocationFieldBuilder();
}
}
private static Builder create() {
@@ -32938,6 +33037,14 @@ public final class DebugJsAstProtoBuf {
} else {
statementBuilder_.clear();
}
fileId_ = 0;
bitField0_ = (bitField0_ & ~0x00000004);
if (locationBuilder_ == null) {
location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
} else {
locationBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000008);
return this;
}
@@ -32983,6 +33090,18 @@ public final class DebugJsAstProtoBuf {
} else {
result.statement_ = statementBuilder_.build();
}
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
to_bitField0_ |= 0x00000002;
}
result.fileId_ = fileId_;
if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
to_bitField0_ |= 0x00000004;
}
if (locationBuilder_ == null) {
result.location_ = location_;
} else {
result.location_ = locationBuilder_.build();
}
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
@@ -33028,6 +33147,12 @@ public final class DebugJsAstProtoBuf {
}
}
}
if (other.hasFileId()) {
setFileId(other.getFileId());
}
if (other.hasLocation()) {
mergeLocation(other.getLocation());
}
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
@@ -33045,6 +33170,12 @@ public final class DebugJsAstProtoBuf {
return false;
}
}
if (hasLocation()) {
if (!getLocation().isInitialized()) {
return false;
}
}
return true;
}
@@ -33423,6 +33554,154 @@ public final class DebugJsAstProtoBuf {
return statementBuilder_;
}
private int fileId_ ;
/**
* <code>optional int32 fileId = 3;</code>
*/
public boolean hasFileId() {
return ((bitField0_ & 0x00000004) == 0x00000004);
}
/**
* <code>optional int32 fileId = 3;</code>
*/
public int getFileId() {
return fileId_;
}
/**
* <code>optional int32 fileId = 3;</code>
*/
public Builder setFileId(int value) {
bitField0_ |= 0x00000004;
fileId_ = value;
onChanged();
return this;
}
/**
* <code>optional int32 fileId = 3;</code>
*/
public Builder clearFileId() {
bitField0_ = (bitField0_ & ~0x00000004);
fileId_ = 0;
onChanged();
return this;
}
private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder> locationBuilder_;
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public boolean hasLocation() {
return ((bitField0_ & 0x00000008) == 0x00000008);
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
if (locationBuilder_ == null) {
return location_;
} else {
return locationBuilder_.getMessage();
}
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public Builder setLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
if (locationBuilder_ == null) {
if (value == null) {
throw new NullPointerException();
}
location_ = value;
onChanged();
} else {
locationBuilder_.setMessage(value);
}
bitField0_ |= 0x00000008;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public Builder setLocation(
org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder builderForValue) {
if (locationBuilder_ == null) {
location_ = builderForValue.build();
onChanged();
} else {
locationBuilder_.setMessage(builderForValue.build());
}
bitField0_ |= 0x00000008;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public Builder mergeLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
if (locationBuilder_ == null) {
if (((bitField0_ & 0x00000008) == 0x00000008) &&
location_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance()) {
location_ =
org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.newBuilder(location_).mergeFrom(value).buildPartial();
} else {
location_ = value;
}
onChanged();
} else {
locationBuilder_.mergeFrom(value);
}
bitField0_ |= 0x00000008;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public Builder clearLocation() {
if (locationBuilder_ == null) {
location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
onChanged();
} else {
locationBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000008);
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder getLocationBuilder() {
bitField0_ |= 0x00000008;
onChanged();
return getLocationFieldBuilder().getBuilder();
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
if (locationBuilder_ != null) {
return locationBuilder_.getMessageOrBuilder();
} else {
return location_;
}
}
/**
* <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
*/
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder>
getLocationFieldBuilder() {
if (locationBuilder_ == null) {
locationBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder>(
getLocation(),
getParentForChildren(),
isClean());
location_ = null;
}
return locationBuilder_;
}
// @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.SwitchEntry)
}
@@ -49474,101 +49753,103 @@ public final class DebugJsAstProtoBuf {
"tch\022I\n\nexpression\030\001 \002(\01325.org.jetbrains." +
"kotlin.serialization.js.ast.Expression\022E" +
"\n\005entry\030\002 \003(\01326.org.jetbrains.kotlin.ser" +
"ialization.js.ast.SwitchEntry\"\234\001\n\013Switch" +
"ialization.js.ast.SwitchEntry\"\363\001\n\013Switch" +
"Entry\022D\n\005label\030\001 \001(\01325.org.jetbrains.kot" +
"lin.serialization.js.ast.Expression\022G\n\ts",
"tatement\030\002 \003(\01324.org.jetbrains.kotlin.se" +
"rialization.js.ast.Statement\"\225\001\n\005While\022H" +
"\n\tcondition\030\001 \002(\01325.org.jetbrains.kotlin" +
".serialization.js.ast.Expression\022B\n\004body" +
"\030\002 \002(\01324.org.jetbrains.kotlin.serializat" +
"ion.js.ast.Statement\"\227\001\n\007DoWhile\022H\n\tcond" +
"ition\030\001 \002(\01325.org.jetbrains.kotlin.seria" +
"lization.js.ast.Expression\022B\n\004body\030\002 \002(\013" +
"24.org.jetbrains.kotlin.serialization.js" +
".ast.Statement\"\304\003\n\003For\022I\n\tvariables\030\001 \001(",
"\01324.org.jetbrains.kotlin.serialization.j" +
"s.ast.StatementH\000\022K\n\nexpression\030\002 \001(\01325." +
"org.jetbrains.kotlin.serialization.js.as" +
"t.ExpressionH\000\022E\n\005empty\030\003 \001(\01324.org.jetb" +
"rains.kotlin.serialization.js.ast.EmptyI" +
"nitH\000\022H\n\tcondition\030\004 \001(\01325.org.jetbrains" +
"rialization.js.ast.Statement\022\016\n\006fileId\030\003" +
" \001(\005\022E\n\010location\030\004 \001(\01323.org.jetbrains.k" +
"otlin.serialization.js.ast.Location\"\225\001\n\005" +
"While\022H\n\tcondition\030\001 \002(\01325.org.jetbrains" +
".kotlin.serialization.js.ast.Expression\022" +
"H\n\tincrement\030\005 \001(\01325.org.jetbrains.kotli" +
"n.serialization.js.ast.Expression\022B\n\004bod" +
"y\030\006 \002(\01324.org.jetbrains.kotlin.serializa",
"tion.js.ast.StatementB\006\n\004init\"\013\n\tEmptyIn" +
"it\"\374\001\n\005ForIn\022\020\n\006nameId\030\001 \001(\005H\000\022K\n\nexpres" +
"sion\030\002 \001(\01325.org.jetbrains.kotlin.serial" +
"ization.js.ast.ExpressionH\000\022G\n\010iterable\030" +
"\003 \002(\01325.org.jetbrains.kotlin.serializati" +
"on.js.ast.Expression\022B\n\004body\030\004 \002(\01324.org" +
".jetbrains.kotlin.serialization.js.ast.S" +
"tatementB\007\n\005value\"\337\001\n\003Try\022F\n\010tryBlock\030\001 " +
"\002(\01324.org.jetbrains.kotlin.serialization" +
".js.ast.Statement\022D\n\ncatchBlock\030\002 \001(\01320.",
"org.jetbrains.kotlin.serialization.js.as" +
"t.Catch\022J\n\014finallyBlock\030\003 \001(\01324.org.jetb" +
"rains.kotlin.serialization.js.ast.Statem" +
"ent\"\224\001\n\005Catch\022G\n\tparameter\030\001 \002(\01324.org.j" +
"etbrains.kotlin.serialization.js.ast.Par" +
"ameter\022B\n\004body\030\002 \002(\01324.org.jetbrains.kot" +
"lin.serialization.js.ast.Statement\"\007\n\005Em" +
"pty\"\327\005\n\010Fragment\022R\n\017imported_module\030\001 \003(" +
"\01329.org.jetbrains.kotlin.serialization.j" +
"s.ast.ImportedModule\022G\n\014import_entry\030\002 \003",
"(\01321.org.jetbrains.kotlin.serialization." +
"js.ast.Import\022Q\n\021declaration_block\030\003 \001(\013" +
"26.org.jetbrains.kotlin.serialization.js" +
".ast.GlobalBlock\022L\n\014export_block\030\004 \001(\01326" +
".org.jetbrains.kotlin.serialization.js.a" +
"st.GlobalBlock\022Q\n\021initializer_block\030\005 \001(" +
"\01326.org.jetbrains.kotlin.serialization.j" +
"s.ast.GlobalBlock\022L\n\014name_binding\030\006 \003(\0132" +
"6.org.jetbrains.kotlin.serialization.js." +
"ast.NameBinding\022J\n\013class_model\030\007 \003(\01325.o",
"B\n\004body\030\002 \002(\01324.org.jetbrains.kotlin.ser" +
"ialization.js.ast.Statement\"\227\001\n\007DoWhile\022" +
"H\n\tcondition\030\001 \002(\01325.org.jetbrains.kotli" +
"n.serialization.js.ast.Expression\022B\n\004bod",
"y\030\002 \002(\01324.org.jetbrains.kotlin.serializa" +
"tion.js.ast.Statement\"\304\003\n\003For\022I\n\tvariabl" +
"es\030\001 \001(\01324.org.jetbrains.kotlin.serializ" +
"ation.js.ast.StatementH\000\022K\n\nexpression\030\002" +
" \001(\01325.org.jetbrains.kotlin.serializatio" +
"n.js.ast.ExpressionH\000\022E\n\005empty\030\003 \001(\01324.o" +
"rg.jetbrains.kotlin.serialization.js.ast" +
".ClassModel\022P\n\021module_expression\030\010 \003(\01325" +
".org.jetbrains.kotlin.serialization.js.a" +
"st.Expression\022N\n\rinline_module\030\t \003(\01327.o" +
".EmptyInitH\000\022H\n\tcondition\030\004 \001(\01325.org.je" +
"tbrains.kotlin.serialization.js.ast.Expr" +
"ession\022H\n\tincrement\030\005 \001(\01325.org.jetbrain",
"s.kotlin.serialization.js.ast.Expression" +
"\022B\n\004body\030\006 \002(\01324.org.jetbrains.kotlin.se" +
"rialization.js.ast.StatementB\006\n\004init\"\013\n\t" +
"EmptyInit\"\374\001\n\005ForIn\022\020\n\006nameId\030\001 \001(\005H\000\022K\n" +
"\nexpression\030\002 \001(\01325.org.jetbrains.kotlin" +
".serialization.js.ast.ExpressionH\000\022G\n\010it" +
"erable\030\003 \002(\01325.org.jetbrains.kotlin.seri" +
"alization.js.ast.Expression\022B\n\004body\030\004 \002(" +
"\01324.org.jetbrains.kotlin.serialization.j" +
"s.ast.StatementB\007\n\005value\"\337\001\n\003Try\022F\n\010tryB",
"lock\030\001 \002(\01324.org.jetbrains.kotlin.serial" +
"ization.js.ast.Statement\022D\n\ncatchBlock\030\002" +
" \001(\01320.org.jetbrains.kotlin.serializatio" +
"n.js.ast.Catch\022J\n\014finallyBlock\030\003 \001(\01324.o" +
"rg.jetbrains.kotlin.serialization.js.ast" +
".InlineModule\"\224\001\n\016ImportedModule\022\030\n\020exte" +
"rnal_name_id\030\001 \002(\005\022\030\n\020internal_name_id\030\002" +
" \002(\005\022N\n\017plain_reference\030\003 \001(\01325.org.jetb" +
"rains.kotlin.serialization.js.ast.Expres" +
"sion\"i\n\006Import\022\024\n\014signature_id\030\001 \002(\005\022I\n\n",
"expression\030\002 \002(\01325.org.jetbrains.kotlin." +
"serialization.js.ast.Expression\"3\n\013NameB" +
"inding\022\024\n\014signature_id\030\001 \002(\005\022\016\n\006nameId\030\002" +
" \002(\005\"\247\001\n\nClassModel\022\017\n\007name_id\030\001 \002(\005\022\025\n\r" +
"super_name_id\030\002 \001(\005\022\031\n\021interface_name_id" +
"\030\004 \003(\005\022V\n\026post_declaration_block\030\003 \001(\01326" +
".org.jetbrains.kotlin.serialization.js.a" +
"st.GlobalBlock\";\n\014InlineModule\022\024\n\014signat" +
"ure_id\030\001 \002(\005\022\025\n\rexpression_id\030\002 \002(\005\"\034\n\013S" +
"tringTable\022\r\n\005entry\030\001 \003(\t\"K\n\tNameTable\022>",
"\n\005entry\030\001 \003(\0132/.org.jetbrains.kotlin.ser" +
"ialization.js.ast.Name\"\263\001\n\004Name\022\021\n\ttempo" +
"rary\030\001 \002(\010\022\022\n\nidentifier\030\002 \001(\005\022\025\n\rlocal_" +
"name_id\030\003 \001(\005\022\027\n\010imported\030\004 \001(\010:\005false\022T" +
"\n\020special_function\030\005 \001(\0162:.org.jetbrains" +
".kotlin.serialization.js.ast.SpecialFunc" +
"tion\"\346\001\n\005Chunk\022L\n\014string_table\030\001 \002(\01326.o" +
".Statement\"\224\001\n\005Catch\022G\n\tparameter\030\001 \002(\0132" +
"4.org.jetbrains.kotlin.serialization.js." +
"ast.Parameter\022B\n\004body\030\002 \002(\01324.org.jetbra" +
"ins.kotlin.serialization.js.ast.Statemen" +
"t\"\007\n\005Empty\"\327\005\n\010Fragment\022R\n\017imported_modu",
"le\030\001 \003(\01329.org.jetbrains.kotlin.serializ" +
"ation.js.ast.ImportedModule\022G\n\014import_en" +
"try\030\002 \003(\01321.org.jetbrains.kotlin.seriali" +
"zation.js.ast.Import\022Q\n\021declaration_bloc" +
"k\030\003 \001(\01326.org.jetbrains.kotlin.serializa" +
"tion.js.ast.GlobalBlock\022L\n\014export_block\030" +
"\004 \001(\01326.org.jetbrains.kotlin.serializati" +
"on.js.ast.GlobalBlock\022Q\n\021initializer_blo" +
"ck\030\005 \001(\01326.org.jetbrains.kotlin.serializ" +
"ation.js.ast.GlobalBlock\022L\n\014name_binding",
"\030\006 \003(\01326.org.jetbrains.kotlin.serializat" +
"ion.js.ast.NameBinding\022J\n\013class_model\030\007 " +
"\003(\01325.org.jetbrains.kotlin.serialization" +
".js.ast.ClassModel\022P\n\021module_expression\030" +
"\010 \003(\01325.org.jetbrains.kotlin.serializati" +
"on.js.ast.Expression\022N\n\rinline_module\030\t " +
"\003(\01327.org.jetbrains.kotlin.serialization" +
".js.ast.InlineModule\"\224\001\n\016ImportedModule\022" +
"\030\n\020external_name_id\030\001 \002(\005\022\030\n\020internal_na" +
"me_id\030\002 \002(\005\022N\n\017plain_reference\030\003 \001(\01325.o",
"rg.jetbrains.kotlin.serialization.js.ast" +
".StringTable\022H\n\nname_table\030\002 \002(\01324.org.j" +
"etbrains.kotlin.serialization.js.ast.Nam",
"eTable\022E\n\010fragment\030\003 \002(\01323.org.jetbrains" +
".kotlin.serialization.js.ast.Fragment*@\n" +
"\013SideEffects\022\021\n\rAFFECTS_STATE\020\001\022\024\n\020DEPEN" +
"DS_ON_STATE\020\002\022\010\n\004PURE\020\003*?\n\016InlineStrateg" +
"y\022\017\n\013AS_FUNCTION\020\000\022\014\n\010IN_PLACE\020\001\022\016\n\nNOT_" +
"INLINE\020\002*\327\001\n\017SpecialFunction\022\032\n\026DEFINE_I" +
"NLINE_FUNCTION\020\001\022\021\n\rWRAP_FUNCTION\020\002\022\021\n\rT" +
"O_BOXED_CHAR\020\003\022\016\n\nUNBOX_CHAR\020\004\022\020\n\014SUSPEN" +
"D_CALL\020\005\022\024\n\020COROUTINE_RESULT\020\006\022\030\n\024COROUT" +
"INE_CONTROLLER\020\007\022\026\n\022COROUTINE_RECEIVER\020\010",
"\022\030\n\024SET_COROUTINE_RESULT\020\tB\024B\022DebugJsAst" +
"ProtoBuf"
".Expression\"i\n\006Import\022\024\n\014signature_id\030\001 " +
"\002(\005\022I\n\nexpression\030\002 \002(\01325.org.jetbrains." +
"kotlin.serialization.js.ast.Expression\"3" +
"\n\013NameBinding\022\024\n\014signature_id\030\001 \002(\005\022\016\n\006n" +
"ameId\030\002 \002(\005\"\247\001\n\nClassModel\022\017\n\007name_id\030\001 " +
"\002(\005\022\025\n\rsuper_name_id\030\002 \001(\005\022\031\n\021interface_" +
"name_id\030\004 \003(\005\022V\n\026post_declaration_block\030" +
"\003 \001(\01326.org.jetbrains.kotlin.serializati" +
"on.js.ast.GlobalBlock\";\n\014InlineModule\022\024\n",
"\014signature_id\030\001 \002(\005\022\025\n\rexpression_id\030\002 \002" +
"(\005\"\034\n\013StringTable\022\r\n\005entry\030\001 \003(\t\"K\n\tName" +
"Table\022>\n\005entry\030\001 \003(\0132/.org.jetbrains.kot" +
"lin.serialization.js.ast.Name\"\263\001\n\004Name\022\021" +
"\n\ttemporary\030\001 \002(\010\022\022\n\nidentifier\030\002 \001(\005\022\025\n" +
"\rlocal_name_id\030\003 \001(\005\022\027\n\010imported\030\004 \001(\010:\005" +
"false\022T\n\020special_function\030\005 \001(\0162:.org.je" +
"tbrains.kotlin.serialization.js.ast.Spec" +
"ialFunction\"\346\001\n\005Chunk\022L\n\014string_table\030\001 " +
"\002(\01326.org.jetbrains.kotlin.serialization",
".js.ast.StringTable\022H\n\nname_table\030\002 \002(\0132" +
"4.org.jetbrains.kotlin.serialization.js." +
"ast.NameTable\022E\n\010fragment\030\003 \002(\01323.org.je" +
"tbrains.kotlin.serialization.js.ast.Frag" +
"ment*@\n\013SideEffects\022\021\n\rAFFECTS_STATE\020\001\022\024" +
"\n\020DEPENDS_ON_STATE\020\002\022\010\n\004PURE\020\003*?\n\016Inline" +
"Strategy\022\017\n\013AS_FUNCTION\020\000\022\014\n\010IN_PLACE\020\001\022" +
"\016\n\nNOT_INLINE\020\002*\327\001\n\017SpecialFunction\022\032\n\026D" +
"EFINE_INLINE_FUNCTION\020\001\022\021\n\rWRAP_FUNCTION" +
"\020\002\022\021\n\rTO_BOXED_CHAR\020\003\022\016\n\nUNBOX_CHAR\020\004\022\020\n",
"\014SUSPEND_CALL\020\005\022\024\n\020COROUTINE_RESULT\020\006\022\030\n" +
"\024COROUTINE_CONTROLLER\020\007\022\026\n\022COROUTINE_REC" +
"EIVER\020\010\022\030\n\024SET_COROUTINE_RESULT\020\tB\024B\022Deb" +
"ugJsAstProtoBuf"
};
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
@@ -49803,7 +50084,7 @@ public final class DebugJsAstProtoBuf {
internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_fieldAccessorTable = new
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_descriptor,
new java.lang.String[] { "Label", "Statement", });
new java.lang.String[] { "Label", "Statement", "FileId", "Location", });
internal_static_org_jetbrains_kotlin_serialization_js_ast_While_descriptor =
getDescriptor().getMessageTypes().get(37);
internal_static_org_jetbrains_kotlin_serialization_js_ast_While_fieldAccessorTable = new

View File

@@ -1,3 +1,4 @@
import org.gradle.api.Project
import java.util.*
import java.io.File
@@ -9,13 +10,15 @@ import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
buildscript {
extra["defaultSnapshotVersion"] = "1.2-SNAPSHOT"
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.2.20-dev-524", onlySuccessBootstrap = false))
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.2.30-dev-672", onlySuccessBootstrap = false))
val repos = listOfNotNull(
bootstrapKotlinRepo,
"https://jcenter.bintray.com/",
"https://plugins.gradle.org/m2",
"http://repository.jetbrains.com/utils/")
"http://dl.bintray.com/kotlin/kotlinx",
"https://repo.gradle.org/gradle/libs-releases-local", // for native-platform
"https://jetbrains.bintray.com/intellij-third-party-dependencies") // for jflex
extra["repos"] = repos
@@ -77,16 +80,21 @@ dependencies {
}
val commonBuildDir = File(rootDir, "build")
val distDir = "$rootDir/dist"
val distKotlinHomeDir = "$distDir/kotlinc"
val distDir by extra("$rootDir/dist")
val distKotlinHomeDir by extra("$distDir/kotlinc")
val distLibDir = "$distKotlinHomeDir/lib"
val ideaPluginDir = "$distDir/artifacts/Kotlin"
val ideaUltimatePluginDir = "$distDir/artifacts/KotlinUltimate"
val commonLocalDataDir = "$rootDir/local"
val ideaSandboxDir = "$commonLocalDataDir/ideaSandbox"
val ideaUltimateSandboxDir = "$commonLocalDataDir/ideaUltimateSandbox"
val ideaPluginDir = "$distDir/artifacts/ideaPlugin/Kotlin"
val ideaUltimatePluginDir = "$distDir/artifacts/ideaUltimatePlugin/Kotlin"
extra["distDir"] = distDir
extra["distKotlinHomeDir"] = distKotlinHomeDir
// TODO: use "by extra()" syntax where possible
extra["distLibDir"] = project.file(distLibDir)
extra["libsDir"] = project.file(distLibDir)
extra["commonLocalDataDir"] = project.file(commonLocalDataDir)
extra["ideaSandboxDir"] = project.file(ideaSandboxDir)
extra["ideaUltimateSandboxDir"] = project.file(ideaUltimateSandboxDir)
extra["ideaPluginDir"] = project.file(ideaPluginDir)
extra["ideaUltimatePluginDir"] = project.file(ideaUltimatePluginDir)
extra["isSonatypeRelease"] = false
@@ -105,6 +113,10 @@ extra["JDK_17"] = jdkPath("1.7")
extra["JDK_18"] = jdkPath("1.8")
extra["JDK_9"] = jdkPathIfFound("9")
rootProject.apply {
from(rootProject.file("versions.gradle.kts"))
}
extra["versions.protobuf-java"] = "2.6.1"
extra["versions.javax.inject"] = "1"
extra["versions.jsr305"] = "1.3.9"
@@ -114,9 +126,57 @@ extra["versions.junit"] = "4.12"
extra["versions.javaslang"] = "2.0.6"
extra["versions.ant"] = "1.8.2"
extra["versions.android"] = "2.3.1"
extra["versions.kotlinx-coroutines-core"] = "0.20"
extra["versions.kotlinx-coroutines-jdk8"] = "0.20"
extra["versions.json"] = "20160807"
extra["versions.native-platform"] = "0.14"
extra["versions.ant-launcher"] = "1.8.0"
extra["versions.robolectric"] = "3.1"
extra["versions.org.springframework"] = "4.2.0.RELEASE"
extra["versions.jflex"] = "1.7.0"
extra["ideaCoreSdkJars"] = arrayOf("annotations", "asm-all", "guava", "intellij-core", "jdom", "jna", "log4j", "picocontainer",
"snappy-in-java", "streamex", "trove4j", "xpp3-1.1.4-min", "xstream")
val markdownVer = "4054 - Kotlin 1.0.2-dev-566".replace(" ", "%20") // fixed here, was last with "status:SUCCESS,tag:forKotlin"
extra["markdownParserRepo"] = "https://teamcity.jetbrains.com/guestAuth/repository/download/IntelliJMarkdownParser_Build/$markdownVer/([artifact]_[ext]/)[artifact](.[ext])"
fun Project.getBooleanProperty(name: String): Boolean? = this.findProperty(name)?.let {
val v = it.toString()
if (v.isBlank()) true
else v.toBoolean()
}
val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
val intellijUltimateEnabled = project.getBooleanProperty("intellijUltimateEnabled") ?: isTeamcityBuild
val intellijSeparateSdks = project.getBooleanProperty("intellijSeparateSdks") ?: false
extra["intellijUltimateEnabled"] = intellijUltimateEnabled
extra["intellijSeparateSdks"] = intellijSeparateSdks
extra["IntellijCoreDependencies"] =
listOf("annotations",
"asm-all",
"guava-21.0",
"jdom",
"jna",
"log4j",
"picocontainer",
"snappy-in-java-0.5.1",
"streamex",
"trove4j",
"xpp3-1.1.4-min",
"xstream-1.4.8")
extra["nativePlatformVariants"] =
listOf("windows-amd64",
"windows-i386",
"osx-amd64",
"osx-i386",
"linux-amd64",
"linux-i386",
"freebsd-amd64-libcpp",
"freebsd-amd64-libstdcpp",
"freebsd-i386-libcpp",
"freebsd-i386-libstdcpp")
extra["compilerModules"] = arrayOf(
":compiler:util",
@@ -192,21 +252,6 @@ apply {
}
}
val importedAntTasksPrefix = "imported-ant-update-"
// TODO: check the reasons of import conflict with xerces
//ant.importBuild("$rootDir/update_dependencies.xml") { antTaskName -> importedAntTasksPrefix + antTaskName }
tasks.matching { task ->
task.name.startsWith(importedAntTasksPrefix)
}.forEach {
it.group = "Imported ant"
}
//task("update-dependencies") {
// dependsOn(tasks.getByName(importedAntTasksPrefix + "update"))
//}
fun Project.allprojectsRecursive(body: Project.() -> Unit) {
this.body()
this.subprojects { allprojectsRecursive(body) }
@@ -237,11 +282,16 @@ allprojects {
for (repo in (rootProject.extra["repos"] as List<String>)) {
maven { setUrl(repo) }
}
ivy {
artifactPattern(rootProject.extra["markdownParserRepo"] as String)
}
intellijSdkRepo(project)
androidDxJarRepo(project)
}
configureJvmProject(javaHome!!, jvmTarget!!)
val commonCompilerArgs = listOf("-Xallow-kotlin-package")
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
kotlinOptions {
languageVersion = kotlinLanguageVersion
@@ -283,6 +333,18 @@ allprojects {
if (javaHome != defaultJavaHome || jvmTarget != defaultJvmTarget) {
configureJvmProject(javaHome!!, jvmTarget!!)
}
fun File.toProjectRootRelativePathOrSelf() = (relativeToOrNull(rootDir)?.takeUnless { it.startsWith("..") } ?: this).path
fun FileCollection.printClassPath(role: String) =
println("${project.path} $role classpath:\n ${joinToString("\n ") { it.toProjectRootRelativePathOrSelf() } }")
try { the<JavaPluginConvention>() } catch (_: UnknownDomainObjectException) { null }?.let { javaConvention ->
task("printCompileClasspath") { doFirst { javaConvention.sourceSets["main"].compileClasspath.printClassPath("compile") } }
task("printRuntimeClasspath") { doFirst { javaConvention.sourceSets["main"].runtimeClasspath.printClassPath("runtime") } }
task("printTestCompileClasspath") { doFirst { javaConvention.sourceSets["test"].compileClasspath.printClassPath("test compile") } }
task("printTestRuntimeClasspath") { doFirst { javaConvention.sourceSets["test"].runtimeClasspath.printClassPath("test runtime") } }
}
}
}
@@ -293,14 +355,13 @@ task<Copy>("dist") {
}
val compilerCopyTask = task<Copy>("idea-plugin-copy-compiler") {
dependsOnTaskIfExistsRec("dist")
shouldRunAfter(":dist")
into(ideaPluginDir)
from(distDir) { include("kotlinc/**") }
}
task<Copy>("ideaPlugin") {
dependsOn(compilerCopyTask)
dependsOnTaskIfExistsRec("idea-plugin")
shouldRunAfter(":prepare:idea-plugin:idea-plugin")
into("$ideaPluginDir/lib")
}
@@ -313,6 +374,13 @@ tasks {
}
}
// TODO: copied from TeamCityBuild.xml (with ultimate-related modification), consider removing after migrating from it
"cleanupArtifacts" {
doLast {
delete(ideaPluginDir)
delete(ideaUltimatePluginDir)
}
}
"coreLibsTest" {
(coreLibProjects + listOf(
@@ -343,6 +411,7 @@ tasks {
"jsCompilerTest" {
dependsOn(":js:js.tests:test")
dependsOn(":js:js.tests:runMocha")
}
"scriptingTest" {
@@ -356,6 +425,7 @@ tasks {
dependsOn("scriptingTest")
dependsOn(":kotlin-build-common:test")
dependsOn(":compiler:incremental-compilation-impl:test")
}
"examplesTest" {
@@ -437,19 +507,70 @@ tasks {
"check" { dependsOn("test") }
}
fun CopySpec.compilerScriptPermissionsSpec() {
filesMatching("bin/*") { mode = 0b111101101 }
filesMatching("bin/*.bat") { mode = 0b110100100 }
}
val zipCompiler by task<Zip> {
destinationDir = file(distDir)
archiveName = "kotlin-compiler-$kotlinVersion.zip"
from(distKotlinHomeDir) {
into("kotlinc")
compilerScriptPermissionsSpec()
}
doLast {
logger.lifecycle("Compiler artifacts packed to $archivePath")
}
}
val zipTestData by task<Zip> {
destinationDir = file(distDir)
archiveName = "kotlin-test-data.zip"
from("compiler/testData") { into("compiler") }
from("idea/testData") { into("ide") }
from("idea/idea-completion/testData") { into("ide/completion") }
doLast {
logger.lifecycle("Test data packed to $archivePath")
}
}
val zipPlugin by task<Zip> {
val src = when (project.findProperty("pluginArtifactDir") as String?) {
"Kotlin" -> ideaPluginDir
"KotlinUltimate" -> ideaUltimatePluginDir
null -> if (project.hasProperty("ultimate")) ideaUltimatePluginDir else ideaPluginDir
else -> error("Unsupported plugin artifact dir")
}
val destPath = project.findProperty("pluginZipPath") as String?
val dest = File(destPath ?: "$buildDir/kotlin-plugin.zip")
destinationDir = dest.parentFile
archiveName = dest.name
doFirst {
if (destPath == null) throw GradleException("Specify target zip path with 'pluginZipPath' property")
}
into("Kotlin") {
from("$src/kotlinc") {
into("kotlinc")
compilerScriptPermissionsSpec()
}
from(src) {
exclude("kotlinc")
}
}
doLast {
logger.lifecycle("Plugin artifacts packed to $archivePath")
}
}
configure<IdeaModel> {
module {
excludeDirs = files(
project.buildDir,
commonLocalDataDir,
".gradle",
"dependencies",
"dist",
"ideaSDK/bin",
"ideaSDK/androidSDK",
"ideaSDK/config",
"ideaSDK/config-idea",
"ideaSDK/system",
"ideaSDK/system-idea"
"dist"
).toSet()
}
}

1048
build.xml

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,8 @@ buildscript {
val buildSrcKotlinVersion: String by extra(findProperty("buildSrc.kotlin.version")?.toString() ?: embeddedKotlinVersion)
val buildSrcKotlinRepo: String? by extra(findProperty("buildSrc.kotlin.repo") as String?)
extra["versions.shadow"] = "2.0.1"
extra["versions.intellij-plugin"] = "0.3.0-SNAPSHOT"
extra["versions.native-platform"] = "0.14"
repositories {
buildSrcKotlinRepo?.let {
@@ -29,19 +31,40 @@ plugins {
`kotlin-dsl`
}
fun Project.getBooleanProperty(name: String): Boolean? = this.findProperty(name)?.let {
val v = it.toString()
if (v.isBlank()) true
else v.toBoolean()
}
rootProject.apply {
from(rootProject.file("../versions.gradle.kts"))
}
val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
val intellijUltimateEnabled by extra(project.getBooleanProperty("intellijUltimateEnabled") ?: isTeamcityBuild)
val intellijSeparateSdks by extra(project.getBooleanProperty("intellijSeparateSdks") ?: false)
extra["intellijRepo"] = "https://www.jetbrains.com/intellij-repository"
extra["intellijReleaseType"] = "releases" // or "snapshots"
extra["versions.androidDxSources"] = "5.0.0_r2"
extra["customDepsOrg"] = "kotlin.build.custom.deps"
repositories {
extra["buildSrcKotlinRepo"]?.let {
maven(url = it)
}
maven(url = "https://dl.bintray.com/kotlin/kotlin-dev") // for dex-method-list
// maven { setUrl("https://repo.gradle.org/gradle/libs-releases-local") }
maven(url = "https://repo.gradle.org/gradle/libs-releases-local") // for native-platform
jcenter()
}
dependencies {
compile(files("../dependencies/native-platform-uberjar.jar"))
compile("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
compile("net.rubygrapefruit:native-platform-windows-amd64:${property("versions.native-platform")}")
compile("net.rubygrapefruit:native-platform-windows-i386:${property("versions.native-platform")}")
compile("com.jakewharton.dex:dex-method-list:2.0.0-alpha")
// compile("net.rubygrapefruit:native-platform:0.14")
// TODO: adding the dep to the plugin breaks the build unexpectedly, resolve and uncomment
// compile("org.jetbrains.kotlin:kotlin-gradle-plugin:${rootProject.extra["bootstrap_kotlin_version"]}")
compile("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
@@ -54,3 +77,5 @@ samWithReceiver {
fun Project.`samWithReceiver`(configure: org.jetbrains.kotlin.samWithReceiver.gradle.SamWithReceiverExtension.() -> Unit): Unit =
extensions.configure("samWithReceiver", configure)
tasks["build"].dependsOn(":prepare-deps:android-dx:build", ":prepare-deps:intellij-sdk:build")

View File

@@ -0,0 +1,106 @@
import org.gradle.api.publish.ivy.internal.artifact.DefaultIvyArtifact
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyConfiguration
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyPublicationIdentity
import org.gradle.api.publish.ivy.internal.publisher.IvyDescriptorFileGenerator
import java.io.File
import org.gradle.internal.os.OperatingSystem
import org.gradle.jvm.tasks.Jar
val toolsOs by lazy {
when {
OperatingSystem.current().isWindows -> "windows"
OperatingSystem.current().isMacOsX -> "macosx"
OperatingSystem.current().isLinux -> "linux"
else -> {
logger.error("Unknown operating system for android tools: ${OperatingSystem.current().name}")
""
}
}
}
val buildToolsVersion = rootProject.extra["versions.androidBuildTools"] as String
val dxSourcesVersion = rootProject.extra["versions.androidDxSources"] as String
repositories {
ivy {
artifactPattern("https://dl-ssl.google.com/android/repository/[artifact]_[revision](-[classifier]).[ext]")
artifactPattern("https://android.googlesource.com/platform/dalvik/+archive/android-$dxSourcesVersion/[artifact].[ext]")
}
}
val customDepsRepoDir = File(buildDir, "repo")
val customDepsOrg: String by rootProject.extra
val dxModuleName = "android-dx"
val dxRevision = buildToolsVersion
val dxRepoModuleDir = File(customDepsRepoDir, "$customDepsOrg/$dxModuleName/$dxRevision")
val buildToolsZip by configurations.creating
val dxSourcesTar by configurations.creating
dependencies {
buildToolsZip("google:build-tools:$buildToolsVersion:$toolsOs@zip")
dxSourcesTar("google:dx:0@tar.gz")
}
val unzipDxJar by tasks.creating {
dependsOn(buildToolsZip)
inputs.files(buildToolsZip)
outputs.files(File(dxRepoModuleDir, "dx.jar"))
doFirst {
project.copy {
from(zipTree(buildToolsZip.singleFile).files)
include("**/dx.jar")
into(dxRepoModuleDir)
}
}
}
val dxSourcesTargetDir = File(buildDir, "dx_src")
val untarDxSources by tasks.creating {
dependsOn(dxSourcesTar)
inputs.files(dxSourcesTar)
outputs.dir(dxSourcesTargetDir)
doFirst {
project.copy {
from(tarTree(dxSourcesTar.singleFile))
include("src/**")
includeEmptyDirs = false
into(dxSourcesTargetDir)
}
}
}
val prepareDxSourcesJar by tasks.creating(Jar::class) {
dependsOn(untarDxSources)
from("$dxSourcesTargetDir/src")
destinationDir = dxRepoModuleDir
baseName = "dx"
classifier = "sources"
}
val prepareIvyXml by tasks.creating {
dependsOn(unzipDxJar, prepareDxSourcesJar)
inputs.files(unzipDxJar, prepareDxSourcesJar)
val ivyFile = File(dxRepoModuleDir, "$dxModuleName.ivy.xml")
outputs.file(ivyFile)
doLast {
with(IvyDescriptorFileGenerator(DefaultIvyPublicationIdentity(customDepsOrg, dxModuleName, dxRevision))) {
addConfiguration(DefaultIvyConfiguration("default"))
addConfiguration(DefaultIvyConfiguration("sources"))
addArtifact(DefaultIvyArtifact(File(dxRepoModuleDir, "dx.jar"), "dx", "jar", "jar", null).also { it.conf = "default" })
addArtifact(DefaultIvyArtifact(File(dxRepoModuleDir, "dx-sources.jar"), "dx", "jar", "sources", "sources").also { it.conf = "sources" })
writeTo(ivyFile)
}
}
}
val build by tasks.creating {
dependsOn(unzipDxJar, prepareDxSourcesJar, prepareIvyXml)
}
val clean by tasks.creating(Delete::class) {
delete(dxRepoModuleDir)
delete(buildDir)
}

View File

@@ -0,0 +1,223 @@
@file:Suppress("PropertyName")
import org.gradle.api.publish.ivy.internal.artifact.DefaultIvyArtifact
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyConfiguration
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyPublicationIdentity
import org.gradle.api.publish.ivy.internal.publisher.IvyDescriptorFileGenerator
import java.io.File
import org.gradle.internal.os.OperatingSystem
val intellijUltimateEnabled: Boolean by rootProject.extra
val intellijRepo: String by rootProject.extra
val intellijReleaseType: String by rootProject.extra
val intellijVersion = rootProject.extra["versions.intellijSdk"] as String
val androidStudioRelease = rootProject.findProperty("versions.androidStudioRelease") as String?
val androidStudioBuild = rootProject.findProperty("versions.androidStudioBuild") as String?
val intellijSeparateSdks: Boolean by rootProject.extra
val installIntellijCommunity = !intellijUltimateEnabled || intellijSeparateSdks
val installIntellijUltimate = intellijUltimateEnabled
logger.info("intellijUltimateEnabled: $intellijUltimateEnabled")
logger.info("intellijVersion: $intellijVersion")
logger.info("androidStudioRelease: $androidStudioRelease")
logger.info("androidStudioBuild: $androidStudioBuild")
logger.info("intellijSeparateSdks: $intellijSeparateSdks")
logger.info("installIntellijCommunity: $installIntellijCommunity")
logger.info("installIntellijUltimate: $installIntellijUltimate")
val studioOs by lazy {
when {
OperatingSystem.current().isWindows -> "windows"
OperatingSystem.current().isMacOsX -> "mac"
OperatingSystem.current().isLinux -> "linux"
else -> {
logger.error("Unknown operating system for android tools: ${OperatingSystem.current().name}")
""
}
}
}
repositories {
if (androidStudioRelease != null) {
ivy {
artifactPattern("https://dl.google.com/dl/android/studio/ide-zips/$androidStudioRelease/[artifact]-[revision]-$studioOs.zip")
}
}
maven { setUrl("$intellijRepo/$intellijReleaseType") }
maven { setUrl("https://plugins.jetbrains.com/maven") }
}
val intellij by configurations.creating
val intellijUltimate by configurations.creating
val sources by configurations.creating
val `jps-standalone` by configurations.creating
val `jps-build-test` by configurations.creating
val `intellij-core` by configurations.creating
val `plugins-NodeJS` by configurations.creating
val customDepsRepoDir = File(buildDir, "repo")
val customDepsOrg: String by rootProject.extra
val customDepsRevision = intellijVersion
val customDepsRepoModulesDir = File(customDepsRepoDir, "$customDepsOrg/$customDepsRevision")
val repoDir = customDepsRepoModulesDir
dependencies {
if (androidStudioRelease != null) {
intellij("google:android-studio-ide:$androidStudioBuild")
} else {
if (installIntellijCommunity) {
intellij("com.jetbrains.intellij.idea:ideaIC:$intellijVersion")
}
if (installIntellijUltimate) {
intellijUltimate("com.jetbrains.intellij.idea:ideaIU:$intellijVersion")
}
}
sources("com.jetbrains.intellij.idea:ideaIC:$intellijVersion:sources@jar")
`jps-standalone`("com.jetbrains.intellij.idea:jps-standalone:$intellijVersion")
`jps-build-test`("com.jetbrains.intellij.idea:jps-build-test:$intellijVersion")
`intellij-core`("com.jetbrains.intellij.idea:intellij-core:$intellijVersion")
if (intellijUltimateEnabled) {
`plugins-NodeJS`("com.jetbrains.plugins:NodeJS:${rootProject.extra["versions.idea.NodeJS"]}@zip")
}
}
fun Task.configureExtractFromConfigurationTask(sourceConfig: Configuration,
pathRemap: (String) -> String = { it },
extractor: (Configuration) -> Any) {
dependsOn(sourceConfig)
inputs.files(sourceConfig)
val targetDir = File(repoDir, sourceConfig.name)
outputs.dirs(targetDir)
doFirst {
project.copy {
from(extractor(sourceConfig))
into(targetDir)
eachFile {
path = pathRemap(path)
}
}
}
}
fun removePathPrefix(path: String): String {
if (androidStudioRelease == null) return path
val slashes = if (studioOs == "mac") 2 else 1
var result = path
repeat(slashes) {
result = result.substringAfter('/')
}
return result
}
val unzipIntellijSdk by tasks.creating {
configureExtractFromConfigurationTask(intellij, pathRemap = { removePathPrefix(it) }) { zipTree(it.singleFile) }
}
val unzipIntellijUltimateSdk by tasks.creating { configureExtractFromConfigurationTask(intellijUltimate) { zipTree(it.singleFile) } }
val unzipIntellijCore by tasks.creating { configureExtractFromConfigurationTask(`intellij-core`) { zipTree(it.singleFile) } }
val unzipJpsStandalone by tasks.creating { configureExtractFromConfigurationTask(`jps-standalone`) { zipTree(it.singleFile) } }
val copyIntellijSdkSources by tasks.creating {
configureExtractFromConfigurationTask(sources) { it.singleFile }
}
val copyJpsBuildTest by tasks.creating { configureExtractFromConfigurationTask(`jps-build-test`) { it.singleFile } }
val unzipNodeJSPlugin by tasks.creating { configureExtractFromConfigurationTask(`plugins-NodeJS`) { zipTree(it.singleFile) } }
fun writeIvyXml(moduleName: String, fileName: String, jarFiles: FileCollection, baseDir: File, sourcesJar: File?) {
with(IvyDescriptorFileGenerator(DefaultIvyPublicationIdentity(customDepsOrg, moduleName, intellijVersion))) {
addConfiguration(DefaultIvyConfiguration("default"))
addConfiguration(DefaultIvyConfiguration("sources"))
jarFiles.asFileTree.files.forEach {
if (it.isFile && it.extension == "jar") {
val relativeName = it.toRelativeString(baseDir).removeSuffix(".jar")
addArtifact(DefaultIvyArtifact(it, relativeName, "jar", "jar", null).also { it.conf = "default" })
}
}
if (sourcesJar != null) {
val sourcesArtifactName = sourcesJar.name.removeSuffix(".jar").substringBefore("-")
addArtifact(DefaultIvyArtifact(sourcesJar, sourcesArtifactName, "jar", "sources", "sources").also { it.conf = "sources" })
}
writeTo(File(customDepsRepoModulesDir, "$fileName.ivy.xml"))
}
}
val prepareIvyXmls by tasks.creating {
dependsOn(unzipIntellijCore, unzipJpsStandalone, copyIntellijSdkSources, copyJpsBuildTest)
val intellijSdkDir = File(repoDir, intellij.name)
val intellijUltimateSdkDir = File(repoDir, intellijUltimate.name)
if (installIntellijCommunity) {
dependsOn(unzipIntellijSdk)
inputs.dir(intellijSdkDir)
outputs.file(File(repoDir, "${intellij.name}.ivy.xml"))
}
if (installIntellijUltimate) {
dependsOn(unzipIntellijUltimateSdk)
inputs.dir(intellijUltimateSdkDir)
outputs.file(File(repoDir, "${intellijUltimate.name}.ivy.xml"))
}
val flatDeps = listOf(`intellij-core`, `jps-standalone`, `jps-build-test`)
flatDeps.forEach {
inputs.dir(File(repoDir, it.name))
outputs.file(File(repoDir, "${it.name}.ivy.xml"))
}
inputs.dir(File(repoDir, sources.name))
if (intellijUltimateEnabled) {
dependsOn(unzipNodeJSPlugin)
inputs.dir(File(repoDir, `plugins-NodeJS`.name))
outputs.file(File(repoDir, "${`plugins-NodeJS`.name}.ivy.xml"))
}
doFirst {
val sourcesFile = if (sources.isEmpty) null else File(repoDir, "${sources.name}/${sources.singleFile.name}")
if (installIntellijCommunity) {
writeIvyXml(intellij.name, intellij.name,
files("$intellijSdkDir/lib/").filter { !it.name.startsWith("kotlin-") },
File(intellijSdkDir, "lib"),
sourcesFile)
File(intellijSdkDir, "plugins").listFiles { it: File -> it.isDirectory }.forEach {
writeIvyXml(it.name, "intellij.plugin.${it.name}", files("$it/lib/"), File(it, "lib"), sourcesFile)
}
}
if (installIntellijUltimate) {
writeIvyXml(intellij.name /* important! the module name should be "intellij" */ , intellijUltimate.name,
files("$intellijUltimateSdkDir/lib/").filter { !it.name.startsWith("kotlin-") },
File(intellijUltimateSdkDir, "lib"),
sourcesFile)
File(intellijUltimateSdkDir, "plugins").listFiles { it: File -> it.isDirectory }.forEach {
writeIvyXml(it.name, "intellijUltimate.plugin.${it.name}", files("$it/lib/"), File(it, "lib"), sourcesFile)
}
}
flatDeps.forEach {
writeIvyXml(it.name, it.name, files("$repoDir/${it.name}"), File(repoDir, it.name), sourcesFile)
}
if (intellijUltimateEnabled) {
val nodeJsBaseDir = "${`plugins-NodeJS`.name}/NodeJS/lib"
writeIvyXml("NodeJS", `plugins-NodeJS`.name, files("$repoDir/$nodeJsBaseDir"), File(repoDir, nodeJsBaseDir), sourcesFile)
}
}
}
val build by tasks.creating {
dependsOn(prepareIvyXmls)
}
val clean by tasks.creating(Delete::class) {
delete(customDepsRepoModulesDir)
delete(buildDir)
}

3
buildSrc/settings.gradle Normal file
View File

@@ -0,0 +1,3 @@
include "prepare-deps:android-dx",
"prepare-deps:intellij-sdk"

View File

@@ -0,0 +1,14 @@
@file:Suppress("unused") // usages in build scripts are not tracked properly
import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.IvyArtifactRepository
import org.gradle.kotlin.dsl.extra
fun RepositoryHandler.androidDxJarRepo(project: Project): IvyArtifactRepository = ivy {
val baseDir = File("${project.rootDir}/buildSrc/prepare-deps/android-dx/build/repo")
ivyPattern("${baseDir.canonicalPath}/[organisation]/[module]/[revision]/[module].ivy.xml")
artifactPattern("${baseDir.canonicalPath}/[organisation]/[module]/[revision]/[artifact](-[classifier]).jar")
}
fun Project.androidDxJar() = "kotlin.build.custom.deps:android-dx:${rootProject.extra["versions.androidBuildTools"]}"

View File

@@ -1,13 +1,17 @@
@file:Suppress("unused") // usages in build scripts are not tracked properly
import groovy.lang.Closure
import org.gradle.api.*
import org.gradle.api.tasks.*
import org.gradle.kotlin.dsl.*
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.internal.AbstractTask
import org.gradle.jvm.tasks.Jar
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.SourceSetOutput
import org.gradle.kotlin.dsl.creating
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.the
import java.io.File
inline fun <reified T : Task> Project.task(noinline configuration: T.() -> Unit) = tasks.creating(T::class, configuration)
@@ -16,26 +20,6 @@ fun Project.callGroovy(name: String, vararg args: Any?): Any? {
return (property(name) as Closure<*>).call(*args)
}
fun AbstractTask.dependsOnTaskIfExists(task: String, project: Project?, parentProject: Project?) {
val thisTask = this
val p = project ?: this.project
p.afterEvaluate {
p.tasks.firstOrNull { it.name == task }?.also {
if (parentProject != null) {
parentProject.evaluationDependsOn(p.path)
}
thisTask.dependsOn(it)
}
}
}
fun AbstractTask.dependsOnTaskIfExistsRec(task: String, project: Project? = null, parentProject: Project? = null) {
dependsOnTaskIfExists(task, project, parentProject)
(project ?: this.project).subprojects.forEach {
dependsOnTaskIfExistsRec(task, it, this.project)
}
}
inline fun<T: Any> Project.withJavaPlugin(crossinline body: () -> T?): T? {
var res: T? = null
pluginManager.withPlugin("java") {

View File

@@ -2,7 +2,6 @@
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.file.ConfigurableFileCollection
@@ -14,14 +13,24 @@ import java.io.File
fun Project.commonDep(coord: String): String {
val parts = coord.split(':')
return when (parts.size) {
1 -> "$coord:$coord:${rootProject.extra["versions.$coord"]}"
2 -> "${parts[0]}:${parts[1]}:${rootProject.extra["versions.${parts[1]}"]}"
1 -> "$coord:$coord:${commonVer(coord, coord)}"
2 -> "${parts[0]}:${parts[1]}:${commonVer(parts[0], parts[1])}"
3 -> coord
else -> throw IllegalArgumentException("Illegal maven coordinates: $coord")
}
}
fun Project.commonDep(group: String, artifact: String): String = "$group:$artifact:${rootProject.extra["versions.$artifact"]}"
fun Project.commonDep(group: String, artifact: String, vararg suffixesAndClassifiers: String): String {
val (classifiers, artifactSuffixes) = suffixesAndClassifiers.partition { it.startsWith(':') }
return "$group:$artifact${artifactSuffixes.joinToString("")}:${commonVer(group, artifact)}${classifiers.joinToString("")}"
}
fun Project.commonVer(group: String, artifact: String) =
when {
rootProject.extra.has("versions.$artifact") -> rootProject.extra["versions.$artifact"]
rootProject.extra.has("versions.$group") -> rootProject.extra["versions.$group"]
else -> throw GradleException("Neither versions.$artifact nor versions.$group is defined in the root project's extra")
}
fun Project.preloadedDeps(vararg artifactBaseNames: String, baseDir: File = File(rootDir, "dependencies"), subdir: String? = null, optional: Boolean = false): ConfigurableFileCollection {
val dir = if (subdir != null) File(baseDir, subdir) else baseDir
@@ -44,25 +53,6 @@ fun Project.ideaUltimatePreloadedDeps(vararg artifactBaseNames: String, subdir:
else files()
}
fun Project.ideaSdkDeps(vararg artifactBaseNames: String, subdir: String = "lib", optional: Boolean = false): ConfigurableFileCollection =
preloadedDeps(*artifactBaseNames, baseDir = File(rootDir, "ideaSDK"), subdir = subdir, optional = optional)
fun Project.ideaUltimateSdkDeps(vararg artifactBaseNames: String, subdir: String = "lib"): ConfigurableFileCollection {
val ultimateSdkDir = File(rootDir, "ultimate", "ideaSDK")
return if (ultimateSdkDir.isDirectory) preloadedDeps(*artifactBaseNames, baseDir = ultimateSdkDir, subdir = subdir)
else files()
}
fun Project.ideaSdkCoreDeps(vararg artifactBaseNames: String): ConfigurableFileCollection = ideaSdkDeps(*artifactBaseNames, subdir = "core")
fun Project.ideaUltimateSdkCoreDeps(vararg artifactBaseNames: String): ConfigurableFileCollection = ideaUltimateSdkDeps(*artifactBaseNames, subdir = "core")
fun Project.ideaPluginDeps(vararg artifactBaseNames: String, plugin: String, subdir: String = "lib", optional: Boolean = false): ConfigurableFileCollection =
ideaSdkDeps(*artifactBaseNames, subdir = "plugins/$plugin/$subdir", optional = optional)
fun Project.ideaUltimatePluginDeps(vararg artifactBaseNames: String, plugin: String, subdir: String = "lib"): ConfigurableFileCollection =
ideaUltimateSdkDeps(*artifactBaseNames, subdir = "plugins/$plugin/$subdir")
fun Project.kotlinDep(artifactBaseName: String, version: String): String = "org.jetbrains.kotlin:kotlin-$artifactBaseName:$version"
fun DependencyHandler.projectDist(name: String): ProjectDependency = project(name, configuration = "distJar").apply { isTransitive = false }
@@ -72,15 +62,15 @@ fun DependencyHandler.projectArchives(name: String): ProjectDependency = project
fun DependencyHandler.projectClasses(name: String): ProjectDependency = project(name, configuration = "classes-dirs")
val protobufLiteProject = ":custom-dependencies:protobuf-lite"
val protobufRelocatedProject = ":custom-dependencies:protobuf-relocated"
fun DependencyHandler.protobufLite(): ProjectDependency =
project(protobufLiteProject, configuration = "default").apply { isTransitive = false }
val protobufLiteTask = "$protobufLiteProject:prepare"
fun DependencyHandler.protobufFull(): ProjectDependency =
project(protobufLiteProject, configuration = "relocated").apply { isTransitive = false }
val protobufFullTask = "$protobufLiteProject:prepare-relocated-protobuf"
project(protobufRelocatedProject, configuration = "default").apply { isTransitive = false }
private fun File.matchMaybeVersionedArtifact(baseName: String) = name.matches(baseName.toMaybeVersionedJarRegex())
fun File.matchMaybeVersionedArtifact(baseName: String) = name.matches(baseName.toMaybeVersionedJarRegex())
private val wildcardsRe = """[^*?]+|(\*)|(\?)""".toRegex()
@@ -103,8 +93,8 @@ private fun String.toMaybeVersionedJarRegex(): Regex {
private val jreHome = System.getProperty("java.home")
fun firstFromJavaHomeThatExists(vararg paths: String): File =
fun firstFromJavaHomeThatExists(vararg paths: String): File? =
paths.mapNotNull { File(jreHome, it).takeIf { it.exists() } }.firstOrNull()
?: throw GradleException("Cannot find under '$jreHome' neither of: ${paths.joinToString()}")
fun toolsJar(): File = firstFromJavaHomeThatExists("../lib/tools.jar", "../Classes/tools.jar")
fun toolsJar(): File? = firstFromJavaHomeThatExists("../lib/tools.jar", "../Classes/tools.jar")

View File

@@ -1,10 +1,8 @@
@file:Suppress("unused") // usages in build scripts are not tracked properly
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.tasks.bundling.Zip
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.task
import org.gradle.kotlin.dsl.*
@@ -20,7 +18,8 @@ val packagesToRelocate =
"org.picocontainer",
"org.jline",
"gnu",
"org.fusesource")
"org.fusesource",
"kotlinx.coroutines")
// The shaded compiler "dummy" is used to rewrite dependencies in projects that are used with the embeddable compiler
// on the runtime and use some shaded dependencies from the compiler
@@ -104,23 +103,22 @@ fun Project.embeddableCompilerDummyForDependenciesRewriting(taskName: String = "
}
}
fun Project.rewriteDepsToShadedJar(originalJarTask: Jar, shadowJarTask: Zip, body: Jar.() -> Unit = {}): Jar {
val originalFiles by lazy {
val jarContents = zipTree(originalJarTask.outputs.files.singleFile).files
val basePath = jarContents.find { it.name == "MANIFEST.MF" }?.parentFile?.parentFile ?: throw GradleException("cannot determine the jar root dir")
jarContents.map { it.relativeTo(basePath).path }.toSet()
fun Project.rewriteDepsToShadedJar(originalJarTask: Jar, shadowJarTask: Jar, body: Jar.() -> Unit = {}): Jar {
originalJarTask.apply {
classifier = "original"
}
return task<Jar>("rewrittenDepsJar") {
originalJarTask.apply {
classifier = "original"
}
shadowJarTask.apply {
dependsOn(originalJarTask)
from(originalJarTask)// { include("**") }
classifier = "shadow"
}
dependsOn(shadowJarTask)
from(project.zipTree(shadowJarTask.outputs.files.singleFile)) { include { originalFiles.any { originalFile -> it.file.canonicalPath.endsWith(originalFile) } } }
val compilerDummyJarFile by lazy { configurations.getAt("compilerDummyJar").singleFile }
return shadowJarTask.apply {
dependsOn(originalJarTask)
from(originalJarTask)// { include("**") }
// When Gradle traverses the inputs, reject the shaded compiler JAR,
// which leads to the content of that JAR being excluded as well:
exclude { it.file == compilerDummyJarFile }
classifier = null
body()
}
}

View File

@@ -17,6 +17,7 @@
*/
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
@@ -51,6 +52,12 @@ fun Project.configureInstrumentation() {
}
}
val instrumentationClasspathCfg = configurations.create("instrumentationClasspath")
dependencies {
instrumentationClasspathCfg(intellijDep()) { includeJars("javac2", "jdom", "asm-all", "jgoodies-forms") }
}
afterEvaluate {
the<JavaPluginConvention>().sourceSets.all { sourceSetParam ->
// This copy will ignore filters, but they are unlikely to be used.
@@ -66,6 +73,7 @@ fun Project.configureInstrumentation() {
instrumentTask.apply {
dependsOn(sourceSetParam.classesTaskName).onlyIf { !classesDirsCopy.isEmpty }
sourceSet = sourceSetParam
instrumentationClasspath = instrumentationClasspathCfg
originalClassesDirs = classesDirsCopy
output = instrumentedClassesDir
}
@@ -88,6 +96,8 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
var sourceSet: SourceSet? = null
var instrumentationClasspath: Configuration? = null
@Input
var originalClassesDirs: FileCollection? = null
@@ -101,9 +111,10 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
@TaskAction
fun instrumentClasses() {
logger.info("input files are: ${originalClassesDirs?.joinToString("; ", transform = { "'${it.name}'${if (it.exists()) "" else " (does not exists)" }"})}")
output?.deleteRecursively()
copyOriginalClasses()
val classpath = project.ideaSdkDeps("javac2.jar", "jdom.jar", "asm-all.jar", "jgoodies-forms.jar")
val classpath = instrumentationClasspath!!
ant.withGroovyBuilder {
"taskdef"("name" to "instrumentIdeaExtensions",
@@ -113,7 +124,7 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
}
logger.info("Compiling forms and instrumenting code with nullability preconditions")
val instrumentNotNull = prepareNotNullInstrumenting(classpath)
val instrumentNotNull = prepareNotNullInstrumenting(classpath.asPath)
instrumentCode(sourceDirs, instrumentNotNull)
}
@@ -124,10 +135,10 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
}
}
private fun prepareNotNullInstrumenting(classpath: ConfigurableFileCollection): Boolean {
private fun prepareNotNullInstrumenting(classpath: String): Boolean {
ant.withGroovyBuilder {
"typedef"("name" to "skip",
"classpath" to classpath.asPath,
"classpath" to classpath,
"loaderref" to LOADER_REF,
"classname" to FILTER_ANNOTATION_REGEXP_CLASS)
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright 2010-2017 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.
*/
@file:Suppress("unused") // usages in build scripts are not tracked properly
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.IvyArtifactRepository
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.JavaExec
import org.gradle.kotlin.dsl.*
import java.io.File
private fun Project.intellijRepoDir() = File("${project.rootDir.absoluteFile}/buildSrc/prepare-deps/intellij-sdk/build/repo")
fun RepositoryHandler.intellijSdkRepo(project: Project): IvyArtifactRepository = ivy {
val baseDir = project.intellijRepoDir()
setUrl(baseDir)
ivyPattern("${baseDir.canonicalPath}/[organisation]/[revision]/[module]Ultimate.ivy.xml")
ivyPattern("${baseDir.canonicalPath}/[organisation]/[revision]/[module].ivy.xml")
ivyPattern("${baseDir.canonicalPath}/[organisation]/[revision]/intellijUltimate.plugin.[module].ivy.xml")
ivyPattern("${baseDir.canonicalPath}/[organisation]/[revision]/intellij.plugin.[module].ivy.xml")
artifactPattern("${baseDir.canonicalPath}/[organisation]/[revision]/[module]Ultimate/lib/[artifact](-[classifier]).jar")
artifactPattern("${baseDir.canonicalPath}/[organisation]/[revision]/[module]/lib/[artifact](-[classifier]).jar")
artifactPattern("${baseDir.canonicalPath}/[organisation]/[revision]/intellijUltimate/plugins/[module]/lib/[artifact](-[classifier]).jar")
artifactPattern("${baseDir.canonicalPath}/[organisation]/[revision]/intellij/plugins/[module]/lib/[artifact](-[classifier]).jar")
artifactPattern("${baseDir.canonicalPath}/[organisation]/[revision]/plugins-[module]/[module]/lib/[artifact](-[classifier]).jar")
artifactPattern("${baseDir.canonicalPath}/[organisation]/[revision]/[module]/[artifact].jar")
artifactPattern("${baseDir.canonicalPath}/[organisation]/[revision]/[module]/[artifact](-[revision])(-[classifier]).jar")
artifactPattern("${baseDir.canonicalPath}/[organisation]/[revision]/sources/[artifact]-[revision]-[classifier].[ext]")
}
fun Project.intellijDep(module: String = "intellij") = "kotlin.build.custom.deps:$module:${rootProject.extra["versions.intellijSdk"]}"
fun Project.intellijCoreDep() = intellijDep("intellij-core")
fun Project.intellijPluginDep(plugin: String) = intellijDep(plugin)
fun Project.intellijUltimateDep() = intellijDep("intellij")
fun Project.intellijUltimatePluginDep(plugin: String) = intellijDep(plugin)
fun ModuleDependency.includeJars(vararg names: String, rootProject: Project? = null) {
names.forEach {
var baseName = it.removeSuffix(".jar")
if (rootProject != null && rootProject.extra.has("ignore.jar.$baseName")) {
return@forEach
}
if (rootProject != null && rootProject.extra.has("versions.jar.$baseName")) {
baseName += "-${rootProject.extra["versions.jar.$baseName"]}"
}
artifact {
name = baseName
type = "jar"
extension = "jar"
}
}
}
fun ModuleDependency.includeIntellijCoreJarDependencies(project: Project) =
includeJars(*(project.rootProject.extra["IntellijCoreDependencies"] as List<String>).toTypedArray(), rootProject = project.rootProject)
fun ModuleDependency.includeIntellijCoreJarDependencies(project: Project, jarsFilterPredicate: (String) -> Boolean) =
includeJars(*(project.rootProject.extra["IntellijCoreDependencies"] as List<String>).filter { jarsFilterPredicate(it) }.toTypedArray(), rootProject = project.rootProject)
fun Project.isIntellijCommunityAvailable() = !(rootProject.extra["intellijUltimateEnabled"] as Boolean) || rootProject.extra["intellijSeparateSdks"] as Boolean
fun Project.isIntellijUltimateSdkAvailable() = (rootProject.extra["intellijUltimateEnabled"] as Boolean)
fun Project.intellijRootDir() =
File(intellijRepoDir(), "kotlin.build.custom.deps/${rootProject.extra["versions.intellijSdk"]}/intellij${if (isIntellijCommunityAvailable()) "" else "Ultimate"}")
fun Project.intellijUltimateRootDir() =
if (isIntellijUltimateSdkAvailable())
File(intellijRepoDir(), "kotlin.build.custom.deps/${rootProject.extra["versions.intellijSdk"]}/intellijUltimate")
else
throw GradleException("intellij ultimate SDK is not available")
fun DependencyHandlerScope.excludeInAndroidStudio(rootProject: Project, block: DependencyHandlerScope.() -> Unit) {
if (!rootProject.extra.has("versions.androidStudioRelease")) {
block()
}
}
fun Project.runIdeTask(name: String, ideaPluginDir: File, ideaSandboxDir: File, body: JavaExec.() -> Unit): JavaExec {
return task<JavaExec>(name) {
val ideaSandboxConfigDir = File(ideaSandboxDir, "config")
classpath = the<JavaPluginConvention>().sourceSets["main"].runtimeClasspath
main = "com.intellij.idea.Main"
workingDir = File(intellijRootDir(), "bin")
jvmArgs(
"-Xmx1250m",
"-XX:ReservedCodeCacheSize=240m",
"-XX:+HeapDumpOnOutOfMemoryError",
"-ea",
"-Didea.is.internal=true",
"-Didea.debug.mode=true",
"-Didea.system.path=$ideaSandboxDir",
"-Didea.config.path=$ideaSandboxConfigDir",
"-Dapple.laf.useScreenMenuBar=true",
"-Dapple.awt.graphics.UseQuartz=true",
"-Dsun.io.useCanonCaches=false",
"-Dplugin.path=${ideaPluginDir.parentFile.absolutePath}",
"-Dkotlin.internal.mode.enabled=true",
"-Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar"
)
if (project.hasProperty("noPCE")) {
jvmArgs("-Didea.ProcessCanceledException=disabled")
}
args()
doFirst {
val disabledPluginsFile = File(ideaSandboxConfigDir, "disabled_plugins.txt")
val disabledPluginsContents = disabledPluginsFile.takeIf { it.isFile }?.readLines()
val filteredContents = disabledPluginsContents?.filterNot { it.contains("org.jetbrains.kotlin") }
if (filteredContents != null && filteredContents.size != disabledPluginsContents.size) {
with(disabledPluginsFile.printWriter()) {
filteredContents.forEach(this::println)
}
}
}
body()
}
}

View File

@@ -10,18 +10,17 @@ dependencies {
compile(project(":compiler:backend"))
compile(projectTests(":compiler:tests-common"))
compile(commonDep("junit:junit"))
compile(ideaSdkDeps("openapi"))
compileOnly(intellijDep()) { includeJars("openapi") }
testCompile(project(":compiler:incremental-compilation-impl"))
testCompile(project(":core:descriptors"))
testCompile(project(":core:descriptors.jvm"))
testCompile(project(":compiler:frontend.java"))
testCompile(projectTests(":jps-plugin"))
testCompile(ideaSdkDeps("jps-model.jar", subdir = "jps"))
testCompile(ideaSdkDeps("groovy-all"))
testCompile(ideaSdkDeps("idea", "idea_rt"))
testCompile(ideaSdkDeps("jps-build-test", subdir = "jps/test"))
testCompile(ideaSdkDeps("jps-builders"))
testCompile(commonDep("junit:junit"))
testCompile(intellijDep()) { includeJars("openapi", "idea", "idea_rt", "groovy-all", "jps-builders", rootProject = rootProject) }
testCompile(intellijDep("jps-standalone")) { includeJars("jps-model") }
testCompile(intellijDep("jps-build-test"))
}
sourceSets {

View File

@@ -152,7 +152,9 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
private fun parseSingleReportInFolder(reportFolder: String): List<TestCase> {
val folder = File(reportFolder)
val files = folder.listFiles()!!
assert(files.size == 1)
assert(files.size == 1) {
"Expecting one file but ${files.size}: ${files.joinToString { it.name }}"
}
val reportFile = files[0]
val dbFactory = DocumentBuilderFactory.newInstance()

View File

@@ -31,11 +31,14 @@ private val packagePattern = Pattern.compile("(?m)^\\s*package[ |\t]+([\\w|\\.]*
private val importPattern = Pattern.compile("import[ |\t]([\\w|]*\\.)")
internal fun genFiles(file: File, fileContent: String, filesHolder: CodegenTestsOnAndroidGenerator.FilesWriter): FqName? {
val testFiles = createTestFiles(file, fileContent)
if (testFiles.filter { it.name.endsWith(".java") }.isNotEmpty()) {
internal fun patchFiles(
file: File,
testFiles: List<CodegenTestCase.TestFile>,
filesHolder: CodegenTestsOnAndroidGenerator.FilesWriter
): FqName? {
if (testFiles.any { it.name.endsWith(".java") }) {
//TODO support java files
return null;
return null
}
val ktFiles = testFiles.filter { it.name.endsWith(".kt") }
if (ktFiles.isEmpty()) return null
@@ -82,16 +85,6 @@ internal fun genFiles(file: File, fileContent: String, filesHolder: CodegenTests
return boxFiles.last().newClassId
}
private fun createTestFiles(file: File, expectedText: String): List<CodegenTestCase.TestFile> {
val files = KotlinTestUtils.createTestFiles(file.name, expectedText, object : KotlinTestUtils.TestFileFactoryNoModules<CodegenTestCase.TestFile>() {
override fun create(fileName: String, text: String, directives: Map<String, String>): CodegenTestCase.TestFile {
return CodegenTestCase.TestFile(fileName, text)
}
})
return files
}
private fun hasBoxMethod(text: String): Boolean {
return text.contains("fun box()")
}

View File

@@ -1,319 +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.android.tests;
import com.google.common.collect.Lists;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
import org.jetbrains.kotlin.cli.common.output.outputUtils.OutputUtilsKt;
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.codegen.CodegenTestFiles;
import org.jetbrains.kotlin.codegen.GenerationUtils;
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.config.JVMConfigurationKeys;
import org.jetbrains.kotlin.idea.KotlinFileType;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.NameUtils;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.test.*;
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase;
import org.jetbrains.kotlin.utils.Printer;
import org.junit.Assert;
import org.junit.Ignore;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Ignore
public class CodegenTestsOnAndroidGenerator extends KtUsefulTestCase {
private final PathManager pathManager;
private static final String testClassPackage = "org.jetbrains.kotlin.android.tests";
private static final String testClassName = "CodegenTestCaseOnAndroid";
private static final String baseTestClassPackage = "org.jetbrains.kotlin.android.tests";
private static final String baseTestClassName = "AbstractCodegenTestCaseOnAndroid";
private static final String generatorName = "CodegenTestsOnAndroidGenerator";
private static int MODULE_INDEX = 1;
private int WRITED_FILES_COUNT = 0;
private final List<String> generatedTestNames = Lists.newArrayList();
public static void generate(PathManager pathManager) throws Throwable {
new CodegenTestsOnAndroidGenerator(pathManager).generateOutputFiles();
}
private CodegenTestsOnAndroidGenerator(PathManager pathManager) {
this.pathManager = pathManager;
}
private void generateOutputFiles() throws Throwable {
prepareAndroidModule();
generateAndSave();
}
private void prepareAndroidModule() throws IOException {
System.out.println("Copying kotlin-runtime.jar and kotlin-reflect.jar in android module...");
copyKotlinRuntimeJars();
System.out.println("Check \"libs\" folder in tested android module...");
File libsFolderInTestedModule = new File(pathManager.getLibsFolderInAndroidTestedModuleTmpFolder());
if (!libsFolderInTestedModule.exists()) {
libsFolderInTestedModule.mkdirs();
}
}
private void copyKotlinRuntimeJars() throws IOException {
FileUtil.copy(
ForTestCompileRuntime.runtimeJarForTests(),
new File(pathManager.getLibsFolderInAndroidTmpFolder() + "/kotlin-runtime.jar")
);
FileUtil.copy(
ForTestCompileRuntime.reflectJarForTests(),
new File(pathManager.getLibsFolderInAndroidTmpFolder() + "/kotlin-reflect.jar")
);
FileUtil.copy(
ForTestCompileRuntime.kotlinTestJarForTests(),
new File(pathManager.getLibsFolderInAndroidTmpFolder() + "/kotlin-test.jar")
);
}
private void generateAndSave() throws Throwable {
System.out.println("Generating test files...");
StringBuilder out = new StringBuilder();
Printer p = new Printer(out);
p.print(FileUtil.loadFile(new File("license/LICENSE.txt")));
p.println("package " + testClassPackage + ";");
p.println();
p.println("import ", baseTestClassPackage, ".", baseTestClassName, ";");
p.println();
p.println("/* This class is generated by " + generatorName + ". DO NOT MODIFY MANUALLY */");
p.println("public class ", testClassName, " extends ", baseTestClassName, " {");
p.pushIndent();
generateTestMethodsForDirectories(p, new File("compiler/testData/codegen/box"), new File("compiler/testData/codegen/boxInline"));
p.popIndent();
p.println("}");
String testSourceFilePath =
pathManager.getSrcFolderInAndroidTmpFolder() + "/" + testClassPackage.replace(".", "/") + "/" + testClassName + ".java";
FileUtil.writeToFile(new File(testSourceFilePath), out.toString());
}
private void generateTestMethodsForDirectories(Printer p, File... dirs) throws IOException {
FilesWriter holderMock = new FilesWriter(false, false);
FilesWriter holderFull = new FilesWriter(true, false);
FilesWriter holderInheritMFP = new FilesWriter(true, true);
for (File dir : dirs) {
File[] files = dir.listFiles();
Assert.assertNotNull("Folder with testData is empty: " + dir.getAbsolutePath(), files);
processFiles(p, files, holderFull, holderMock, holderInheritMFP);
}
holderFull.writeFilesOnDisk();
holderMock.writeFilesOnDisk();
holderInheritMFP.writeFilesOnDisk();
}
class FilesWriter {
private final boolean isFullJdkAndRuntime;
private final boolean inheritMultifileParts;
public List<KtFile> files = new ArrayList<>();
private KotlinCoreEnvironment environment;
private Disposable disposable;
private FilesWriter(boolean isFullJdkAndRuntime, boolean inheritMultifileParts) {
this.isFullJdkAndRuntime = isFullJdkAndRuntime;
this.inheritMultifileParts = inheritMultifileParts;
this.disposable = new TestDisposable();
this.environment = createEnvironment(isFullJdkAndRuntime, disposable);
}
private KotlinCoreEnvironment createEnvironment(boolean isFullJdkAndRuntime, @NotNull Disposable disposable) {
ConfigurationKind configurationKind = isFullJdkAndRuntime ? ConfigurationKind.ALL : ConfigurationKind.NO_KOTLIN_REFLECT;
TestJdkKind testJdkKind = isFullJdkAndRuntime ? TestJdkKind.FULL_JDK : TestJdkKind.MOCK_JDK;
CompilerConfiguration configuration =
KotlinTestUtils.newConfiguration(configurationKind, testJdkKind, KotlinTestUtils.getAnnotationsJar());
configuration.put(CommonConfigurationKeys.MODULE_NAME, "android-module-" + MODULE_INDEX++);
if (inheritMultifileParts) {
configuration.put(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, true);
}
return KotlinCoreEnvironment.createForTests(disposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES);
}
public boolean shouldWriteFilesOnDisk() {
return files.size() > 300;
}
public void writeFilesOnDiskIfNeeded() {
if (shouldWriteFilesOnDisk()) {
writeFilesOnDisk();
}
}
public void writeFilesOnDisk() {
writeFiles(files);
files = new ArrayList<>();
if (disposable != null) {
Disposer.dispose(disposable);
disposable = new TestDisposable();
}
environment = createEnvironment(isFullJdkAndRuntime, disposable);
}
public void addFile(String name, String content) {
try {
files.add(CodegenTestFiles.create(name, content, environment.getProject()).getPsiFile());
}
catch (Throwable e) {
throw new RuntimeException("Problem during creating file " + name + ": \n" + content, e);
}
}
private void writeFiles(List<KtFile> filesToCompile) {
if (filesToCompile.isEmpty()) return;
//1000 files per folder, each folder would be jared by build.gradle script
// We can't create one big jar with all test cause dex has problem with memory on teamcity
WRITED_FILES_COUNT += filesToCompile.size();
File outputDir = new File(pathManager.getOutputForCompiledFiles(WRITED_FILES_COUNT / 1000));
System.out.println("Generating " + filesToCompile.size() + " files" +
(inheritMultifileParts
? " (JVM.INHERIT_MULTIFILE_PARTS)"
: isFullJdkAndRuntime ? " (full jdk and runtime)" : "") + " into " + outputDir.getName() + "...");
OutputFileCollection outputFiles;
GenerationState state = null;
try {
state = GenerationUtils.compileFiles(filesToCompile, environment);
outputFiles = state.getFactory();
}
catch (Throwable e) {
throw new RuntimeException(e);
}
finally {
if (state != null) {
state.destroy();
}
}
if (!outputDir.exists()) {
outputDir.mkdirs();
}
Assert.assertTrue("Cannot create directory for compiled files", outputDir.exists());
OutputUtilsKt.writeAllTo(outputFiles, outputDir);
}
}
private void processFiles(
@NotNull Printer printer,
@NotNull File[] files,
@NotNull FilesWriter holderFull,
@NotNull FilesWriter holderMock,
@NotNull FilesWriter holderInheritMFP
) throws IOException {
holderFull.writeFilesOnDiskIfNeeded();
holderMock.writeFilesOnDiskIfNeeded();
holderInheritMFP.writeFilesOnDiskIfNeeded();
for (File file : files) {
if (SpecialFiles.getExcludedFiles().contains(file.getName())) {
continue;
}
if (file.isDirectory()) {
File[] listFiles = file.listFiles();
if (listFiles != null) {
processFiles(printer, listFiles, holderFull, holderMock, holderInheritMFP);
}
}
else if (!FileUtilRt.getExtension(file.getName()).equals(KotlinFileType.INSTANCE.getDefaultExtension())) {
// skip non kotlin files
}
else {
String fullFileText = FileUtil.loadFile(file, true);
if (!InTextDirectivesUtils.isPassingTarget(TargetBackend.JVM, file)) {
continue;
}
//TODO: support LANGUAGE_VERSION
if (InTextDirectivesUtils.isDirectiveDefined(fullFileText, "LANGUAGE_VERSION:")) {
continue;
}
//TODO: support multifile facades
//TODO: support multifile facades hierarchies
if (hasBoxMethod(fullFileText)) {
FilesWriter filesHolder = InTextDirectivesUtils.isDirectiveDefined(fullFileText, "FULL_JDK") ||
InTextDirectivesUtils.isDirectiveDefined(fullFileText, "WITH_RUNTIME") ||
InTextDirectivesUtils.isDirectiveDefined(fullFileText, "WITH_REFLECT") ? holderFull : holderMock;
filesHolder = fullFileText.contains("+JVM.INHERIT_MULTIFILE_PARTS") ? holderInheritMFP : filesHolder;
FqName classWithBoxMethod = AndroidTestGeneratorKt.genFiles(file, fullFileText, filesHolder);
if (classWithBoxMethod == null)
continue;
String generatedTestName = generateTestName(file.getName());
generateTestMethod(printer, generatedTestName, classWithBoxMethod.asString(), StringUtil.escapeStringCharacters(file.getPath()));
}
}
}
}
private static boolean hasBoxMethod(String text) {
return text.contains("fun box()");
}
private static void generateTestMethod(Printer p, String testName, String className, String filePath) {
p.println("public void test" + testName + "() throws Exception {");
p.pushIndent();
p.println("invokeBoxMethod(" + className + ".class, \"" + filePath + "\", \"OK\");");
p.popIndent();
p.println("}");
p.println();
}
private String generateTestName(String fileName) {
String result = NameUtils.sanitizeAsJavaIdentifier(FileUtil.getNameWithoutExtension(StringUtil.capitalize(fileName)));
int i = 0;
while (generatedTestNames.contains(result)) {
result += "_" + i++;
}
generatedTestNames.add(result);
return result;
}
}

View File

@@ -0,0 +1,294 @@
/*
* 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.android.tests
import com.google.common.collect.Lists
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAllTo
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.codegen.CodegenTestCase
import org.jetbrains.kotlin.codegen.CodegenTestFiles
import org.jetbrains.kotlin.codegen.GenerationUtils
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.name.NameUtils
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.utils.Printer
import org.junit.Assert
import org.junit.Ignore
import java.io.File
import java.io.FileWriter
import java.io.IOException
import java.util.*
data class ConfigurationKey(val kind: ConfigurationKind, val jdkKind: TestJdkKind, val configuration: String)
@Ignore
class CodegenTestsOnAndroidGenerator private constructor(private val pathManager: PathManager) : CodegenTestCase() {
private var writtenFilesCount = 0
private var currentModuleIndex = 1
private val generatedTestNames = Lists.newArrayList<String>()
private fun generateOutputFiles() {
prepareAndroidModule()
generateAndSave()
}
private fun prepareAndroidModule() {
println("Copying kotlin-runtime.jar and kotlin-reflect.jar in android module...")
copyKotlinRuntimeJars()
println("Check 'libs' folder in tested android module...")
val libsFolderInTestedModule = File(pathManager.libsFolderInAndroidTestedModuleTmpFolder)
if (!libsFolderInTestedModule.exists()) {
libsFolderInTestedModule.mkdirs()
}
}
private fun copyKotlinRuntimeJars() {
FileUtil.copy(
ForTestCompileRuntime.runtimeJarForTests(),
File(pathManager.libsFolderInAndroidTmpFolder + "/kotlin-runtime.jar")
)
FileUtil.copy(
ForTestCompileRuntime.reflectJarForTests(),
File(pathManager.libsFolderInAndroidTmpFolder + "/kotlin-reflect.jar")
)
FileUtil.copy(
ForTestCompileRuntime.kotlinTestJarForTests(),
File(pathManager.libsFolderInAndroidTmpFolder + "/kotlin-test.jar")
)
}
private fun generateAndSave() {
println("Generating test files...")
val testSourceFilePath =
pathManager.srcFolderInAndroidTmpFolder + "/" + testClassPackage.replace(".", "/") + "/" + testClassName + ".java"
FileWriter(File(testSourceFilePath)).use {
val p = Printer(it)
p.print(FileUtil.loadFile(File("license/LICENSE.txt")))
p.println(
"""package $testClassPackage;
|
|import $baseTestClassPackage.$baseTestClassName;
|
|/* This class is generated by $generatorName. DO NOT MODIFY MANUALLY */
|public class $testClassName extends $baseTestClassName {
|
""".trimMargin()
)
p.pushIndent()
generateTestMethodsForDirectories(p, File("compiler/testData/codegen/box"), File("compiler/testData/codegen/boxInline"))
p.popIndent()
p.println("}")
}
}
private fun generateTestMethodsForDirectories(p: Printer, vararg dirs: File) {
val holders = mutableMapOf<ConfigurationKey, FilesWriter>()
for (dir in dirs) {
val files = dir.listFiles() ?: error("Folder with testData is empty: ${dir.absolutePath}")
processFiles(p, files, holders)
}
holders.values.forEach {
it.writeFilesOnDisk()
}
}
internal inner class FilesWriter(
private val configuration: CompilerConfiguration
) {
private val rawFiles: MutableList<Pair<String, String>> = ArrayList()
private fun shouldWriteFilesOnDisk(): Boolean = rawFiles.size > 300
fun writeFilesOnDiskIfNeeded() {
if (shouldWriteFilesOnDisk()) {
writeFilesOnDisk()
}
}
fun writeFilesOnDisk() {
val disposable = TestDisposable()
val environment = KotlinCoreEnvironment.createForTests(
disposable,
configuration.copy().apply { put(CommonConfigurationKeys.MODULE_NAME, "android-module-" + currentModuleIndex++) },
EnvironmentConfigFiles.JVM_CONFIG_FILES
)
writeFiles(
rawFiles.map {
CodegenTestFiles.create(it.first, it.second, environment.project).psiFile
}, environment
)
Disposer.dispose(disposable)
rawFiles.clear()
}
fun addFile(name: String, content: String) {
rawFiles.add(name to content)
}
private fun writeFiles(filesToCompile: List<KtFile>, environment: KotlinCoreEnvironment) {
if (filesToCompile.isEmpty()) return
//1000 files per folder, each folder would be jared by build.gradle script
// We can't create one big jar with all test cause dex has problem with memory on teamcity
writtenFilesCount += filesToCompile.size
val outputDir = File(pathManager.getOutputForCompiledFiles(writtenFilesCount / 1000))
println("Generating ${filesToCompile.size} files into ${outputDir.name}, configuration: '${environment.configuration}'...")
val outputFiles = GenerationUtils.compileFiles(filesToCompile, environment).run { destroy(); factory }
if (!outputDir.exists()) {
outputDir.mkdirs()
}
Assert.assertTrue("Cannot create directory for compiled files", outputDir.exists())
outputFiles.writeAllTo(outputDir)
}
}
@Throws(IOException::class)
private fun processFiles(
printer: Printer,
files: Array<File>,
holders: MutableMap<ConfigurationKey, FilesWriter>
) {
holders.values.forEach {
it.writeFilesOnDiskIfNeeded()
}
for (file in files) {
if (SpecialFiles.getExcludedFiles().contains(file.name)) {
continue
}
if (file.isDirectory) {
val listFiles = file.listFiles()
if (listFiles != null) {
processFiles(printer, listFiles, holders)
}
} else if (FileUtilRt.getExtension(file.name) != KotlinFileType.EXTENSION) {
// skip non kotlin files
} else {
if (!InTextDirectivesUtils.isPassingTarget(TargetBackend.JVM, file)) {
continue
}
val fullFileText = FileUtil.loadFile(file, true)
//TODO support JvmPackageName
if (fullFileText.contains("@file:JvmPackageName(")) continue
if (hasBoxMethod(fullFileText)) {
val testFiles = createTestFiles(file, fullFileText)
val kind = extractConfigurationKind(testFiles)
val jdkKind = getJdkKind(testFiles)
val keyConfiguration = CompilerConfiguration()
updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration)
val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString())
val filesHolder = holders.getOrPut(key) {
FilesWriter(KotlinTestUtils.newConfiguration(kind, jdkKind, KotlinTestUtils.getAnnotationsJar()).apply {
println("Creating new configuration by $key")
updateConfigurationByDirectivesInTestFiles(testFiles, this)
})
}
val classWithBoxMethod = patchFiles(file, testFiles, filesHolder) ?: continue
val generatedTestName = generateTestName(file.name)
generateTestMethod(
printer,
generatedTestName,
classWithBoxMethod.asString(),
StringUtil.escapeStringCharacters(file.path)
)
}
}
}
}
private fun createTestFiles(file: File, expectedText: String): List<CodegenTestCase.TestFile> =
KotlinTestUtils.createTestFiles(
file.name,
expectedText,
object : KotlinTestUtils.TestFileFactoryNoModules<CodegenTestCase.TestFile>() {
override fun create(fileName: String, text: String, directives: Map<String, String>): CodegenTestCase.TestFile {
return CodegenTestCase.TestFile(fileName, text)
}
})
private fun generateTestName(fileName: String): String {
var result = NameUtils.sanitizeAsJavaIdentifier(FileUtil.getNameWithoutExtension(StringUtil.capitalize(fileName)))
var i = 0
while (generatedTestNames.contains(result)) {
result += "_" + i++
}
generatedTestNames.add(result)
return result
}
companion object {
private const val testClassPackage = "org.jetbrains.kotlin.android.tests"
private const val testClassName = "CodegenTestCaseOnAndroid"
private const val baseTestClassPackage = "org.jetbrains.kotlin.android.tests"
private const val baseTestClassName = "AbstractCodegenTestCaseOnAndroid"
private const val generatorName = "CodegenTestsOnAndroidGenerator"
@JvmStatic
@Throws(Throwable::class)
fun generate(pathManager: PathManager) {
CodegenTestsOnAndroidGenerator(pathManager).generateOutputFiles()
}
private fun hasBoxMethod(text: String): Boolean {
return text.contains("fun box()")
}
private fun generateTestMethod(p: Printer, testName: String, className: String, filePath: String) {
p.println("public void test$testName() throws Exception {")
p.pushIndent()
p.println("invokeBoxMethod($className.class, \"$filePath\", \"OK\");")
p.popIndent()
p.println("}")
p.println()
}
}
}

View File

@@ -48,6 +48,7 @@ public class SpecialFiles {
excludedFiles.add("enumKClassAnnotation.kt");
excludedFiles.add("primitivesAndArrays.kt");
excludedFiles.add("getDelegateWithoutReflection.kt");
excludedFiles.add("parameterAnnotationInDefaultImpls.kt");
// Reflection is used to check full class name
excludedFiles.add("native");
@@ -127,9 +128,8 @@ public class SpecialFiles {
//wrong function resolution after package renaming
excludedFiles.add("apiVersionAtLeast1.kt");
//special flags
excludedFiles.add("inlineFunInConstructorCallWithEnabledNormalization.kt");
excludedFiles.add("kt9532_lv10.kt");
//special symbols in names
excludedFiles.add("nameWithWhitespace.kt");
}
private SpecialFiles() {

View File

@@ -9,6 +9,7 @@ dependencies {
compile(project(":compiler:util"))
compile(project(":compiler:frontend"))
compile(project(":compiler:ir.tree"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
}
sourceSets {

View File

@@ -11,6 +11,8 @@ dependencies {
compile(project(":compiler:ir.tree"))
compile(project(":compiler:ir.psi2ir"))
compile(project(":compiler:serialization"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeJars("annotations", "asm-all", "trove4j", "guava", rootProject = rootProject) }
}
sourceSets {

View File

@@ -45,7 +45,7 @@ public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDe
this.nameSuffix = nameSuffix;
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
descriptor instanceof ConstructorDescriptor || CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)
descriptor instanceof ConstructorDescriptor || CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(descriptor)
? null
: descriptor.getDispatchReceiverParameter(),
copyTypeParameters(descriptor),

View File

@@ -47,7 +47,7 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
) {
this(property, property.getType(), DescriptorUtils.getReceiverParameterType(property.getExtensionReceiverParameter()),
/* dispatchReceiverParameter = */
CodegenUtilKt.isJvmStaticInObjectOrClass(property) ? null : property.getDispatchReceiverParameter(),
CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(property) ? null : property.getDispatchReceiverParameter(),
containingDeclaration, superCallTarget, nameSuffix,
getterAccessorRequired, setterAccessorRequired);
}

View File

@@ -370,8 +370,9 @@ public abstract class AnnotationCodegen {
@Override
public Void visitEnumValue(EnumValue value, Void data) {
String propertyName = value.getValue().getName().asString();
annotationVisitor.visitEnum(name, typeMapper.mapType(value.getType()).getDescriptor(), propertyName);
String enumClassInternalName = AsmUtil.asmTypeByClassId(value.getEnumClassId()).getDescriptor();
String enumEntryName = value.getEnumEntryName().asString();
annotationVisitor.visitEnum(name, enumClassInternalName, enumEntryName);
return null;
}
@@ -437,7 +438,7 @@ public abstract class AnnotationCodegen {
}
@Nullable
private Set<ElementType> getJavaTargetList(ClassDescriptor descriptor) {
private static Set<ElementType> getJavaTargetList(ClassDescriptor descriptor) {
AnnotationDescriptor targetAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Target.class.getName()));
if (targetAnnotation != null) {
Collection<ConstantValue<?>> valueArguments = targetAnnotation.getAllValueArguments().values();
@@ -448,12 +449,9 @@ public abstract class AnnotationCodegen {
Set<ElementType> result = EnumSet.noneOf(ElementType.class);
for (ConstantValue<?> value : values) {
if (value instanceof EnumValue) {
ClassDescriptor enumEntry = ((EnumValue) value).getValue();
KotlinType classObjectType = DescriptorUtilsKt.getClassValueType(enumEntry);
if (classObjectType != null) {
if ("java/lang/annotation/ElementType".equals(typeMapper.mapType(classObjectType).getInternalName())) {
result.add(ElementType.valueOf(enumEntry.getName().asString()));
}
FqName enumClassFqName = ((EnumValue) value).getEnumClassId().asSingleFqName();
if (ElementType.class.getName().equals(enumClassFqName.asString())) {
result.add(ElementType.valueOf(((EnumValue) value).getEnumEntryName().asString()));
}
}
}
@@ -465,21 +463,18 @@ public abstract class AnnotationCodegen {
}
@NotNull
private RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
private static RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
KotlinRetention retention = DescriptorUtilsKt.getAnnotationRetention(descriptor);
if (retention != null) {
return annotationRetentionMap.get(retention);
}
AnnotationDescriptor retentionAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Retention.class.getName()));
if (retentionAnnotation != null) {
ConstantValue<?> compileTimeConstant = CollectionsKt.firstOrNull(retentionAnnotation.getAllValueArguments().values());
if (compileTimeConstant instanceof EnumValue) {
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
KotlinType classObjectType = DescriptorUtilsKt.getClassValueType(enumEntry);
if (classObjectType != null) {
if ("java/lang/annotation/RetentionPolicy".equals(typeMapper.mapType(classObjectType).getInternalName())) {
return RetentionPolicy.valueOf(enumEntry.getName().asString());
}
ConstantValue<?> value = CollectionsKt.firstOrNull(retentionAnnotation.getAllValueArguments().values());
if (value instanceof EnumValue) {
FqName enumClassFqName = ((EnumValue) value).getEnumClassId().asSingleFqName();
if (RetentionPolicy.class.getName().equals(enumClassFqName.asString())) {
return RetentionPolicy.valueOf(((EnumValue) value).getEnumEntryName().asString());
}
}
}

View File

@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.codegen.serialization.JvmStringTable;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.JvmTarget;
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JavaVisibilities;
@@ -194,7 +193,7 @@ public class AsmUtil {
public static boolean isStaticMethod(OwnerKind kind, CallableMemberDescriptor functionDescriptor) {
return isStaticKind(kind) ||
KotlinTypeMapper.isStaticAccessor(functionDescriptor) ||
CodegenUtilKt.isJvmStaticInObjectOrClass(functionDescriptor);
CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
}
public static boolean isStaticKind(OwnerKind kind) {
@@ -781,7 +780,7 @@ public class AsmUtil {
public static boolean isPropertyWithBackingFieldCopyInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
DeclarationDescriptor propertyContainer = propertyDescriptor.getContainingDeclaration();
return propertyDescriptor.isConst()
&& isCompanionObject(propertyContainer) && isInterface(propertyContainer.getContainingDeclaration())
&& isCompanionObject(propertyContainer) && isJvmInterface(propertyContainer.getContainingDeclaration())
&& getVisibilityForBackingField(propertyDescriptor, false) == ACC_PUBLIC;
}

View File

@@ -92,7 +92,7 @@ public class CallReceiver extends StackValue {
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
if (CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)) {
if (CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(descriptor)) {
return Type.VOID_TYPE;
}

View File

@@ -16,19 +16,85 @@
package org.jetbrains.kotlin.codegen
import com.google.common.collect.Sets
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.KtFile
interface CodegenFactory {
fun generateModule(state: GenerationState, files: Collection<KtFile?>, errorHandler: CompilationErrorHandler)
fun createPackageCodegen(state: GenerationState, files: Collection<KtFile>, fqName: FqName, registry: PackagePartRegistry): PackageCodegen
fun createMultifileClassCodegen(state: GenerationState, files: Collection<KtFile>, fqName: FqName, registry: PackagePartRegistry): MultifileClassCodegen
companion object {
fun doCheckCancelled(state: GenerationState) {
if (state.classBuilderMode.generateBodies) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
}
}
}
}
object DefaultCodegenFactory : CodegenFactory {
override fun generateModule(state: GenerationState, files: Collection<KtFile?>, errorHandler: CompilationErrorHandler) {
val filesInPackages = MultiMap<FqName, KtFile>()
val filesInMultifileClasses = MultiMap<FqName, KtFile>()
for (file in files) {
if (file == null) throw IllegalArgumentException("A null file given for compilation")
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file)
if (fileClassInfo.withJvmMultifileClass) {
filesInMultifileClasses.putValue(fileClassInfo.facadeClassFqName, file)
}
else {
filesInPackages.putValue(file.packageFqName, file)
}
}
val obsoleteMultifileClasses = HashSet(state.obsoleteMultifileClasses)
for (multifileClassFqName in filesInMultifileClasses.keySet() + obsoleteMultifileClasses) {
CodegenFactory.doCheckCancelled(state)
generateMultifileClass(state, multifileClassFqName, filesInMultifileClasses.get(multifileClassFqName), errorHandler)
}
val packagesWithObsoleteParts = HashSet(state.packagesWithObsoleteParts)
for (packageFqName in packagesWithObsoleteParts + filesInPackages.keySet()) {
CodegenFactory.doCheckCancelled(state)
generatePackage(state, packageFqName, filesInPackages.get(packageFqName), errorHandler)
}
}
override fun createPackageCodegen(state: GenerationState, files: Collection<KtFile>, fqName: FqName, registry: PackagePartRegistry) =
PackageCodegenImpl(state, files, fqName, registry)
override fun createMultifileClassCodegen(state: GenerationState, files: Collection<KtFile>, fqName: FqName, registry: PackagePartRegistry) =
MultifileClassCodegenImpl(state, files, fqName, registry)
private fun generateMultifileClass(
state: GenerationState,
multifileClassFqName: FqName,
files: Collection<KtFile>,
handler: CompilationErrorHandler
) {
val codegen = state.factory.forMultifileClass(multifileClassFqName, files)
codegen.generate(handler)
}
fun generatePackage(
state: GenerationState,
packageFqName: FqName,
jetFiles: Collection<KtFile>,
errorHandler: CompilationErrorHandler
) {
// We do not really generate package class, but use old package fqName to identify package in module-info.
//FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(packageFqName);
val codegen = state.factory.forPackage(packageFqName, jetFiles)
codegen.generate(errorHandler)
}
}

View File

@@ -1,17 +1,6 @@
/*
* 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.
* Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen;
@@ -19,14 +8,22 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.util.ExceptionUtilKt;
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
public class CompilationException extends RuntimeException {
public class CompilationException extends KotlinExceptionWithAttachments {
private final PsiElement element;
public CompilationException(@NotNull String message, @Nullable Throwable cause, @Nullable PsiElement element) {
super(ExceptionUtilKt.getExceptionMessage("Back-end (JVM)", message, cause, element), cause);
super(ExceptionUtilKt.getExceptionMessage("Back-end (JVM)", message, cause,
element == null ? null : DiagnosticUtils.atLocation(element)),
cause);
this.element = element;
if (element != null) {
withAttachment("element.kt", element.getText());
}
}
@Nullable

View File

@@ -1,21 +1,11 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen
import com.intellij.openapi.diagnostic.Attachment
import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
@@ -23,7 +13,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
object ExceptionLogger {
@JvmStatic
fun logDescriptorNotFound(problemDescription: String, psi: PsiElement): AssertionError {
LOG.error(problemDescription, psi.getElementTextWithContext())
LOG.error(problemDescription, Attachment("psi.kt", psi.getElementTextWithContext()))
throw AssertionError(problemDescription)
}

View File

@@ -2324,6 +2324,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
if (isSuspendCall) {
addReturnsUnitMarkerIfNecessary(v, resolvedCall);
addSuspendMarker(v, false);
addInlineMarker(v, false);
}
@@ -2525,8 +2527,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
else if (receiverDescriptor instanceof ScriptDescriptor) {
return generateScriptReceiver
((ScriptDescriptor) receiverDescriptor);
return generateScriptReceiver((ScriptDescriptor) receiverDescriptor);
}
else {
return StackValue.thisOrOuter(this, receiverDescriptor, isSuper,
@@ -2630,7 +2631,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
if (thisOrOuterClass.equals(context.getThisDescriptor()) &&
!CodegenUtilKt.isJvmStaticInObjectOrClass(context.getFunctionDescriptor())) {
!CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(context.getFunctionDescriptor())) {
return StackValue.local(0, typeMapper.mapType(thisOrOuterClass));
}
else if (shouldGenerateSingletonAsThisOrOuterFromContext(thisOrOuterClass)) {

View File

@@ -58,6 +58,16 @@ public class FieldInfo {
return new FieldInfo(owner, fieldType, fieldName, false);
}
@NotNull
public static FieldInfo createForHiddenField(
@NotNull Type owner,
@NotNull Type fieldType,
@NotNull String fieldName,
@NotNull boolean isStatic
) {
return new FieldInfo(owner, fieldType, fieldName, isStatic);
}
private final Type fieldType;
private final Type ownerType;
private final String fieldName;

View File

@@ -223,9 +223,8 @@ public class FunctionCodegen {
generateMethodAnnotations(functionDescriptor, asmMethod, mv);
JvmMethodSignature signature = typeMapper.mapSignatureSkipGeneric(functionDescriptor);
generateParameterAnnotations(functionDescriptor, mv, signature);
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, signature, state, (flags & ACC_SYNTHETIC) != 0);
generateParameterAnnotations(functionDescriptor, mv, jvmSignature);
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
generateBridges(functionDescriptor);
@@ -243,6 +242,7 @@ public class FunctionCodegen {
functionDescriptor.isSuspend() &&
functionDescriptor.getModality() != Modality.ABSTRACT && isOverridable(functionDescriptor) &&
!isInterface(functionDescriptor.getContainingDeclaration()) &&
!(functionDescriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor) &&
origin.getOriginKind() != JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL;
if (isOpenSuspendInClass) {
@@ -558,7 +558,7 @@ public class FunctionCodegen {
mv.visitLabel(methodEntry);
context.setMethodStartLabel(methodEntry);
if (!KotlinTypeMapper.isAccessor(functionDescriptor)) {
if (!strategy.skipNotNullAssertionsForParameters()) {
genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
}
@@ -1383,6 +1383,11 @@ public class FunctionCodegen {
iv.areturn(delegateMethod.getReturnType());
}
@Override
public boolean skipNotNullAssertionsForParameters() {
return false;
}
}
);
}

View File

@@ -34,6 +34,8 @@ public abstract class FunctionGenerationStrategy {
@NotNull MemberCodegen<?> parentCodegen
);
public abstract boolean skipNotNullAssertionsForParameters();
public MethodVisitor wrapMethodVisitor(@NotNull MethodVisitor mv, int access, @NotNull String name, @NotNull String desc) {
return mv;
}
@@ -76,6 +78,12 @@ public abstract class FunctionGenerationStrategy {
doGenerateBody(codegen, signature);
}
@Override
public boolean skipNotNullAssertionsForParameters() {
// Assume the strategy injects non-null checks for parameters by default
return false;
}
public abstract void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature);
}
}

View File

@@ -52,7 +52,8 @@ import org.jetbrains.kotlin.resolve.DelegationResolver;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.*;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
@@ -64,7 +65,10 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.FieldVisitor;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
@@ -671,6 +675,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
iv.areturn(componentType);
}
@Override
public boolean skipNotNullAssertionsForParameters() {
return false;
}
});
}
@@ -719,6 +728,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.areturn(thisDescriptorType);
}
@Override
public boolean skipNotNullAssertionsForParameters() {
return false;
}
private void pushCapturedFieldsOnStack(InstructionAdapter iv, MutableClosure closure) {
ClassDescriptor captureThis = closure.getCaptureThis();
if (captureThis != null) {
@@ -964,7 +978,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
private void generatePrimaryConstructor(DelegationFieldsInfo delegationFieldsInfo) {
if (isInterface(descriptor) || isAnnotationClass(descriptor)) return;
if (isJvmInterface(descriptor)) return;
ClassConstructorDescriptor constructorDescriptor = descriptor.getUnsubstitutedPrimaryConstructor();
if (constructorDescriptor == null) return;

View File

@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
import org.jetbrains.kotlin.load.kotlin.*;
@@ -57,6 +58,7 @@ import static org.jetbrains.kotlin.descriptors.ClassKind.INTERFACE;
import static org.jetbrains.kotlin.descriptors.Modality.ABSTRACT;
import static org.jetbrains.kotlin.descriptors.Modality.FINAL;
import static org.jetbrains.kotlin.resolve.BindingContext.DELEGATED_PROPERTY_CALL;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
public class JvmCodegenUtil {
@@ -330,4 +332,10 @@ public class JvmCodegenUtil {
return receiver;
}
public static boolean isCompanionObjectInInterfaceNotIntrinsic(@NotNull DeclarationDescriptor companionObject) {
return isCompanionObject(companionObject) &&
isJvmInterface(companionObject.getContainingDeclaration()) &&
!JvmAbi.isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
}
}

View File

@@ -44,6 +44,8 @@ class JvmStaticInCompanionObjectGenerator(
Synthetic(originElement, staticFunctionDescriptor),
staticFunctionDescriptor,
object : FunctionGenerationStrategy.CodegenBased(state) {
override fun skipNotNullAssertionsForParameters(): Boolean = true
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
val iv = codegen.v
val classDescriptor = descriptor.containingDeclaration as ClassDescriptor

View File

@@ -16,19 +16,13 @@
package org.jetbrains.kotlin.codegen;
import com.intellij.util.containers.MultiMap;
import kotlin.collections.SetsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
import org.jetbrains.kotlin.psi.KtFile;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class KotlinCodegenFacade {
@@ -50,64 +44,19 @@ public class KotlinCodegenFacade {
@NotNull GenerationState state,
@NotNull CompilationErrorHandler errorHandler
) {
MultiMap<FqName, KtFile> filesInPackages = new MultiMap<>();
MultiMap<FqName, KtFile> filesInMultifileClasses = new MultiMap<>();
state.getCodegenFactory().generateModule(state, files, errorHandler);
for (KtFile file : files) {
if (file == null) throw new IllegalArgumentException("A null file given for compilation");
JvmFileClassInfo fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file);
if (fileClassInfo.getWithJvmMultifileClass()) {
filesInMultifileClasses.putValue(fileClassInfo.getFacadeClassFqName(), file);
}
else {
filesInPackages.putValue(file.getPackageFqName(), file);
}
}
Set<FqName> obsoleteMultifileClasses = new HashSet<>(state.getObsoleteMultifileClasses());
for (FqName multifileClassFqName : SetsKt.plus(filesInMultifileClasses.keySet(), obsoleteMultifileClasses)) {
doCheckCancelled(state);
generateMultifileClass(state, multifileClassFqName, filesInMultifileClasses.get(multifileClassFqName), errorHandler);
}
Set<FqName> packagesWithObsoleteParts = new HashSet<>(state.getPackagesWithObsoleteParts());
for (FqName packageFqName : SetsKt.plus(packagesWithObsoleteParts, filesInPackages.keySet())) {
doCheckCancelled(state);
generatePackage(state, packageFqName, filesInPackages.get(packageFqName), errorHandler);
}
doCheckCancelled(state);
CodegenFactory.Companion.doCheckCancelled(state);
state.getFactory().done();
}
private static void doCheckCancelled(GenerationState state) {
if (state.getClassBuilderMode().generateBodies) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
}
}
public static void generatePackage(
@NotNull GenerationState state,
@NotNull FqName packageFqName,
@NotNull Collection<KtFile> jetFiles,
@NotNull CompilationErrorHandler errorHandler
) {
// We do not really generate package class, but use old package fqName to identify package in module-info.
//FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(packageFqName);
PackageCodegen codegen = state.getFactory().forPackage(packageFqName, jetFiles);
codegen.generate(errorHandler);
}
private static void generateMultifileClass(
@NotNull GenerationState state,
@NotNull FqName multifileClassFqName,
@NotNull Collection<KtFile> files,
@NotNull CompilationErrorHandler handler
) {
MultifileClassCodegen codegen = state.getFactory().forMultifileClass(multifileClassFqName, files);
codegen.generate(handler);
DefaultCodegenFactory.INSTANCE.generatePackage(state, packageFqName, jetFiles, errorHandler);
}
private KotlinCodegenFacade() {}

View File

@@ -719,6 +719,11 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
functionCodegen.generateMethod(
Synthetic(null, original), accessor,
new FunctionGenerationStrategy.CodegenBased(state) {
@Override
public boolean skipNotNullAssertionsForParameters() {
return true;
}
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
markLineNumberForElement(element.getPsiOrParent(), codegen.v);
@@ -779,6 +784,11 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
iv.areturn(signature.getReturnType());
}
@Override
public boolean skipNotNullAssertionsForParameters() {
return true;
}
}
if (accessor.isWithSyntheticGetterAccessor()) {
@@ -812,7 +822,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallTarget() != null
);
boolean isJvmStaticInObjectOrClass = CodegenUtilKt.isJvmStaticInObjectOrClass(functionDescriptor);
boolean isJvmStaticInObjectOrClass = CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) &&
!isNonDefaultInterfaceMember(functionDescriptor, state) &&
!isJvmStaticInObjectOrClass;

View File

@@ -312,6 +312,10 @@ class MultifileClassCodegenImpl(
}
object DelegateToCompiledMemberGenerationStrategy : FunctionGenerationStrategy() {
override fun skipNotNullAssertionsForParameters(): kotlin.Boolean {
throw IllegalStateException("shouldn't be called")
}
override fun generateBody(mv: MethodVisitor, frameMap: FrameMap, signature: JvmMethodSignature, context: MethodContext, parentCodegen: MemberCodegen<*>) {
throw IllegalStateException("shouldn't be called")
}

View File

@@ -21,8 +21,11 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
@@ -32,30 +35,30 @@ import org.jetbrains.org.objectweb.asm.Type
val supportedRangeTypes = listOf(PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.LONG)
private val RANGE_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
supportedRangeTypes.associateBy {
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Range"))
}
supportedRangeTypes.associateBy {
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Range"))
}
private val PROGRESSION_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
supportedRangeTypes.associateBy {
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Progression"))
}
supportedRangeTypes.associateBy {
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Progression"))
}
fun isPrimitiveRange(rangeType: KotlinType) =
!rangeType.isMarkedNullable && getPrimitiveRangeElementType(rangeType) != null
!rangeType.isMarkedNullable && getPrimitiveRangeElementType(rangeType) != null
fun isPrimitiveProgression(rangeType: KotlinType) =
!rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null
!rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null
fun getPrimitiveRangeElementType(rangeType: KotlinType): PrimitiveType? =
getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE)
getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE)
private fun getPrimitiveProgressionElementType(rangeType: KotlinType) =
getPrimitiveRangeOrProgressionElementType(rangeType, PROGRESSION_TO_ELEMENT_TYPE)
getPrimitiveRangeOrProgressionElementType(rangeType, PROGRESSION_TO_ELEMENT_TYPE)
private fun getPrimitiveRangeOrProgressionElementType(
rangeOrProgression: KotlinType,
map: Map<FqName, PrimitiveType>
rangeOrProgression: KotlinType,
map: Map<FqName, PrimitiveType>
): PrimitiveType? {
val declarationDescriptor = rangeOrProgression.constructor.declarationDescriptor ?: return null
val fqName = DescriptorUtils.getFqName(declarationDescriptor).takeIf { it.isSafe } ?: return null
@@ -67,101 +70,117 @@ fun getRangeOrProgressionElementType(rangeType: KotlinType): KotlinType? {
val builtIns = rangeTypeDescriptor.builtIns
return when {
isTopLevelInPackage(rangeTypeDescriptor, "CharRange", "kotlin.ranges") -> builtIns.charType
isTopLevelInPackage(rangeTypeDescriptor, "IntRange", "kotlin.ranges") -> builtIns.intType
isTopLevelInPackage(rangeTypeDescriptor, "LongRange", "kotlin.ranges") -> builtIns.longType
rangeTypeDescriptor.isTopLevelInPackage("CharRange", "kotlin.ranges") -> builtIns.charType
rangeTypeDescriptor.isTopLevelInPackage("IntRange", "kotlin.ranges") -> builtIns.intType
rangeTypeDescriptor.isTopLevelInPackage("LongRange", "kotlin.ranges") -> builtIns.longType
isTopLevelInPackage(rangeTypeDescriptor, "CharProgression", "kotlin.ranges") -> builtIns.charType
isTopLevelInPackage(rangeTypeDescriptor, "IntProgression", "kotlin.ranges") -> builtIns.intType
isTopLevelInPackage(rangeTypeDescriptor, "LongProgression", "kotlin.ranges") -> builtIns.longType
rangeTypeDescriptor.isTopLevelInPackage("CharProgression", "kotlin.ranges") -> builtIns.charType
rangeTypeDescriptor.isTopLevelInPackage("IntProgression", "kotlin.ranges") -> builtIns.intType
rangeTypeDescriptor.isTopLevelInPackage("LongProgression", "kotlin.ranges") -> builtIns.longType
isTopLevelInPackage(rangeTypeDescriptor, "ClosedFloatRange", "kotlin.ranges") -> builtIns.floatType
isTopLevelInPackage(rangeTypeDescriptor, "ClosedDoubleRange", "kotlin.ranges") -> builtIns.doubleType
rangeTypeDescriptor.isTopLevelInPackage("ClosedFloatRange", "kotlin.ranges") -> builtIns.floatType
rangeTypeDescriptor.isTopLevelInPackage("ClosedDoubleRange", "kotlin.ranges") -> builtIns.doubleType
isTopLevelInPackage(rangeTypeDescriptor, "ClosedRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type
rangeTypeDescriptor.isTopLevelInPackage("ClosedRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type
isTopLevelInPackage(rangeTypeDescriptor, "ClosedFloatingPointRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type
rangeTypeDescriptor.isTopLevelInPackage("ClosedFloatingPointRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type
isTopLevelInPackage(rangeTypeDescriptor, "ComparableRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type
rangeTypeDescriptor.isTopLevelInPackage("ComparableRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type
else -> null
}
}
fun BindingContext.getElementType(forExpression: KtForExpression): KotlinType {
val loopRange = forExpression.loopRange!!
val nextCall = get(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, loopRange)
?: throw AssertionError("No next() function " + DiagnosticUtils.atLocation(loopRange))
return nextCall.resultingDescriptor.returnType!!
}
fun getPrimitiveRangeOrProgressionElementType(rangeOrProgressionName: FqName): PrimitiveType? =
RANGE_TO_ELEMENT_TYPE[rangeOrProgressionName] ?:
PROGRESSION_TO_ELEMENT_TYPE[rangeOrProgressionName]
RANGE_TO_ELEMENT_TYPE[rangeOrProgressionName] ?: PROGRESSION_TO_ELEMENT_TYPE[rangeOrProgressionName]
fun isRangeOrProgression(className: FqName) =
getPrimitiveRangeOrProgressionElementType(className) != null
getPrimitiveRangeOrProgressionElementType(className) != null
fun isPrimitiveNumberRangeTo(rangeTo: CallableDescriptor) =
"rangeTo" == rangeTo.name.asString() && isPrimitiveNumberClassDescriptor(rangeTo.containingDeclaration) ||
isPrimitiveRangeToExtension(rangeTo)
"rangeTo" == rangeTo.name.asString() && isPrimitiveNumberClassDescriptor(rangeTo.containingDeclaration) ||
isPrimitiveRangeToExtension(rangeTo)
private fun isPrimitiveRangeToExtension(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "rangeTo", "kotlin.ranges")) return false
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
return KotlinBuiltIns.isPrimitiveType(extensionReceiver.type)
private inline fun CallableDescriptor.isTopLevelExtensionOnType(
name: String,
packageFQN: String,
receiverTypePredicate: (KotlinType) -> Boolean
): Boolean {
if (!this.isTopLevelInPackage(name, packageFQN)) return false
val extensionReceiverType = original.extensionReceiverParameter?.type ?: return false
return receiverTypePredicate(extensionReceiverType)
}
fun isPrimitiveNumberDownTo(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "downTo", "kotlin.ranges")) return false
private fun isPrimitiveRangeToExtension(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("rangeTo", "kotlin.ranges") {
KotlinBuiltIns.isPrimitiveType(it)
}
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverClassifier = extensionReceiver.type.constructor.declarationDescriptor
return isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)
}
fun isPrimitiveNumberDownTo(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("downTo", "kotlin.ranges") {
isPrimitiveNumberClassDescriptor(it.constructor.declarationDescriptor)
}
fun isPrimitiveNumberUntil(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "until", "kotlin.ranges")) return false
fun isPrimitiveNumberUntil(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("until", "kotlin.ranges") {
isPrimitiveNumberClassDescriptor(it.constructor.declarationDescriptor)
}
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverClassifier = extensionReceiver.type.constructor.declarationDescriptor
return isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)
}
fun isArrayOrPrimitiveArrayIndices(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("indices", "kotlin.collections") {
KotlinBuiltIns.isArray(it) || KotlinBuiltIns.isPrimitiveArray(it)
}
fun isArrayOrPrimitiveArrayIndices(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false
fun isArrayOrPrimitiveArrayWithIndex(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("withIndex", "kotlin.collections") {
KotlinBuiltIns.isArray(it) || KotlinBuiltIns.isPrimitiveArray(it)
}
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverType = extensionReceiver.type
return KotlinBuiltIns.isArray(extensionReceiverType) || KotlinBuiltIns.isPrimitiveArray(extensionReceiverType)
}
fun isCollectionIndices(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("indices", "kotlin.collections") {
KotlinBuiltIns.isCollectionOrNullableCollection(it)
}
fun isCollectionIndices(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false
fun isIterableWithIndex(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("withIndex", "kotlin.collections") {
KotlinBuiltIns.isIterableOrNullableIterable(it)
}
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverType = extensionReceiver.type
return KotlinBuiltIns.isCollectionOrNullableCollection(extensionReceiverType)
}
fun isSequenceWithIndex(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("withIndex", "kotlin.sequences") {
val typeDescriptor = it.constructor.declarationDescriptor ?: return false
typeDescriptor.isTopLevelInPackage("Sequence", "kotlin.sequences")
}
fun isCharSequenceIndices(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.text")) return false
fun isCharSequenceIndices(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("indices", "kotlin.text") {
KotlinBuiltIns.isCharSequenceOrNullableCharSequence(it)
}
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverType = extensionReceiver.type
return KotlinBuiltIns.isCharSequenceOrNullableCharSequence(extensionReceiverType)
}
fun isCharSequenceWithIndex(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("withIndex", "kotlin.text") {
KotlinBuiltIns.isCharSequenceOrNullableCharSequence(it)
}
fun isComparableRangeTo(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "rangeTo", "kotlin.ranges")) return false
val extensionReceiver = descriptor.original.extensionReceiverParameter ?: return false
val extensionReceiverTypeDescriptor = extensionReceiver.type.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false
val upperBoundType = extensionReceiverTypeDescriptor.upperBounds.singleOrNull() ?: return false
val upperBoundClassDescriptor = upperBoundType.constructor.declarationDescriptor as? ClassDescriptor ?: return false
if (!isTopLevelInPackage(upperBoundClassDescriptor, "Comparable", "kotlin")) return false
return true
}
fun isComparableRangeTo(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("rangeTo", "kotlin.ranges") {
val extensionReceiverTypeDescriptor = it.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false
val upperBoundType = extensionReceiverTypeDescriptor.upperBounds.singleOrNull() ?: return false
val upperBoundClassDescriptor = upperBoundType.constructor.declarationDescriptor as? ClassDescriptor ?: return false
upperBoundClassDescriptor.isTopLevelInPackage("Comparable", "kotlin")
}
fun isClosedRangeContains(descriptor: CallableDescriptor): Boolean {
if (descriptor.name.asString() != "contains") return false
val containingClassDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return false
if (!isTopLevelInPackage(containingClassDescriptor, "ClosedRange", "kotlin.ranges")) return false
if (!containingClassDescriptor.isTopLevelInPackage("ClosedRange", "kotlin.ranges")) return false
return true
}
@@ -188,33 +207,38 @@ fun isPrimitiveNumberRangeExtensionContainsPrimitiveNumber(descriptor: CallableD
return true
}
fun isPrimitiveProgressionReverse(descriptor: CallableDescriptor) =
descriptor.isTopLevelExtensionOnType("reversed", "kotlin.ranges") {
isPrimitiveProgression(it)
}
private fun isPrimitiveNumberType(type: KotlinType) =
KotlinBuiltIns.isByte(type) ||
KotlinBuiltIns.isShort(type) ||
KotlinBuiltIns.isInt(type) ||
KotlinBuiltIns.isChar(type) ||
KotlinBuiltIns.isLong(type) ||
KotlinBuiltIns.isFloat(type) ||
KotlinBuiltIns.isDouble(type)
KotlinBuiltIns.isByte(type) ||
KotlinBuiltIns.isShort(type) ||
KotlinBuiltIns.isInt(type) ||
KotlinBuiltIns.isChar(type) ||
KotlinBuiltIns.isLong(type) ||
KotlinBuiltIns.isFloat(type) ||
KotlinBuiltIns.isDouble(type)
fun isClosedFloatingPointRangeContains(descriptor: CallableDescriptor): Boolean {
if (descriptor.name.asString() != "contains") return false
val containingClassDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return false
if (!isTopLevelInPackage(containingClassDescriptor, "ClosedFloatingPointRange", "kotlin.ranges")) return false
if (!containingClassDescriptor.isTopLevelInPackage("ClosedFloatingPointRange", "kotlin.ranges")) return false
return true
}
fun getClosedFloatingPointRangeElementType(rangeType: KotlinType): KotlinType? {
val classDescriptor = rangeType.constructor.declarationDescriptor as? ClassDescriptor ?: return null
if (!isTopLevelInPackage(classDescriptor, "ClosedFloatingPointRange", "kotlin.ranges")) return null
if (!classDescriptor.isTopLevelInPackage("ClosedFloatingPointRange", "kotlin.ranges")) return null
return rangeType.arguments.singleOrNull()?.type
}
private fun isTopLevelInPackage(descriptor: DeclarationDescriptor, name: String, packageName: String): Boolean {
if (name != descriptor.name.asString()) return false
private fun DeclarationDescriptor.isTopLevelInPackage(name: String, packageName: String): Boolean {
if (name != this.name.asString()) return false
val containingDeclaration = descriptor.containingDeclaration as? PackageFragmentDescriptor ?: return false
val containingDeclaration = containingDeclaration as? PackageFragmentDescriptor ?: return false
val packageFqName = containingDeclaration.fqName.asString()
return packageName == packageFqName
}
@@ -234,7 +258,8 @@ fun getAsmRangeElementTypeForPrimitiveRangeOrProgression(rangeCallee: CallableDe
when {
KotlinBuiltIns.isDouble(it) -> return Type.DOUBLE_TYPE
KotlinBuiltIns.isFloat(it) -> return Type.FLOAT_TYPE
else -> {}
else -> {
}
}
}

View File

@@ -185,6 +185,8 @@ public class SamWrapperCodegen {
private FqName getWrapperName(@NotNull KtFile containingFile) {
FqName fileClassFqName = JvmFileClassUtil.getFileClassInfoNoResolve(containingFile).getFileClassFqName();
JavaClassDescriptor descriptor = samType.getJavaClassDescriptor();
//Change sam wrapper name template carefully cause it's used in inliner:
// see isSamWrapper/isSamWrapperConstructorCall in inlineCodegenUtils.kt
int hash = PackagePartClassUtils.getPathHashCode(containingFile.getVirtualFile()) * 31 +
DescriptorUtils.getFqNameSafe(descriptor).hashCode();
String shortName = String.format(

View File

@@ -1,242 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.context.ScriptContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
import org.jetbrains.kotlin.descriptors.ScriptDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class ScriptCodegen extends MemberCodegen<KtScript> {
public static ScriptCodegen createScriptCodegen(
@NotNull KtScript declaration,
@NotNull GenerationState state,
@NotNull CodegenContext parentContext
) {
BindingContext bindingContext = state.getBindingContext();
ScriptDescriptor scriptDescriptor = bindingContext.get(BindingContext.SCRIPT, declaration);
assert scriptDescriptor != null;
Type classType = state.getTypeMapper().mapType(scriptDescriptor);
ClassBuilder builder = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(declaration, scriptDescriptor),
classType, declaration.getContainingFile());
List<ScriptDescriptor> earlierScripts = state.getReplSpecific().getEarlierScriptsForReplInterpreter();
ScriptContext scriptContext = parentContext.intoScript(
scriptDescriptor,
earlierScripts == null ? Collections.emptyList() : earlierScripts,
scriptDescriptor,
state.getTypeMapper()
);
return new ScriptCodegen(declaration, state, scriptContext, builder);
}
private final KtScript scriptDeclaration;
private final ScriptContext context;
private final ScriptDescriptor scriptDescriptor;
private final Type classAsmType;
private ScriptCodegen(
@NotNull KtScript scriptDeclaration,
@NotNull GenerationState state,
@NotNull ScriptContext context,
@NotNull ClassBuilder builder
) {
super(state, null, context, scriptDeclaration, builder);
this.scriptDeclaration = scriptDeclaration;
this.context = context;
this.scriptDescriptor = context.getScriptDescriptor();
classAsmType = typeMapper.mapClass(context.getContextDescriptor());
}
@Override
protected void generateDeclaration() {
v.defineClass(scriptDeclaration,
state.getClassFileVersion(),
ACC_PUBLIC | ACC_SUPER,
classAsmType.getInternalName(),
null,
typeMapper.mapSupertype(DescriptorUtilsKt.getSuperClassOrAny(scriptDescriptor).getDefaultType(), null).getInternalName(),
CodegenUtilKt.mapSupertypesNames(typeMapper, DescriptorUtilsKt.getSuperInterfaces(scriptDescriptor), null));
}
@Override
protected void generateBody() {
genMembers();
genFieldsForParameters(v);
genConstructor(scriptDescriptor, v,
context.intoFunction(scriptDescriptor.getUnsubstitutedPrimaryConstructor()));
}
@Override
protected void generateSyntheticPartsBeforeBody() {
generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
}
@Override
protected void generateSyntheticPartsAfterBody() {
}
@Override
protected void generateKotlinMetadataAnnotation() {
generateKotlinClassMetadataAnnotation(scriptDescriptor, true);
}
private void genConstructor(
@NotNull ScriptDescriptor scriptDescriptor,
@NotNull ClassBuilder classBuilder,
@NotNull MethodContext methodContext
) {
JvmMethodSignature jvmSignature = typeMapper.mapScriptSignature(scriptDescriptor, context.getEarlierScripts());
if (state.getReplSpecific().getShouldGenerateScriptResultValue()) {
FieldInfo resultFieldInfo = context.getResultFieldInfo();
classBuilder.newField(
JvmDeclarationOrigin.NO_ORIGIN,
ACC_PUBLIC | ACC_FINAL,
resultFieldInfo.getFieldName(),
resultFieldInfo.getFieldType().getDescriptor(),
null,
null
);
}
MethodVisitor mv = classBuilder.newMethod(
JvmDeclarationOriginKt.OtherOrigin(scriptDeclaration, scriptDescriptor.getUnsubstitutedPrimaryConstructor()),
ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(),
null, null);
if (state.getClassBuilderMode().generateBodies) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
Type classType = typeMapper.mapType(scriptDescriptor);
ClassDescriptor superclass = DescriptorUtilsKt.getSuperClassNotAny(scriptDescriptor);
// TODO: throw if class is not found)
if (superclass == null) {
iv.load(0, classType);
iv.invokespecial("java/lang/Object", "<init>", "()V", false);
}
else {
ConstructorDescriptor ctorDesc = superclass.getUnsubstitutedPrimaryConstructor();
if (ctorDesc == null) throw new RuntimeException("Primary constructor not found for script template " + superclass.toString());
iv.load(0, classType);
int valueParamStart = context.getEarlierScripts().isEmpty() ? 1 : 2; // this + array of earlier scripts if not empty
List<ValueParameterDescriptor> valueParameters = scriptDescriptor.getUnsubstitutedPrimaryConstructor().getValueParameters();
for (ValueParameterDescriptor superclassParam: ctorDesc.getValueParameters()) {
ValueParameterDescriptor valueParam = null;
for (ValueParameterDescriptor vpd: valueParameters) {
if (vpd.getName().equals(superclassParam.getName())) {
valueParam = vpd;
break;
}
}
assert valueParam != null;
iv.load(valueParam.getIndex() + valueParamStart, typeMapper.mapType(valueParam.getType()));
}
CallableMethod ctorMethod = typeMapper.mapToCallableMethod(ctorDesc, false);
String sig = ctorMethod.getAsmMethod().getDescriptor();
iv.invokespecial(
typeMapper.mapSupertype(superclass.getDefaultType(), null).getInternalName(),
"<init>", sig, false);
}
iv.load(0, classType);
FrameMap frameMap = new FrameMap();
frameMap.enterTemp(OBJECT_TYPE);
if (!context.getEarlierScripts().isEmpty()) {
int scriptsParamIndex = frameMap.enterTemp(AsmUtil.getArrayType(OBJECT_TYPE));
int earlierScriptIndex = 0;
for (ScriptDescriptor earlierScript : context.getEarlierScripts()) {
Type earlierClassType = typeMapper.mapClass(earlierScript);
iv.load(0, classType);
iv.load(scriptsParamIndex, earlierClassType);
iv.aconst(earlierScriptIndex++);
iv.aload(OBJECT_TYPE);
iv.checkcast(earlierClassType);
iv.putfield(classType.getInternalName(), context.getScriptFieldName(earlierScript), earlierClassType.getDescriptor());
}
}
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, methodContext, state, this);
generateInitializers(() -> codegen);
iv.areturn(Type.VOID_TYPE);
}
mv.visitMaxs(-1, -1);
mv.visitEnd();
}
private void genFieldsForParameters(@NotNull ClassBuilder classBuilder) {
for (ScriptDescriptor earlierScript : context.getEarlierScripts()) {
Type earlierClassName = typeMapper.mapType(earlierScript);
int access = ACC_PUBLIC | ACC_FINAL;
classBuilder.newField(NO_ORIGIN, access, context.getScriptFieldName(earlierScript), earlierClassName.getDescriptor(), null, null);
}
}
private void genMembers() {
for (KtDeclaration declaration : scriptDeclaration.getDeclarations()) {
if (declaration instanceof KtProperty || declaration instanceof KtNamedFunction || declaration instanceof KtTypeAlias) {
genSimpleMember(declaration);
}
else if (declaration instanceof KtClassOrObject) {
genClassOrObject((KtClassOrObject) declaration);
}
else if (declaration instanceof KtDestructuringDeclaration) {
for (KtDestructuringDeclarationEntry entry : ((KtDestructuringDeclaration) declaration).getEntries()) {
genSimpleMember(entry);
}
}
}
}
}

View File

@@ -0,0 +1,217 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.context.MethodContext
import org.jetbrains.kotlin.codegen.context.ScriptContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN
import org.jetbrains.org.objectweb.asm.Opcodes.*
class ScriptCodegen private constructor(
private val scriptDeclaration: KtScript,
state: GenerationState,
private val scriptContext: ScriptContext,
builder: ClassBuilder
) : MemberCodegen<KtScript>(state, null, scriptContext, scriptDeclaration, builder) {
private val scriptDescriptor = scriptContext.scriptDescriptor
private val classAsmType = typeMapper.mapClass(scriptContext.contextDescriptor)
override fun generateDeclaration() {
v.defineClass(
scriptDeclaration,
state.classFileVersion,
ACC_PUBLIC or ACC_SUPER,
classAsmType.internalName,
null,
typeMapper.mapSupertype(scriptDescriptor.getSuperClassOrAny().defaultType, null).internalName,
mapSupertypesNames(typeMapper, scriptDescriptor.getSuperInterfaces(), null)
)
}
override fun generateBody() {
genMembers()
genFieldsForParameters(v)
genConstructor(scriptDescriptor, v, scriptContext.intoFunction(scriptDescriptor.unsubstitutedPrimaryConstructor))
}
override fun generateSyntheticPartsBeforeBody() {
generatePropertyMetadataArrayFieldIfNeeded(classAsmType)
}
override fun generateSyntheticPartsAfterBody() {}
override fun generateKotlinMetadataAnnotation() {
generateKotlinClassMetadataAnnotation(scriptDescriptor, true)
}
private fun genConstructor(
scriptDescriptor: ScriptDescriptor,
classBuilder: ClassBuilder,
methodContext: MethodContext
) {
val jvmSignature = typeMapper.mapScriptSignature(scriptDescriptor, scriptContext.earlierScripts)
if (state.replSpecific.shouldGenerateScriptResultValue) {
val resultFieldInfo = scriptContext.resultFieldInfo
classBuilder.newField(
JvmDeclarationOrigin.NO_ORIGIN,
ACC_PUBLIC or ACC_FINAL,
resultFieldInfo.fieldName,
resultFieldInfo.fieldType.descriptor,
null, null)
}
val mv = classBuilder.newMethod(
OtherOrigin(scriptDeclaration, scriptDescriptor.unsubstitutedPrimaryConstructor),
ACC_PUBLIC, jvmSignature.asmMethod.name, jvmSignature.asmMethod.descriptor, null, null)
if (state.classBuilderMode.generateBodies) {
mv.visitCode()
val iv = InstructionAdapter(mv)
val classType = typeMapper.mapType(scriptDescriptor)
val superclass = scriptDescriptor.getSuperClassNotAny()
// TODO: throw if class is not found)
if (superclass == null) {
iv.load(0, classType)
iv.invokespecial("java/lang/Object", "<init>", "()V", false)
}
else {
val ctorDesc = superclass.unsubstitutedPrimaryConstructor
?: throw RuntimeException("Primary constructor not found for script template " + superclass.toString())
iv.load(0, classType)
val valueParamStart = if (scriptContext.earlierScripts.isEmpty()) 1 else 2 // this + array of earlier scripts if not empty
val valueParameters = scriptDescriptor.unsubstitutedPrimaryConstructor.valueParameters
for (superclassParam in ctorDesc.valueParameters) {
val valueParam = valueParameters.first { it.name == superclassParam.name }
iv.load(valueParam!!.index + valueParamStart, typeMapper.mapType(valueParam.type))
}
val ctorMethod = typeMapper.mapToCallableMethod(ctorDesc, false)
val sig = ctorMethod.getAsmMethod().descriptor
iv.invokespecial(
typeMapper.mapSupertype(superclass.defaultType, null).internalName,
"<init>", sig, false)
}
iv.load(0, classType)
val frameMap = FrameMap()
frameMap.enterTemp(OBJECT_TYPE)
if (!scriptContext.earlierScripts.isEmpty()) {
val scriptsParamIndex = frameMap.enterTemp(AsmUtil.getArrayType(OBJECT_TYPE))
var earlierScriptIndex = 0
for (earlierScript in scriptContext.earlierScripts) {
val earlierClassType = typeMapper.mapClass(earlierScript)
iv.load(0, classType)
iv.load(scriptsParamIndex, earlierClassType)
iv.aconst(earlierScriptIndex++)
iv.aload(OBJECT_TYPE)
iv.checkcast(earlierClassType)
iv.putfield(classType.internalName, scriptContext.getScriptFieldName(earlierScript), earlierClassType.descriptor)
}
}
val codegen = ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, methodContext, state, this)
generateInitializers { codegen }
iv.areturn(Type.VOID_TYPE)
}
mv.visitMaxs(-1, -1)
mv.visitEnd()
}
private fun genFieldsForParameters(classBuilder: ClassBuilder) {
for (earlierScript in scriptContext.earlierScripts) {
val earlierClassName = typeMapper.mapType(earlierScript)
val access = ACC_PUBLIC or ACC_FINAL
classBuilder.newField(NO_ORIGIN, access, scriptContext.getScriptFieldName(earlierScript), earlierClassName.descriptor, null, null)
}
}
private fun genMembers() {
for (declaration in scriptDeclaration.declarations) {
if (declaration is KtProperty || declaration is KtNamedFunction || declaration is KtTypeAlias) {
genSimpleMember(declaration)
}
else if (declaration is KtClassOrObject) {
genClassOrObject(declaration)
}
else if (declaration is KtDestructuringDeclaration) {
for (entry in declaration.entries) {
genSimpleMember(entry)
}
}
}
}
companion object {
@JvmStatic
fun createScriptCodegen(
declaration: KtScript,
state: GenerationState,
parentContext: CodegenContext<*>
): MemberCodegen<KtScript> {
val bindingContext = state.bindingContext
val scriptDescriptor = bindingContext.get<PsiElement, ScriptDescriptor>(BindingContext.SCRIPT, declaration)!!
if (scriptDescriptor.isReplSnippet) {
return ScriptCodegenForRepl.createScriptCodegen(declaration, state, parentContext)
}
val classType = state.typeMapper.mapType(scriptDescriptor)
val builder = state.factory.newVisitor(
OtherOrigin(declaration, scriptDescriptor), classType, declaration.containingFile)
val earlierScripts = state.replSpecific.earlierScriptsForReplInterpreter
val scriptContext = parentContext.intoScript(
scriptDescriptor,
earlierScripts ?: emptyList(),
scriptDescriptor,
state.typeMapper
)
return ScriptCodegen(declaration, state, scriptContext, builder)
}
}
}

View File

@@ -0,0 +1,165 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.context.MethodContext
import org.jetbrains.kotlin.codegen.context.ScriptContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.Opcodes.*
class ScriptCodegenForRepl private constructor(
private val scriptDeclaration: KtScript,
state: GenerationState,
private val scriptContext: ScriptContext,
builder: ClassBuilder
) : MemberCodegen<KtScript>(state, null, scriptContext, scriptDeclaration, builder) {
private val scriptDescriptor = scriptContext.scriptDescriptor
private val classAsmType = typeMapper.mapClass(scriptContext.contextDescriptor)
override fun generateDeclaration() {
// Do not allow superclasses for REPL line scripts
assert(scriptDescriptor.getSuperClassNotAny() == null)
v.defineClass(
scriptDeclaration,
state.classFileVersion,
ACC_PUBLIC or ACC_SUPER,
classAsmType.internalName,
null,
"java/lang/Object",
mapSupertypesNames(typeMapper, scriptDescriptor.getSuperInterfaces(), null)
)
}
override fun generateBody() {
genMembers()
genDefaultConstructor(v)
genRunMethod(v, scriptContext.intoFunction(scriptDescriptor.unsubstitutedPrimaryConstructor))
genResultFieldIfNeeded(v)
}
override fun generateSyntheticPartsBeforeBody() {
generatePropertyMetadataArrayFieldIfNeeded(classAsmType)
}
override fun generateSyntheticPartsAfterBody() {}
override fun generateKotlinMetadataAnnotation() {
generateKotlinClassMetadataAnnotation(scriptDescriptor, true)
}
private fun genResultFieldIfNeeded(classBuilder: ClassBuilder) {
if (state.replSpecific.shouldGenerateScriptResultValue) {
val resultFieldInfo = scriptContext.resultFieldInfo
classBuilder.newField(
JvmDeclarationOrigin.NO_ORIGIN,
ACC_PUBLIC or ACC_FINAL or ACC_STATIC,
resultFieldInfo.fieldName,
resultFieldInfo.fieldType.descriptor,
null, null)
}
}
private fun genDefaultConstructor(classBuilder: ClassBuilder) {
val mv = classBuilder.newMethod(OtherOrigin(scriptDeclaration), ACC_PUBLIC, "<init>", "()V", null, null)
if (state.classBuilderMode.generateBodies) {
mv.visitCode()
with (InstructionAdapter(mv)) {
load(0, typeMapper.mapType(scriptDescriptor))
invokespecial("java/lang/Object", "<init>", "()V", false)
areturn(Type.VOID_TYPE)
}
}
mv.visitMaxs(-1, -1)
mv.visitEnd()
}
private fun genRunMethod(classBuilder: ClassBuilder, methodContext: MethodContext) {
val mv = classBuilder.newMethod(OtherOrigin(scriptDeclaration), ACC_PUBLIC or ACC_STATIC, RUN_METHOD_NAME, "()V", null, null)
if (state.classBuilderMode.generateBodies) {
mv.visitCode()
with (InstructionAdapter(mv)) {
val codegen = ExpressionCodegen(mv, FrameMap(), Type.VOID_TYPE, methodContext, state, this@ScriptCodegenForRepl)
generateInitializers { codegen }
areturn(Type.VOID_TYPE)
}
}
mv.visitMaxs(-1, -1)
mv.visitEnd()
}
private fun genMembers() {
for (declaration in scriptDeclaration.declarations) {
if (declaration is KtProperty || declaration is KtNamedFunction || declaration is KtTypeAlias) {
genSimpleMember(declaration)
}
else if (declaration is KtClassOrObject) {
genClassOrObject(declaration)
}
else if (declaration is KtDestructuringDeclaration) {
for (entry in declaration.entries) {
genSimpleMember(entry)
}
}
}
}
companion object {
val RUN_METHOD_NAME = "run"
@JvmStatic
fun createScriptCodegen(
declaration: KtScript,
state: GenerationState,
parentContext: CodegenContext<*>
): MemberCodegen<KtScript> {
val bindingContext = state.bindingContext
val scriptDescriptor = bindingContext.get<PsiElement, ScriptDescriptor>(BindingContext.SCRIPT, declaration)!!
val classType = state.typeMapper.mapType(scriptDescriptor)
val builder = state.factory.newVisitor(
OtherOrigin(declaration, scriptDescriptor), classType, declaration.containingFile)
val earlierScripts = state.replSpecific.earlierScriptsForReplInterpreter
val scriptContext = parentContext.intoScript(
scriptDescriptor,
earlierScripts ?: emptyList(),
scriptDescriptor,
state.typeMapper
)
return ScriptCodegenForRepl(declaration, state, scriptContext, builder)
}
}
}

View File

@@ -187,6 +187,9 @@ public abstract class StackValue {
else if (type == Type.BYTE_TYPE || type == Type.SHORT_TYPE || type == Type.INT_TYPE) {
return constant(Integer.valueOf(value), type);
}
else if (type == Type.CHAR_TYPE) {
return constant(Character.valueOf((char) value), type);
}
else {
throw new AssertionError("Unexpected integer type: " + type);
}
@@ -590,7 +593,7 @@ public abstract class StackValue {
}
private static StackValue platformStaticCallIfPresent(@NotNull StackValue resultReceiver, @NotNull CallableDescriptor descriptor) {
if (CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)) {
if (CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(descriptor)) {
if (resultReceiver.canHaveSideEffects()) {
return coercion(resultReceiver, Type.VOID_TYPE);
}

View File

@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen.binding;
@@ -33,6 +22,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice;
import org.jetbrains.kotlin.util.slicedMap.Slices;
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
import org.jetbrains.org.objectweb.asm.Type;
import java.util.*;
@@ -124,7 +114,8 @@ public class CodegenBinding {
return asmTypeForAnonymousClass(bindingContext, variableDescriptor);
}
throw new IllegalStateException("Couldn't compute ASM type for " + PsiUtilsKt.getElementTextWithContext(expression));
throw new KotlinExceptionWithAttachments("Couldn't compute ASM type for expression")
.withAttachment("expression.kt", PsiUtilsKt.getElementTextWithContext(expression));
}
@NotNull
@@ -142,7 +133,10 @@ public class CodegenBinding {
return false;
}
return classDescriptor.isInner() || !(classDescriptor.getContainingDeclaration() instanceof ClassDescriptor);
DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration();
return classDescriptor.isInner()
|| containingDeclaration instanceof ScriptDescriptor
|| !(containingDeclaration instanceof ClassDescriptor);
}
@NotNull

View File

@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.isSubclass
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
import org.jetbrains.kotlin.resolve.calls.callUtil.getFirstArgumentExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
@@ -252,12 +253,12 @@ fun reportTarget6InheritanceErrorIfNeeded(
}
}
fun CallableDescriptor.isJvmStaticInObjectOrClass(): Boolean =
fun CallableDescriptor.isJvmStaticInObjectOrClassOrInterface(): Boolean =
isJvmStaticIn {
DescriptorUtils.isNonCompanionObject(it) ||
// This is necessary because for generation of @JvmStatic methods from companion of class A
// we create a synthesized descriptor containing in class A
DescriptorUtils.isClassOrEnumClass(it)
DescriptorUtils.isClassOrEnumClass(it) || DescriptorUtils.isInterface(it)
}
fun CallableDescriptor.isJvmStaticInCompanionObject(): Boolean =
@@ -420,15 +421,15 @@ fun extractReificationArgument(type: KotlinType): Pair<TypeParameterDescriptor,
fun unwrapInitialSignatureDescriptor(function: FunctionDescriptor): FunctionDescriptor =
function.initialSignatureDescriptor ?: function
fun ExpressionCodegen.generateCallReceiver(rangeCall: ResolvedCall<out CallableDescriptor>): StackValue =
generateReceiverValue(rangeCall.extensionReceiver ?: rangeCall.dispatchReceiver!!, false)
fun ExpressionCodegen.generateCallReceiver(call: ResolvedCall<out CallableDescriptor>): StackValue =
generateReceiverValue(call.extensionReceiver ?: call.dispatchReceiver!!, false)
fun ExpressionCodegen.generateCallSingleArgument(rangeCall: ResolvedCall<out CallableDescriptor>): StackValue =
gen(ExpressionCodegen.getSingleArgumentExpression(rangeCall)!!)
fun ExpressionCodegen.generateCallSingleArgument(call: ResolvedCall<out CallableDescriptor>): StackValue =
gen(call.getFirstArgumentExpression()!!)
fun ClassDescriptor.isPossiblyUninitializedSingleton() =
DescriptorUtils.isEnumEntry(this) ||
DescriptorUtils.isCompanionObject(this) && DescriptorUtils.isInterface(this.containingDeclaration)
DescriptorUtils.isCompanionObject(this) && JvmCodegenUtil.isJvmInterface(this.containingDeclaration)
val CodegenContext<*>.parentContextsWithSelf
get() = generateSequence(this) { it.parentContext }
@@ -437,4 +438,4 @@ val CodegenContext<*>.parentContexts
get() = parentContext?.parentContextsWithSelf ?: emptySequence()
val CodegenContext<*>.contextStackText
get() = parentContextsWithSelf.joinToString(separator = "\n") { it.toString() }
get() = parentContextsWithSelf.joinToString(separator = "\n") { it.toString() }

View File

@@ -57,13 +57,16 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
private static class AccessorKey {
public final DeclarationDescriptor descriptor;
public final ClassDescriptor superCallLabelTarget;
public final FieldAccessorKind fieldAccessorKind;
public AccessorKey(
@NotNull DeclarationDescriptor descriptor,
@Nullable ClassDescriptor superCallLabelTarget
@Nullable ClassDescriptor superCallLabelTarget,
@NotNull FieldAccessorKind fieldAccessorKind
) {
this.descriptor = descriptor;
this.superCallLabelTarget = superCallLabelTarget;
this.fieldAccessorKind = fieldAccessorKind;
}
@Override
@@ -71,13 +74,16 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (!(obj instanceof AccessorKey)) return false;
AccessorKey other = (AccessorKey) obj;
return descriptor.equals(other.descriptor) &&
fieldAccessorKind == other.fieldAccessorKind &&
(superCallLabelTarget == null ? other.superCallLabelTarget == null
: superCallLabelTarget.equals(other.superCallLabelTarget));
}
@Override
public int hashCode() {
return 31 * descriptor.hashCode() + (superCallLabelTarget == null ? 0 : superCallLabelTarget.hashCode());
return 31 * descriptor.hashCode() +
fieldAccessorKind.hashCode() +
(superCallLabelTarget == null ? 0 : superCallLabelTarget.hashCode());
}
@Override
@@ -458,7 +464,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
D descriptor = (D) possiblySubstitutedDescriptor.getOriginal();
AccessorKey key = new AccessorKey(descriptor, superCallTarget);
AccessorKey key = new AccessorKey(descriptor, superCallTarget, accessorKind);
// NB should check for property accessor factory first (or change property accessor tracking under propertyAccessorFactory creation)
if (propertyAccessorFactories.containsKey(key)) {

View File

@@ -69,9 +69,15 @@ public class ScriptContext extends ClassContext {
public FieldInfo getResultFieldInfo() {
assert getState().getReplSpecific().getShouldGenerateScriptResultValue() : "Should not be called unless 'scriptResultFieldName' is set";
GenerationState state = getState();
String scriptResultFieldName = state.getReplSpecific().getScriptResultFieldName();
assert scriptResultFieldName != null;
return FieldInfo.createForHiddenField(state.getTypeMapper().mapClass(scriptDescriptor), AsmTypes.OBJECT_TYPE, scriptResultFieldName);
return FieldInfo.createForHiddenField(
state.getTypeMapper().mapClass(scriptDescriptor),
AsmTypes.OBJECT_TYPE,
scriptResultFieldName,
scriptDescriptor.isReplSnippet());
}
@NotNull

View File

@@ -531,6 +531,10 @@ class CoroutineCodegenForNamedFunction private constructor(
private const val COROUTINE_LAMBDA_PARAMETER_PREFIX = "p$"
private object FailingFunctionGenerationStrategy : FunctionGenerationStrategy() {
override fun skipNotNullAssertionsForParameters(): kotlin.Boolean {
error("This functions must not be called")
}
override fun generateBody(
mv: MethodVisitor,
frameMap: FrameMap,

View File

@@ -41,25 +41,26 @@ import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
class CoroutineTransformerMethodVisitor(
delegate: MethodVisitor,
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<out String>?,
private val containingClassInternalName: String,
obtainClassBuilderForCoroutineState: () -> ClassBuilder,
private val isForNamedFunction: Boolean,
private val shouldPreserveClassInitialization: Boolean,
private val element: KtElement,
// It's only matters for named functions, may differ from '!isStatic(access)' in case of DefaultImpls
private val needDispatchReceiver: Boolean = false,
// May differ from containingClassInternalName in case of DefaultImpls
private val internalNameForDispatchReceiver: String? = null
delegate: MethodVisitor,
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<out String>?,
private val containingClassInternalName: String,
obtainClassBuilderForCoroutineState: () -> ClassBuilder,
private val isForNamedFunction: Boolean,
private val shouldPreserveClassInitialization: Boolean,
private val element: KtElement,
// It's only matters for named functions, may differ from '!isStatic(access)' in case of DefaultImpls
private val needDispatchReceiver: Boolean = false,
// May differ from containingClassInternalName in case of DefaultImpls
private val internalNameForDispatchReceiver: String? = null
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
@@ -77,6 +78,8 @@ class CoroutineTransformerMethodVisitor(
FixStackMethodTransformer().transform(containingClassInternalName, methodNode)
if (isForNamedFunction) {
ReturnUnitMethodTransformer.transform(containingClassInternalName, methodNode)
if (allSuspensionPointsAreTailCalls(containingClassInternalName, methodNode, suspensionPoints)) {
dropSuspensionMarkers(methodNode, suspensionPoints)
return
@@ -117,22 +120,24 @@ class CoroutineTransformerMethodVisitor(
val lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0
// tableswitch(this.label)
insertBefore(actualCoroutineStart,
insnListOf(
*withInstructionAdapter { loadCoroutineSuspendedMarker() }.toArray(),
tableSwitchLabel,
// Allow debugger to stop on enter into suspend function
LineNumberNode(lineNumber, tableSwitchLabel),
VarInsnNode(Opcodes.ASTORE, suspendMarkerVarIndex),
VarInsnNode(Opcodes.ALOAD, continuationIndex),
createInsnForReadingLabel(),
TableSwitchInsnNode(0,
suspensionPoints.size,
defaultLabel,
startLabel, *suspensionPointLabels.toTypedArray()
),
startLabel
)
insertBefore(
actualCoroutineStart,
insnListOf(
*withInstructionAdapter { loadCoroutineSuspendedMarker() }.toArray(),
tableSwitchLabel,
// Allow debugger to stop on enter into suspend function
LineNumberNode(lineNumber, tableSwitchLabel),
VarInsnNode(Opcodes.ASTORE, suspendMarkerVarIndex),
VarInsnNode(Opcodes.ALOAD, continuationIndex),
createInsnForReadingLabel(),
TableSwitchInsnNode(
0,
suspensionPoints.size,
defaultLabel,
startLabel, *suspensionPointLabels.toTypedArray()
),
startLabel
)
)
insert(startLabel, withInstructionAdapter { generateResumeWithExceptionCheck(exceptionIndex) })
@@ -149,48 +154,48 @@ class CoroutineTransformerMethodVisitor(
}
private fun createInsnForReadingLabel() =
if (isForNamedFunction)
MethodInsnNode(
Opcodes.INVOKEVIRTUAL,
classBuilderForCoroutineState.thisName,
"getLabel",
Type.getMethodDescriptor(Type.INT_TYPE),
false
)
else
FieldInsnNode(
Opcodes.GETFIELD,
COROUTINE_IMPL_ASM_TYPE.internalName,
COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor
)
if (isForNamedFunction)
MethodInsnNode(
Opcodes.INVOKEVIRTUAL,
classBuilderForCoroutineState.thisName,
"getLabel",
Type.getMethodDescriptor(Type.INT_TYPE),
false
)
else
FieldInsnNode(
Opcodes.GETFIELD,
COROUTINE_IMPL_ASM_TYPE.internalName,
COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor
)
private fun createInsnForSettingLabel() =
if (isForNamedFunction)
MethodInsnNode(
Opcodes.INVOKEVIRTUAL,
classBuilderForCoroutineState.thisName,
"setLabel",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
false
)
else
FieldInsnNode(
Opcodes.PUTFIELD,
COROUTINE_IMPL_ASM_TYPE.internalName,
COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor
)
if (isForNamedFunction)
MethodInsnNode(
Opcodes.INVOKEVIRTUAL,
classBuilderForCoroutineState.thisName,
"setLabel",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
false
)
else
FieldInsnNode(
Opcodes.PUTFIELD,
COROUTINE_IMPL_ASM_TYPE.internalName,
COROUTINE_LABEL_FIELD_NAME, Type.INT_TYPE.descriptor
)
private fun updateMaxStack(methodNode: MethodNode) {
methodNode.instructions.resetLabels()
methodNode.accept(
MaxStackFrameSizeAndLocalsCalculator(
Opcodes.ASM5, methodNode.access, methodNode.desc,
object : MethodVisitor(Opcodes.ASM5) {
override fun visitMaxs(maxStack: Int, maxLocals: Int) {
methodNode.maxStack = maxStack
}
}
)
MaxStackFrameSizeAndLocalsCalculator(
Opcodes.ASM5, methodNode.access, methodNode.desc,
object : MethodVisitor(Opcodes.ASM5) {
override fun visitMaxs(maxStack: Int, maxLocals: Int) {
methodNode.maxStack = maxStack
}
}
)
)
}
@@ -232,10 +237,10 @@ class CoroutineTransformerMethodVisitor(
visitVarInsn(Opcodes.ALOAD, continuationIndex)
invokevirtual(
classBuilderForCoroutineState.thisName,
"getLabel",
Type.getMethodDescriptor(Type.INT_TYPE),
false
classBuilderForCoroutineState.thisName,
"getLabel",
Type.getMethodDescriptor(Type.INT_TYPE),
false
)
iconst(1 shl 31)
@@ -245,19 +250,19 @@ class CoroutineTransformerMethodVisitor(
visitVarInsn(Opcodes.ALOAD, continuationIndex)
dup()
invokevirtual(
classBuilderForCoroutineState.thisName,
"getLabel",
Type.getMethodDescriptor(Type.INT_TYPE),
false
classBuilderForCoroutineState.thisName,
"getLabel",
Type.getMethodDescriptor(Type.INT_TYPE),
false
)
iconst(1 shl 31)
sub(Type.INT_TYPE)
invokevirtual(
classBuilderForCoroutineState.thisName,
"setLabel",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
false
classBuilderForCoroutineState.thisName,
"setLabel",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
false
)
goTo(afterCoroutineStateCreated)
@@ -268,26 +273,26 @@ class CoroutineTransformerMethodVisitor(
dup()
val parameterTypesAndIndices =
getParameterTypesIndicesForCoroutineConstructor(
methodNode.desc,
methodNode.access,
needDispatchReceiver, internalNameForDispatchReceiver ?: containingClassInternalName
)
getParameterTypesIndicesForCoroutineConstructor(
methodNode.desc,
methodNode.access,
needDispatchReceiver, internalNameForDispatchReceiver ?: containingClassInternalName
)
for ((type, index) in parameterTypesAndIndices) {
load(index, type)
}
invokespecial(
classBuilderForCoroutineState.thisName,
"<init>",
Type.getMethodDescriptor(
Type.VOID_TYPE,
*getParameterTypesForCoroutineConstructor(
methodNode.desc, needDispatchReceiver,
internalNameForDispatchReceiver ?: containingClassInternalName
)
),
false
classBuilderForCoroutineState.thisName,
"<init>",
Type.getMethodDescriptor(
Type.VOID_TYPE,
*getParameterTypesForCoroutineConstructor(
methodNode.desc, needDispatchReceiver,
internalNameForDispatchReceiver ?: containingClassInternalName
)
),
false
)
visitVarInsn(Opcodes.ASTORE, continuationIndex)
@@ -391,13 +396,13 @@ class CoroutineTransformerMethodVisitor(
// k + 1 - data
// k + 2 - exception
val variablesToSpill =
(0 until localsCount)
.filter{ it !in setOf(continuationIndex, dataIndex, exceptionIndex) }
.map { Pair(it, frame.getLocal(it)) }
.filter { (index, value) ->
(index == 0 && needDispatchReceiver && isForNamedFunction) ||
(0 until localsCount)
.filter { it !in setOf(continuationIndex, dataIndex, exceptionIndex) }
.map { Pair(it, frame.getLocal(it)) }
.filter { (index, value) ->
(index == 0 && needDispatchReceiver && isForNamedFunction) ||
(value != StrictBasicValue.UNINITIALIZED_VALUE && livenessFrame.isAlive(index))
}
}
for ((index, basicValue) in variablesToSpill) {
if (basicValue === StrictBasicValue.NULL_VALUE) {
@@ -452,8 +457,9 @@ class CoroutineTransformerMethodVisitor(
val (type, maxIndex) = entry
for (index in 0..maxIndex) {
classBuilderForCoroutineState.newField(
JvmDeclarationOrigin.NO_ORIGIN, AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
type.fieldNameForVar(index), type.descriptor, null, null)
JvmDeclarationOrigin.NO_ORIGIN, AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
type.fieldNameForVar(index), type.descriptor, null, null
)
}
}
}
@@ -465,17 +471,17 @@ class CoroutineTransformerMethodVisitor(
get() {
assert(suspensionCallEnd.next is LabelNode) {
"Next instruction after ${this} should be a label, but " +
"${suspensionCallEnd.next::class.java}/${suspensionCallEnd.next.opcode} was found"
"${suspensionCallEnd.next::class.java}/${suspensionCallEnd.next.opcode} was found"
}
return suspensionCallEnd.next as LabelNode
}
private fun transformCallAndReturnContinuationLabel(
id: Int,
suspension: SuspensionPoint,
methodNode: MethodNode,
suspendMarkerVarIndex: Int
id: Int,
suspension: SuspensionPoint,
methodNode: MethodNode,
suspendMarkerVarIndex: Int
): LabelNode {
val continuationLabel = LabelNode()
val continuationLabelAfterLoadedResult = LabelNode()
@@ -483,12 +489,13 @@ class CoroutineTransformerMethodVisitor(
val nextLineNumberNode = suspension.suspensionCallEnd.findNextOrNull { it is LineNumberNode } as? LineNumberNode
with(methodNode.instructions) {
// Save state
insertBefore(suspension.suspensionCallBegin,
insnListOf(
VarInsnNode(Opcodes.ALOAD, continuationIndex),
*withInstructionAdapter { iconst(id) }.toArray(),
createInsnForSettingLabel()
)
insertBefore(
suspension.suspensionCallBegin,
insnListOf(
VarInsnNode(Opcodes.ALOAD, continuationIndex),
*withInstructionAdapter { iconst(id) }.toArray(),
createInsnForSettingLabel()
)
)
insert(suspension.tryCatchBlockEndLabelAfterSuspensionCall, withInstructionAdapter {
@@ -573,16 +580,17 @@ class CoroutineTransformerMethodVisitor(
methodNode.tryCatchBlocks =
methodNode.tryCatchBlocks.flatMap {
val isContainingSuspensionPoint =
instructions.indexOf(it.start) < beginIndex && beginIndex < instructions.indexOf(it.end)
instructions.indexOf(it.start) < beginIndex && beginIndex < instructions.indexOf(it.end)
if (isContainingSuspensionPoint) {
assert(instructions.indexOf(it.start) < endIndex && endIndex < instructions.indexOf(it.end)) {
"Try catch block containing marker before suspension point should also contain the marker after suspension point"
}
listOf(TryCatchBlockNode(it.start, firstLabel, it.handler, it.type),
TryCatchBlockNode(secondLabel, it.end, it.handler, it.type))
}
else
listOf(
TryCatchBlockNode(it.start, firstLabel, it.handler, it.type),
TryCatchBlockNode(secondLabel, it.end, it.handler, it.type)
)
} else
listOf(it)
}
@@ -630,10 +638,10 @@ private fun Type.normalize() =
* INVOKESTATIC InlineMarker.mark()
*/
private class SuspensionPoint(
// ICONST_0
val suspensionCallBegin: AbstractInsnNode,
// INVOKESTATIC InlineMarker.mark()
val suspensionCallEnd: AbstractInsnNode
// ICONST_0
val suspensionCallBegin: AbstractInsnNode,
// INVOKESTATIC InlineMarker.mark()
val suspensionCallEnd: AbstractInsnNode
) {
lateinit var tryCatchBlocksContinuationLabel: LabelNode
@@ -649,59 +657,68 @@ private class SuspensionPoint(
}
private fun getLastParameterIndex(desc: String, access: Int) =
Type.getArgumentTypes(desc).dropLast(1).map { it.size }.sum() + (if (!isStatic(access)) 1 else 0)
Type.getArgumentTypes(desc).dropLast(1).map { it.size }.sum() + (if (!isStatic(access)) 1 else 0)
private fun getParameterTypesForCoroutineConstructor(desc: String, hasDispatchReceiver: Boolean, thisName: String) =
listOfNotNull(if (!hasDispatchReceiver) null else Type.getObjectType(thisName)).toTypedArray() +
Type.getArgumentTypes(desc).last()
listOfNotNull(if (!hasDispatchReceiver) null else Type.getObjectType(thisName)).toTypedArray() +
Type.getArgumentTypes(desc).last()
private fun isStatic(access: Int) = access and Opcodes.ACC_STATIC != 0
private fun getParameterTypesIndicesForCoroutineConstructor(
desc: String,
containingFunctionAccess: Int,
needDispatchReceiver: Boolean,
thisName: String
desc: String,
containingFunctionAccess: Int,
needDispatchReceiver: Boolean,
thisName: String
): Collection<Pair<Type, Int>> {
return mutableListOf<Pair<Type, Int>>().apply {
if (needDispatchReceiver) {
add(Type.getObjectType(thisName) to 0)
}
val continuationIndex =
getAllParameterTypes(desc, !isStatic(containingFunctionAccess), thisName).dropLast(1).map(Type::getSize).sum()
getAllParameterTypes(desc, !isStatic(containingFunctionAccess), thisName).dropLast(1).map(Type::getSize).sum()
add(CONTINUATION_ASM_TYPE to continuationIndex)
}
}
private fun getAllParameterTypes(desc: String, hasDispatchReceiver: Boolean, thisName: String) =
listOfNotNull(if (!hasDispatchReceiver) null else Type.getObjectType(thisName)).toTypedArray() +
Type.getArgumentTypes(desc)
listOfNotNull(if (!hasDispatchReceiver) null else Type.getObjectType(thisName)).toTypedArray() +
Type.getArgumentTypes(desc)
private fun allSuspensionPointsAreTailCalls(
thisName: String,
methodNode: MethodNode,
suspensionPoints: List<SuspensionPoint>
thisName: String,
methodNode: MethodNode,
suspensionPoints: List<SuspensionPoint>
): Boolean {
val safelyReachableReturns = findSafelyReachableReturns(methodNode)
val sourceFrames = MethodTransformer.analyze(thisName, methodNode, IgnoringCopyOperationSourceInterpreter())
val safelyReachableReturns = findSafelyReachableReturns(methodNode, sourceFrames)
val instructions = methodNode.instructions
return suspensionPoints.all { suspensionPoint ->
val beginIndex = instructions.indexOf(suspensionPoint.suspensionCallBegin)
val endIndex = instructions.indexOf(suspensionPoint.suspensionCallEnd)
safelyReachableReturns[endIndex + 1]?.all { returnIndex ->
val sourceInsn =
sourceFrames[returnIndex].top().sure {
"There must be some value on stack to return"
}.insns.singleOrNull()
if (isUnreachable(beginIndex, sourceFrames)) return@all true
sourceInsn?.let(instructions::indexOf) in beginIndex..endIndex
val insideTryBlock = methodNode.tryCatchBlocks.any { block ->
val tryBlockStartIndex = instructions.indexOf(block.start)
val tryBlockEndIndex = instructions.indexOf(block.end)
beginIndex in tryBlockStartIndex..tryBlockEndIndex
}
if (insideTryBlock) return@all false
safelyReachableReturns[endIndex + 1]?.all { returnIndex ->
sourceFrames[returnIndex].top().sure {
"There must be some value on stack to return"
}.insns.all { sourceInsn ->
sourceInsn?.let(instructions::indexOf) in beginIndex..endIndex
}
} ?: false
}
}
private class IgnoringCopyOperationSourceInterpreter : SourceInterpreter() {
internal class IgnoringCopyOperationSourceInterpreter : SourceInterpreter() {
override fun copyOperation(insn: AbstractInsnNode?, value: SourceValue?) = value
}
@@ -714,22 +731,22 @@ private class IgnoringCopyOperationSourceInterpreter : SourceInterpreter() {
*
* @return indices of safely reachable returns for each instruction in the method node
*/
private fun findSafelyReachableReturns(methodNode: MethodNode): Array<Set<Int>?> {
private fun findSafelyReachableReturns(methodNode: MethodNode, sourceFrames: Array<Frame<SourceValue?>?>): Array<Set<Int>?> {
val controlFlowGraph = ControlFlowGraph.build(methodNode)
val insns = methodNode.instructions
val reachableReturnsIndices = Array<Set<Int>?>(insns.size()) init@{ index ->
val reachableReturnsIndices = Array<Set<Int>?>(insns.size()) init@ { index ->
val insn = insns[index]
if (insn.opcode == Opcodes.ARETURN) {
if (isUnreachable(index, sourceFrames)) return@init null
return@init setOf(index)
}
if (!insn.isMeaningful || insn.opcode in SAFE_OPCODES || insn.isInvisibleInDebugVarInsn(methodNode) ||
isInlineMarker(insn)) {
setOf()
}
else null
} else null
}
var changed: Boolean
@@ -740,12 +757,12 @@ private fun findSafelyReachableReturns(methodNode: MethodNode): Array<Set<Int>?>
@Suppress("RemoveExplicitTypeArguments")
val newResult =
controlFlowGraph
.getSuccessorsIndices(index).plus(index)
.map(reachableReturnsIndices::get)
.fold<Set<Int>?, Set<Int>?>(mutableSetOf<Int>()) { acc, successorsResult ->
if (acc != null && successorsResult != null) acc + successorsResult else null
}
controlFlowGraph
.getSuccessorsIndices(index).plus(index)
.map(reachableReturnsIndices::get)
.fold<Set<Int>?, Set<Int>?>(mutableSetOf<Int>()) { acc, successorsResult ->
if (acc != null && successorsResult != null) acc + successorsResult else null
}
if (newResult != reachableReturnsIndices[index]) {
reachableReturnsIndices[index] = newResult
@@ -757,6 +774,9 @@ private fun findSafelyReachableReturns(methodNode: MethodNode): Array<Set<Int>?>
return reachableReturnsIndices
}
// Check whether this instruction is unreachable, i.e. there is no path leading to this instruction
internal fun isUnreachable(index: Int, sourceFrames: Array<Frame<SourceValue?>?>) = sourceFrames[index] == null
private fun AbstractInsnNode?.isInvisibleInDebugVarInsn(methodNode: MethodNode): Boolean {
val insns = methodNode.instructions
val index = insns.indexOf(this)
@@ -766,4 +786,4 @@ private fun AbstractInsnNode?.isInvisibleInDebugVarInsn(methodNode: MethodNode):
}
private val SAFE_OPCODES =
((Opcodes.DUP..Opcodes.DUP2_X2) + Opcodes.NOP + Opcodes.POP + Opcodes.POP2 + (Opcodes.IFEQ..Opcodes.GOTO)).toSet()
((Opcodes.DUP..Opcodes.DUP2_X2) + Opcodes.NOP + Opcodes.POP + Opcodes.POP2 + (Opcodes.IFEQ..Opcodes.GOTO)).toSet()

View File

@@ -0,0 +1,134 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen.coroutines
import org.jetbrains.kotlin.codegen.inline.isReturnsUnitMarker
import org.jetbrains.kotlin.codegen.optimization.boxing.isUnitInstance
import org.jetbrains.kotlin.codegen.optimization.common.ControlFlowGraph
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
import org.jetbrains.kotlin.codegen.optimization.common.removeAll
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.keysToMap
import org.jetbrains.kotlin.utils.sure
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.*
/*
* Replace POP with ARETURN iff
* 1) It is immediately followed by { GETSTATIC Unit.INSTANCE, ARETURN } sequences
* 2) It is poping Unit
*/
object ReturnUnitMethodTransformer : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) {
val unitMarks = findReturnsUnitMarks(methodNode)
if (unitMarks.isEmpty()) return
val units = findReturnUnitSequences(methodNode)
if (units.isEmpty()) {
cleanUpReturnsUnitMarkers(methodNode, unitMarks)
return
}
val pops = methodNode.instructions.asSequence().filter { it.opcode == Opcodes.POP }.toList()
val popSuccessors = findSuccessors(methodNode, pops)
val sourceInsns = findSourceInstructions(internalClassName, methodNode, pops)
val safePops = filterOutUnsafes(popSuccessors, units, sourceInsns)
// Replace POP with ARETURN for tail call optimization
safePops.forEach { methodNode.instructions.set(it, InsnNode(Opcodes.ARETURN)) }
cleanUpReturnsUnitMarkers(methodNode, unitMarks)
}
// Return list of POPs, which can be safely replaced by ARETURNs
private fun filterOutUnsafes(
popSuccessors: Map<AbstractInsnNode, Collection<AbstractInsnNode>>,
units: Collection<AbstractInsnNode>,
sourceInsns: Map<AbstractInsnNode, Collection<AbstractInsnNode>>
): Collection<AbstractInsnNode> {
return popSuccessors.filter { (pop, successors) ->
successors.all { it in units } &&
sourceInsns[pop].sure { "Sources of $pop cannot be null" }.all(::isSuspendingCallReturningUnit)
}.keys
}
// Find instructions which do something on stack, ignoring markers
// Return map {insn => list of found instructions}
private fun findSuccessors(
methodNode: MethodNode,
insns: List<AbstractInsnNode>
): Map<AbstractInsnNode, Collection<AbstractInsnNode>> {
val cfg = ControlFlowGraph.build(methodNode)
return insns.keysToMap { findSuccessorsDFS(it, cfg, methodNode) }
}
// Find all meaningful successors of insn
private fun findSuccessorsDFS(insn: AbstractInsnNode, cfg: ControlFlowGraph, methodNode: MethodNode): Collection<AbstractInsnNode> {
val visited = hashSetOf<AbstractInsnNode>()
fun dfs(current: AbstractInsnNode): Collection<AbstractInsnNode> {
if (!visited.add(current)) return emptySet()
return cfg.getSuccessorsIndices(current).flatMap {
val succ = methodNode.instructions[it]
when {
!succ.isMeaningful || succ is JumpInsnNode || succ.opcode == Opcodes.NOP -> dfs(succ)
succ.isUnitInstance() -> {
// There can be multiple chains of { UnitInstance, POP } after inlining. Ignore them
val newSuccessors = dfs(succ)
if (newSuccessors.all { it.opcode == Opcodes.POP }) newSuccessors.flatMap { dfs(it) }
else setOf(succ)
}
else -> setOf(succ)
}
}
}
return dfs(insn)
}
private fun isSuspendingCallReturningUnit(node: AbstractInsnNode): Boolean =
node.safeAs<MethodInsnNode>()?.next?.next?.let(::isReturnsUnitMarker) == true
private fun findSourceInstructions(
internalClassName: String,
methodNode: MethodNode,
pops: Collection<AbstractInsnNode>
): Map<AbstractInsnNode, Collection<AbstractInsnNode>> {
val frames = analyze(internalClassName, methodNode, IgnoringCopyOperationSourceInterpreter())
return pops.keysToMap {
val index = methodNode.instructions.indexOf(it)
if (isUnreachable(index, frames)) return@keysToMap emptySet<AbstractInsnNode>()
frames[index].getStack(0).insns
}
}
// Find { GETSTATIC kotlin/Unit.INSTANCE, ARETURN } sequences
// Result is list of GETSTATIC kotlin/Unit.INSTANCE instructions
private fun findReturnUnitSequences(methodNode: MethodNode): Collection<AbstractInsnNode> =
methodNode.instructions.asSequence().filter { it.isUnitInstance() && it.next?.opcode == Opcodes.ARETURN }.toList()
private fun findReturnsUnitMarks(methodNode: MethodNode): Collection<AbstractInsnNode> =
methodNode.instructions.asSequence().filter(::isReturnsUnitMarker).toList()
private fun cleanUpReturnsUnitMarkers(methodNode: MethodNode, unitMarks: Collection<AbstractInsnNode>) {
unitMarks.forEach { methodNode.instructions.removeAll(listOf(it.previous, it)) }
}
}

View File

@@ -68,7 +68,7 @@ open class FieldRemapper(
val insnNode = capturedFieldAccess[currentInstruction] as FieldInsnNode
if (canProcess(insnNode.owner, insnNode.name, true)) {
insnNode.name = CAPTURED_FIELD_FOLD_PREFIX + getFieldNameForFolding(insnNode)
insnNode.name = Companion.foldName(getFieldNameForFolding(insnNode))
insnNode.opcode = Opcodes.GETSTATIC
node.remove(InsnSequence(capturedFieldAccess[0], insnNode))
@@ -95,4 +95,9 @@ open class FieldRemapper(
open fun getFieldForInline(node: FieldInsnNode, prefix: StackValue?): StackValue? =
MethodInliner.findCapturedField(node, this).remapValue
companion object {
fun foldName(fieldName: String) =
CAPTURED_FIELD_FOLD_PREFIX + fieldName
}
}

View File

@@ -51,6 +51,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral
import org.jetbrains.kotlin.types.expressions.LabelResolver
import org.jetbrains.org.objectweb.asm.Opcodes
@@ -157,18 +159,13 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
}
fun performInline(
resolvedCall: ResolvedCall<*>?,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
callDefault: Boolean,
codegen: BaseExpressionCodegen
) {
if (!state.inlineCycleReporter.enterIntoInlining(resolvedCall)) {
generateStub(resolvedCall, codegen)
return
}
var nodeAndSmap: SMAPAndMethodNode? = null
try {
nodeAndSmap = createInlineMethodNode(functionDescriptor, jvmSignature, callDefault, resolvedCall, state, sourceCompiler)
nodeAndSmap = createInlineMethodNode(functionDescriptor, jvmSignature, callDefault, typeArguments, state, sourceCompiler)
endCall(inlineCall(nodeAndSmap, callDefault))
}
catch (e: CompilationException) {
@@ -180,9 +177,6 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
catch (e: Exception) {
throw throwCompilationException(nodeAndSmap, e, true)
}
finally {
state.inlineCycleReporter.exitFromInliningOf(resolvedCall)
}
}
private fun canSkipStackSpillingOnInline(methodNode: MethodNode): Boolean {
@@ -475,17 +469,15 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
functionDescriptor: FunctionDescriptor,
jvmSignature: JvmMethodSignature,
callDefault: Boolean,
resolvedCall: ResolvedCall<*>?,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
state: GenerationState,
sourceCompilerForInline: SourceCompilerForInline
): SMAPAndMethodNode {
when {
isSpecialEnumMethod(functionDescriptor) -> {
val arguments = resolvedCall!!.typeArguments
val node = createSpecialEnumMethodBody(
functionDescriptor.name.asString(),
arguments.keys.single().defaultType,
typeArguments!!.keys.single().defaultType,
state.typeMapper
)
return SMAPAndMethodNode(node, SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1))
@@ -674,7 +666,15 @@ class PsiInlineCodegen(
callDefault: Boolean,
codegen: ExpressionCodegen
) {
performInline(resolvedCall, callDefault, codegen)
if (!state.inlineCycleReporter.enterIntoInlining(resolvedCall)) {
generateStub(resolvedCall, codegen)
return
}
try {
performInline(resolvedCall?.typeArguments, callDefault, codegen)
} finally {
state.inlineCycleReporter.exitFromInliningOf(resolvedCall)
}
}
override fun processAndPutHiddenParameters(justProcess: Boolean) {
@@ -698,7 +698,7 @@ class PsiInlineCodegen(
override fun putClosureParametersOnStack(next: LambdaInfo, functionReferenceReceiver: StackValue?) {
activeLambda = next
when (next) {
is ExpressionLambda -> codegen.pushClosureOnStack(next.classDescriptor, true, this, functionReferenceReceiver)
is PsiExpressionLambda -> codegen.pushClosureOnStack(next.classDescriptor, true, this, functionReferenceReceiver)
is DefaultLambda -> rememberCapturedForDefaultLambda(next)
else -> throw RuntimeException("Unknown lambda: $next")
}
@@ -744,7 +744,7 @@ class PsiInlineCodegen(
val ktLambda = KtPsiUtil.deparenthesize(expression)
assert(isInlinableParameterExpression(ktLambda)) { "Couldn't find inline expression in ${expression.text}" }
return ExpressionLambda(
return PsiExpressionLambda(
ktLambda!!, typeMapper, parameter.isCrossinline, getBoundCallableReferenceReceiver(expression) != null
).also { lambda ->
val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index)

View File

@@ -57,6 +57,8 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : LabelOwner {
abstract fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner)
open val hasDispatchReceiver = true
fun addAllParameters(remapper: FieldRemapper): Parameters {
val builder = ParametersBuilder.initializeBuilderFrom(AsmTypes.OBJECT_TYPE, invokeMethod.descriptor, this)
@@ -164,7 +166,7 @@ class DefaultLambda(
classReader.b,
invokeMethod.name,
invokeMethod.descriptor,
lambdaClassType)!!
lambdaClassType) ?: error("Can't find method '${invokeMethod.name}${invokeMethod.descriptor}' in '${classReader.className}'")
if (needReification) {
//nested classes could also require reification
@@ -175,13 +177,32 @@ class DefaultLambda(
fun Type.boxReceiverForBoundReference() = AsmUtil.boxType(this)
abstract class ExpressionLambda(protected val typeMapper: KotlinTypeMapper, isCrossInline: Boolean): LambdaInfo(isCrossInline) {
class ExpressionLambda(
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
val jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor)
val asmMethod = jvmMethodSignature.asmMethod
val methodNode = MethodNode(
API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, OwnerKind.IMPLEMENTATION, sourceCompiler.state),
asmMethod.name, asmMethod.descriptor, null, null
)
node = wrapWithMaxLocalCalc(methodNode).let { adapter ->
val smap = sourceCompiler.generateLambdaBody(
adapter, jvmMethodSignature, this
)
adapter.visitMaxs(-1, -1)
SMAPAndMethodNode(methodNode, smap)
}
}
}
class PsiExpressionLambda(
expression: KtExpression,
private val typeMapper: KotlinTypeMapper,
typeMapper: KotlinTypeMapper,
isCrossInline: Boolean,
override val isBoundCallableReference: Boolean
) : LambdaInfo(isCrossInline) {
) : ExpressionLambda(typeMapper, isCrossInline) {
override val lambdaClassType: Type
@@ -268,21 +289,4 @@ class ExpressionLambda(
val isPropertyReference: Boolean
get() = propertyReferenceInfo != null
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
val jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor)
val asmMethod = jvmMethodSignature.asmMethod
val methodNode = MethodNode(
API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, OwnerKind.IMPLEMENTATION, sourceCompiler.state),
asmMethod.name, asmMethod.descriptor, null, null
)
node = wrapWithMaxLocalCalc(methodNode).let { adapter ->
val smap = sourceCompiler.generateLambdaBody(
adapter, jvmMethodSignature, this
)
adapter.visitMaxs(-1, -1)
SMAPAndMethodNode(methodNode, smap)
}
}
}

View File

@@ -16,14 +16,17 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.backend.jvm.codegen.IrExpressionLambda
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.ClosureCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.inline.FieldRemapper.Companion.foldName
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.optimization.ApiVersionCallsPreprocessingMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
import org.jetbrains.kotlin.codegen.optimization.fixStack.peek
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.SmartSet
@@ -164,7 +167,9 @@ class MethodInliner(
result.merge(transformResult)
result.addChangedType(oldClassName, newClassName)
if (inliningContext.isInliningLambda && transformationInfo!!.canRemoveAfterTransformation()) {
if (inliningContext.isInliningLambda &&
inliningContext.lambdaInfo !is DefaultLambda && //never delete default lambda classes
transformationInfo!!.canRemoveAfterTransformation()) {
// this class is transformed and original not used so we should remove original one after inlining
result.addClassToRemove(oldClassName)
}
@@ -180,7 +185,7 @@ class MethodInliner(
}
override fun anew(type: Type) {
if (isAnonymousClass(type.internalName)) {
if (isSamWrapper(type.internalName) || isAnonymousClass(type.internalName)) {
handleAnonymousObjectRegeneration()
}
@@ -220,15 +225,20 @@ class MethodInliner(
setLambdaInlining(true)
val lambdaSMAP = info.node.classSMAP
val sourceMapper = if (inliningContext.classRegeneration && !inliningContext.isInliningLambda)
NestedSourceMapper(sourceMapper, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
else
InlineLambdaSourceMapper(sourceMapper.parent!!, info.node)
val childSourceMapper =
if (inliningContext.classRegeneration && !inliningContext.isInliningLambda)
NestedSourceMapper(sourceMapper, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
else if (info is DefaultLambda) {
NestedSourceMapper(sourceMapper.parent!!, lambdaSMAP.intervals, lambdaSMAP.sourceInfo)
}
else InlineLambdaSourceMapper(sourceMapper.parent!!, info.node)
val inliner = MethodInliner(
info.node.node, lambdaParameters, inliningContext.subInlineLambda(info),
newCapturedRemapper, true /*cause all calls in same module as lambda*/,
newCapturedRemapper,
if (info is DefaultLambda) isSameModule else true /*cause all nested objects in same module as lambda*/,
"Lambda inlining " + info.lambdaClassType.internalName,
sourceMapper, inlineCallSiteInfo, null
childSourceMapper, inlineCallSiteInfo, null
)
val varRemapper = LocalVarRemapper(lambdaParameters, valueParamShift)
@@ -242,7 +252,7 @@ class MethodInliner(
StackValue.onStack(info.invokeMethod.returnType).put(bridge.returnType, this)
setLambdaInlining(false)
addInlineMarker(this, false)
sourceMapper.endMapping()
childSourceMapper.endMapping()
inlineOnlySmapSkipper?.markCallSiteLineNumber(remappingMethodAdapter)
}
else if (isAnonymousConstructorCall(owner, name)) { //TODO add method
@@ -320,17 +330,29 @@ class MethodInliner(
val capturedParamsSize = parameters.capturedParametersSizeOnStack
val realParametersSize = parameters.realParametersSizeOnStack
val transformedNode = MethodNode(
API, node.access, node.name,
Type.getMethodDescriptor(Type.getReturnType(node.desc), *(Type.getArgumentTypes(node.desc) + parameters.capturedTypes)),
node.signature, node.exceptions?.toTypedArray()
)
val transformedNode = object : MethodNode(
API, node.access, node.name,
Type.getMethodDescriptor(Type.getReturnType(node.desc), *(Type.getArgumentTypes(node.desc) + parameters.capturedTypes)),
node.signature, node.exceptions?.toTypedArray()
) {
val transformationVisitor = object : MethodVisitor(API, transformedNode) {
private val GENERATE_DEBUG_INFO = GENERATE_SMAP && inlineOnlySmapSkipper == null
private val isInliningLambda = nodeRemapper.isInsideInliningLambda
private fun getNewIndex(`var`: Int): Int {
if (inliningContext.isInliningLambda && inliningContext.lambdaInfo is IrExpressionLambda) {
if (`var` < parameters.argsSizeOnStack) {
if (`var` < capturedParamsSize) {
return `var` + realParametersSize
}
else {
return `var` - capturedParamsSize
}
}
return `var`
}
return `var` + if (`var` < realParametersSize) 0 else capturedParamsSize
}
@@ -383,7 +405,7 @@ class MethodInliner(
}
}
node.accept(transformedNode)
node.accept(transformationVisitor)
transformCaptured(transformedNode)
transformFinallyDeepIndex(transformedNode, finallyDeepShift)
@@ -410,82 +432,111 @@ class MethodInliner(
val frame = sources[instructions.indexOf(cur)]
if (frame != null) {
if (ReifiedTypeInliner.isNeedClassReificationMarker(cur)) {
awaitClassReification = true
}
else if (cur is MethodInsnNode) {
if (isFinallyStart(cur)) {
//TODO deep index calc could be more precise
currentFinallyDeep = getConstant(cur.previous)
}
when {
ReifiedTypeInliner.isNeedClassReificationMarker(cur) -> awaitClassReification = true
val owner = cur.owner
val name = cur.name
//TODO check closure
val argTypes = Type.getArgumentTypes(cur.desc)
val paramCount = argTypes.size + 1//non static
val firstParameterIndex = frame.stackSize - paramCount
if (isInvokeOnLambda(owner, name) /*&& methodInsnNode.owner.equals(INLINE_RUNTIME)*/) {
val sourceValue = frame.getStack(firstParameterIndex)
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, true, instructions, sources, toDelete)
invokeCalls.add(InvokeCall(lambdaInfo, currentFinallyDeep))
}
else if (isAnonymousConstructorCall(owner, name)) {
val lambdaMapping = HashMap<Int, LambdaInfo>()
var offset = 0
var capturesAnonymousObjectThatMustBeRegenerated = false
for (i in 0..paramCount - 1) {
val sourceValue = frame.getStack(firstParameterIndex + i)
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, false, instructions, sources, toDelete
)
if (lambdaInfo != null) {
lambdaMapping.put(offset, lambdaInfo)
}
else if (i < argTypes.size && isAnonymousClassThatMustBeRegenerated(argTypes[i])) {
capturesAnonymousObjectThatMustBeRegenerated = true
}
offset += if (i == 0) 1 else argTypes[i - 1].size
cur is MethodInsnNode -> {
if (isFinallyStart(cur)) {
//TODO deep index calc could be more precise
currentFinallyDeep = getConstant(cur.previous)
}
transformations.add(
buildConstructorInvocation(
owner, cur.desc, lambdaMapping, awaitClassReification, capturesAnonymousObjectThatMustBeRegenerated
val owner = cur.owner
val name = cur.name
//TODO check closure
val argTypes = Type.getArgumentTypes(cur.desc)
val paramCount = argTypes.size + 1//non static
val firstParameterIndex = frame.stackSize - paramCount
if (isInvokeOnLambda(owner, name) /*&& methodInsnNode.owner.equals(INLINE_RUNTIME)*/) {
val sourceValue = frame.getStack(firstParameterIndex)
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, true, instructions, sources, toDelete)
invokeCalls.add(InvokeCall(lambdaInfo, currentFinallyDeep))
}
else if (isSamWrapperConstructorCall(owner, name)) {
transformations.add(SamWrapperTransformationInfo(owner, inliningContext, isAlreadyRegenerated(owner)))
}
else if (isAnonymousConstructorCall(owner, name)) {
val lambdaMapping = HashMap<Int, LambdaInfo>()
var offset = 0
var capturesAnonymousObjectThatMustBeRegenerated = false
for (i in 0 until paramCount) {
val sourceValue = frame.getStack(firstParameterIndex + i)
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(sourceValue, false, instructions, sources, toDelete
)
)
awaitClassReification = false
if (lambdaInfo != null) {
lambdaMapping.put(offset, lambdaInfo)
}
else if (i < argTypes.size && isAnonymousClassThatMustBeRegenerated(argTypes[i])) {
capturesAnonymousObjectThatMustBeRegenerated = true
}
offset += if (i == 0) 1 else argTypes[i - 1].size
}
transformations.add(
buildConstructorInvocation(
owner, cur.desc, lambdaMapping, awaitClassReification, capturesAnonymousObjectThatMustBeRegenerated
)
)
awaitClassReification = false
}
else if (inliningContext.isInliningLambda && ReifiedTypeInliner.isOperationReifiedMarker(cur)) {
val reificationArgument = cur.reificationArgument
val parameterName = reificationArgument!!.parameterName
result.reifiedTypeParametersUsages.addUsedReifiedParameter(parameterName)
}
}
else if (inliningContext.isInliningLambda && ReifiedTypeInliner.isOperationReifiedMarker(cur)) {
val reificationArgument = cur.reificationArgument
val parameterName = reificationArgument!!.parameterName
result.reifiedTypeParametersUsages.addUsedReifiedParameter(parameterName)
cur.opcode == Opcodes.GETSTATIC -> {
val fieldInsnNode = cur as FieldInsnNode?
val className = fieldInsnNode!!.owner
if (isAnonymousSingletonLoad(className, fieldInsnNode.name)) {
transformations.add(
AnonymousObjectTransformationInfo(
className, awaitClassReification, isAlreadyRegenerated(className), true,
inliningContext.nameGenerator
)
)
awaitClassReification = false
}
else if (isWhenMappingAccess(className, fieldInsnNode.name)) {
transformations.add(
WhenMappingTransformationInfo(
className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode
)
)
}
}
}
else if (cur.opcode == Opcodes.GETSTATIC) {
val fieldInsnNode = cur as FieldInsnNode?
val className = fieldInsnNode!!.owner
if (isAnonymousSingletonLoad(className, fieldInsnNode.name)) {
transformations.add(
AnonymousObjectTransformationInfo(
className, awaitClassReification, isAlreadyRegenerated(className), true,
inliningContext.nameGenerator
)
)
awaitClassReification = false
}
else if (isWhenMappingAccess(className, fieldInsnNode.name)) {
transformations.add(
WhenMappingTransformationInfo(
className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode
)
)
}
}
else if (cur.opcode == Opcodes.POP) {
getLambdaIfExistsAndMarkInstructions(frame.top()!!, true, instructions, sources, toDelete)?.let {
cur.opcode == Opcodes.POP -> getLambdaIfExistsAndMarkInstructions(frame.top()!!, true, instructions, sources, toDelete)?.let {
toDelete.add(cur)
}
cur.opcode == Opcodes.PUTFIELD -> {
//Recognize next contract's pattern in inline lambda
// ALOAD 0
// SOME_VALUE
// PUTFIELD $capturedField
// and transform it to
// SOME_VALUE
// PUTSTATIC $$$$capturedField
val fieldInsn = cur as FieldInsnNode
if (isCapturedFieldName(fieldInsn.name) &&
nodeRemapper is InlinedLambdaRemapper &&
nodeRemapper.originalLambdaInternalName == fieldInsn.owner) {
val stackTransformations = mutableSetOf<AbstractInsnNode>()
val lambdaInfo = getLambdaIfExistsAndMarkInstructions(frame.peek(1)!!, false, instructions, sources, stackTransformations)
if (lambdaInfo != null && stackTransformations.all { it is VarInsnNode }) {
assert(lambdaInfo.lambdaClassType.internalName == nodeRemapper.originalLambdaInternalName) {
"Wrong bytecode template for contract template: ${lambdaInfo.lambdaClassType.internalName} != ${nodeRemapper.originalLambdaInternalName}"
}
fieldInsn.name = FieldRemapper.foldName(fieldInsn.name)
fieldInsn.opcode = Opcodes.PUTSTATIC
toDelete.addAll(stackTransformations)
}
}
}
}
}
else {
@@ -606,6 +657,33 @@ class MethodInliner(
return
}
if (inliningContext.isInliningLambda && inliningContext.lambdaInfo is IrExpressionLambda) {
val capturedVars = inliningContext.lambdaInfo!!.capturedVars
var offset = parameters.realParametersSizeOnStack
val map = capturedVars.map {
offset to it.also { offset += it.type.size }
}.toMap()
var cur: AbstractInsnNode? = node.instructions.first
while (cur != null) {
if (cur is VarInsnNode && cur.opcode == Opcodes.ALOAD && map.contains(cur.`var`)) {
val varIndex = cur.`var`
val capturedParamDesc = map[varIndex]!!
val newIns = FieldInsnNode(
Opcodes.GETSTATIC,
capturedParamDesc.containingLambdaName,
foldName(capturedParamDesc.fieldName),
capturedParamDesc.type.descriptor
)
node.instructions.insertBefore(cur, newIns)
node.instructions.remove(cur)
cur = newIns
}
cur = cur.next
}
}
// Fold all captured variables access chains
// ALOAD 0
// [ALOAD this$0]*

View File

@@ -124,8 +124,10 @@ class ParametersBuilder private constructor() {
objectType: Type, descriptor: String, inlineLambda: LambdaInfo? = null
): ParametersBuilder {
val builder = newBuilder()
//skipped this for inlined lambda cause it will be removed
builder.addThis(objectType, inlineLambda != null).lambda = inlineLambda
if (inlineLambda?.hasDispatchReceiver != false) {
//skipped this for inlined lambda cause it will be removed
builder.addThis(objectType, inlineLambda != null).lambda = inlineLambda
}
for (type in Type.getArgumentTypes(descriptor)) {
builder.addNextParameter(type, false)

View File

@@ -261,7 +261,7 @@ val MethodInsnNode.reificationArgument: ReificationArgument?
return ReificationArgument(parameterName, nullable, arrayDepth)
}
private val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get() =
val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get() =
previous?.previous?.intConstant?.let {
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor
class SamWrapperTransformationInfo(override val oldClassName: String, private val inliningContext: InliningContext, private val alreadyRegenerated: Boolean): TransformationInfo {
override val nameGenerator: NameGenerator
get() = object: NameGenerator("stub") {
override fun getGeneratorClass(): String {
error ("Shouldn't be called on $oldClassName transformation")
}
override fun subGenerator(inliningMethod: String?): NameGenerator {
error ("Shouldn't be called on $oldClassName transformation")
}
override fun subGenerator(lambdaNoWhen: Boolean, nameSuffix: String?): NameGenerator {
error ("Shouldn't be called on $oldClassName transformation")
}
}
//TODO consider to use package class instead of inliningContext.root.callSiteInfo.ownerClassName
override val newClassName: String
get() = inliningContext.root.callSiteInfo.ownerClassName + "\$inlined" + "\$sam$".run { this + oldClassName.substringAfter(this) }
override fun shouldRegenerate(sameModule: Boolean) = !sameModule && !alreadyRegenerated
override fun canRemoveAfterTransformation() = false
override fun createTransformer(inliningContext: InliningContext, sameModule: Boolean) =
SamWrapperTransformer(this, inliningContext)
}
class SamWrapperTransformer(transformationInfo: SamWrapperTransformationInfo, private val inliningContext: InliningContext) :
ObjectTransformer<SamWrapperTransformationInfo>(transformationInfo, inliningContext.state) {
override fun doTransform(parentRemapper: FieldRemapper): InlineResult {
val classReader = createClassReader()
val classBuilder = createRemappingClassBuilderViaFactory(inliningContext)
classReader.accept(object : ClassVisitor(API, classBuilder.visitor) {
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
}
}, ClassReader.SKIP_FRAMES)
classBuilder.done()
return transformationResult
}
}

View File

@@ -136,6 +136,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
override fun generateLambdaBody(adapter: MethodVisitor,
jvmMethodSignature: JvmMethodSignature,
lambdaInfo: ExpressionLambda): SMAP {
lambdaInfo as? PsiExpressionLambda ?: error("TODO")
val invokeMethodDescriptor = lambdaInfo.invokeMethodDescriptor
val closureContext =
if (lambdaInfo.isPropertyReference)
@@ -157,7 +158,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
context: MethodContext,
expression: KtExpression,
jvmMethodSignature: JvmMethodSignature,
lambdaInfo: ExpressionLambda?
lambdaInfo: PsiExpressionLambda?
): SMAP {
val isLambda = lambdaInfo != null

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen.inline
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.backend.common.descriptors.substitute
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.BaseExpressionCodegen
@@ -28,6 +29,7 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil
import org.jetbrains.kotlin.codegen.context.InlineLambdaContext
import org.jetbrains.kotlin.codegen.context.MethodContext
import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspendFunction
import org.jetbrains.kotlin.codegen.intrinsics.classId
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
import org.jetbrains.kotlin.codegen.state.GenerationState
@@ -43,14 +45,16 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.ENUM_TYPE
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_CLASS_TYPE
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.*
@@ -87,6 +91,7 @@ private const val INLINE_MARKER_FINALLY_START = "finallyStart"
private const val INLINE_MARKER_FINALLY_END = "finallyEnd"
private const val INLINE_MARKER_BEFORE_SUSPEND_ID = 0
private const val INLINE_MARKER_AFTER_SUSPEND_ID = 1
private const val INLINE_MARKET_RETURNS_UNIT = 2
private val INTRINSIC_ARRAY_CONSTRUCTOR_TYPE = AsmUtil.asmTypeByClassId(classId)
internal fun getMethodNode(
@@ -205,56 +210,34 @@ private fun getInlineName(
internal fun isInvokeOnLambda(owner: String, name: String): Boolean {
return OperatorNameConventions.INVOKE.asString() == name &&
owner.startsWith(NUMBERED_FUNCTION_PREFIX) &&
isInteger(owner.substring(NUMBERED_FUNCTION_PREFIX.length))
owner.substring(NUMBERED_FUNCTION_PREFIX.length).isInteger()
}
internal fun isAnonymousConstructorCall(internalName: String, methodName: String): Boolean {
return "<init>" == methodName && isAnonymousClass(internalName)
}
internal fun isAnonymousConstructorCall(internalName: String, methodName: String): Boolean =
isConstructor(methodName) && isAnonymousClass(internalName)
internal fun isWhenMappingAccess(internalName: String, fieldName: String): Boolean {
return fieldName.startsWith(WhenByEnumsMapping.MAPPING_ARRAY_FIELD_PREFIX) && internalName.endsWith(WhenByEnumsMapping.MAPPINGS_CLASS_NAME_POSTFIX)
}
private fun isConstructor(methodName: String) = "<init>" == methodName
internal fun isAnonymousSingletonLoad(internalName: String, fieldName: String): Boolean {
return JvmAbi.INSTANCE_FIELD == fieldName && isAnonymousClass(internalName)
}
internal fun isWhenMappingAccess(internalName: String, fieldName: String): Boolean =
fieldName.startsWith(WhenByEnumsMapping.MAPPING_ARRAY_FIELD_PREFIX) && internalName.endsWith(WhenByEnumsMapping.MAPPINGS_CLASS_NAME_POSTFIX)
internal fun isAnonymousClass(internalName: String): Boolean {
val shortName = getLastNamePart(internalName)
val index = shortName.lastIndexOf("$")
internal fun isAnonymousSingletonLoad(internalName: String, fieldName: String): Boolean =
JvmAbi.INSTANCE_FIELD == fieldName && isAnonymousClass(internalName)
if (index < 0) {
return false
}
internal fun isSamWrapper(internalName: String) =
internalName.contains("\$sam$") && internalName.substringAfter("\$i$", "").run { length == 8 && toLongOrNull(16) != null }
val suffix = shortName.substring(index + 1)
return isInteger(suffix)
}
internal fun isSamWrapperConstructorCall(internalName: String, methodName: String) =
isConstructor(methodName) && isSamWrapper(internalName)
private fun getLastNamePart(internalName: String): String {
val index = internalName.lastIndexOf("/")
return if (index < 0) internalName else internalName.substring(index + 1)
}
internal fun isAnonymousClass(internalName: String) =
!isSamWrapper(internalName) &&
internalName.substringAfterLast('/').substringAfterLast("$", "").isInteger()
fun wrapWithMaxLocalCalc(methodNode: MethodNode): MethodVisitor {
return MaxStackFrameSizeAndLocalsCalculator(API, methodNode.access, methodNode.desc, methodNode)
}
fun wrapWithMaxLocalCalc(methodNode: MethodNode) =
MaxStackFrameSizeAndLocalsCalculator(API, methodNode.access, methodNode.desc, methodNode)
private fun isInteger(string: String): Boolean {
string.toIntOrNull() != null
if (string.isEmpty()) {
return false
}
for (i in 0..string.length - 1) {
if (!Character.isDigit(string[i])) {
return false
}
}
return true
}
private fun String.isInteger(radix: Int = 10) = toIntOrNull(radix) != null
internal fun isCapturedFieldName(fieldName: String): Boolean {
// TODO: improve this heuristic
@@ -263,14 +246,10 @@ internal fun isCapturedFieldName(fieldName: String): Boolean {
RECEIVER_0 == fieldName
}
internal fun isReturnOpcode(opcode: Int): Boolean {
return opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN
}
internal fun isReturnOpcode(opcode: Int) = opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN
//marked return could be either non-local or local in case of labeled lambda self-returns
internal fun isMarkedReturn(returnIns: AbstractInsnNode): Boolean {
return getMarkedReturnLabelOrNull(returnIns) != null
}
internal fun isMarkedReturn(returnIns: AbstractInsnNode) = getMarkedReturnLabelOrNull(returnIns) != null
internal fun getMarkedReturnLabelOrNull(returnInsn: AbstractInsnNode): String? {
if (!isReturnOpcode(returnInsn.opcode)) {
@@ -308,9 +287,7 @@ internal fun insertNodeBefore(from: MethodNode, to: MethodNode, beforeNode: Abst
}
}
internal fun createEmptyMethodNode(): MethodNode {
return MethodNode(API, 0, "fake", "()V", null, null)
}
internal fun createEmptyMethodNode() = MethodNode(API, 0, "fake", "()V", null, null)
internal fun firstLabelInChain(node: LabelNode): LabelNode {
var curNode = node
@@ -345,9 +322,7 @@ internal val AbstractInsnNode?.insnText: String
}
internal val AbstractInsnNode?.insnOpcodeText: String
get() {
return if (this == null) "null" else Printer.OPCODES[opcode]
}
get() = if (this == null) "null" else Printer.OPCODES[opcode]
internal fun buildClassReaderByInternalName(state: GenerationState, internalName: String): ClassReader {
//try to find just compiled classes then in dependencies
@@ -367,26 +342,18 @@ internal fun generateFinallyMarker(v: InstructionAdapter, depth: Int, start: Boo
v.invokestatic(INLINE_MARKER_CLASS_NAME, if (start) INLINE_MARKER_FINALLY_START else INLINE_MARKER_FINALLY_END, "(I)V", false)
}
internal fun isFinallyEnd(node: AbstractInsnNode): Boolean {
return isFinallyMarker(node, INLINE_MARKER_FINALLY_END)
}
internal fun isFinallyEnd(node: AbstractInsnNode) = isFinallyMarker(node, INLINE_MARKER_FINALLY_END)
internal fun isFinallyStart(node: AbstractInsnNode): Boolean {
return isFinallyMarker(node, INLINE_MARKER_FINALLY_START)
}
internal fun isFinallyStart(node: AbstractInsnNode) = isFinallyMarker(node, INLINE_MARKER_FINALLY_START)
internal fun isFinallyMarker(node: AbstractInsnNode?): Boolean {
return node != null && (isFinallyStart(node) || isFinallyEnd(node))
}
internal fun isFinallyMarker(node: AbstractInsnNode?): Boolean = node != null && (isFinallyStart(node) || isFinallyEnd(node))
private fun isFinallyMarker(node: AbstractInsnNode, name: String): Boolean {
if (node !is MethodInsnNode) return false
return INLINE_MARKER_CLASS_NAME == node.owner && name == node.name
}
internal fun isFinallyMarkerRequired(context: MethodContext): Boolean {
return context.isInlineMethodContext || context is InlineLambdaContext
}
internal fun isFinallyMarkerRequired(context: MethodContext) = context.isInlineMethodContext || context is InlineLambdaContext
internal fun getConstant(ins: AbstractInsnNode): Int {
val opcode = ins.opcode
@@ -424,6 +391,26 @@ internal fun addInlineMarker(v: InstructionAdapter, isStartNotEnd: Boolean) {
)
}
internal fun addReturnsUnitMarkerIfNecessary(v: InstructionAdapter, resolvedCall: ResolvedCall<*>) {
val wrapperDescriptor = resolvedCall.candidateDescriptor.safeAs<FunctionDescriptor>() ?: return
val unsubstitutedDescriptor = wrapperDescriptor.unwrapInitialDescriptorForSuspendFunction()
val typeSubstitutor = TypeSubstitutor.create(
unsubstitutedDescriptor.typeParameters
.withIndex()
.associateBy({ it.value.typeConstructor }) {
TypeProjectionImpl(resolvedCall.typeArguments[wrapperDescriptor.typeParameters[it.index]] ?: return)
}
)
val substitutedDescriptor = unsubstitutedDescriptor.substitute(typeSubstitutor) ?: return
val returnType = substitutedDescriptor.returnType ?: return
if (KotlinBuiltIns.isUnit(returnType)) {
addReturnsUnitMarker(v)
}
}
internal fun addSuspendMarker(v: InstructionAdapter, isStartNotEnd: Boolean) {
v.iconst(if (isStartNotEnd) INLINE_MARKER_BEFORE_SUSPEND_ID else INLINE_MARKER_AFTER_SUSPEND_ID)
v.visitMethodInsn(
@@ -433,8 +420,18 @@ internal fun addSuspendMarker(v: InstructionAdapter, isStartNotEnd: Boolean) {
)
}
private fun addReturnsUnitMarker(v: InstructionAdapter) {
v.iconst(INLINE_MARKET_RETURNS_UNIT)
v.visitMethodInsn(
Opcodes.INVOKESTATIC, INLINE_MARKER_CLASS_NAME,
"mark",
"(I)V", false
)
}
internal fun isBeforeSuspendMarker(insn: AbstractInsnNode) = isSuspendMarker(insn, INLINE_MARKER_BEFORE_SUSPEND_ID)
internal fun isAfterSuspendMarker(insn: AbstractInsnNode) = isSuspendMarker(insn, INLINE_MARKER_AFTER_SUSPEND_ID)
internal fun isReturnsUnitMarker(insn: AbstractInsnNode) = isSuspendMarker(insn, INLINE_MARKET_RETURNS_UNIT)
private fun isSuspendMarker(insn: AbstractInsnNode, id: Int) =
isInlineMarker(insn, "mark") && insn.previous.intConstant == id
@@ -491,9 +488,7 @@ fun isFakeLocalVariableForInline(name: String): Boolean {
return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) || name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT)
}
internal fun isThis0(name: String): Boolean {
return THIS_0 == name
}
internal fun isThis0(name: String): Boolean = THIS_0 == name
internal fun isSpecialEnumMethod(functionDescriptor: FunctionDescriptor): Boolean {
val containingDeclaration = functionDescriptor.containingDeclaration as? PackageFragmentDescriptor ?: return false

View File

@@ -46,10 +46,10 @@ class ApiVersionCallsPreprocessingMethodTransformer(private val targetApiVersion
val atLeastVersion = MavenComparableVersion("$epic.$major.$minor")
val replacementInsn =
if (targetApiVersion.version >= atLeastVersion)
InsnNode(Opcodes.ICONST_1)
else
InsnNode(Opcodes.ICONST_0)
if (targetApiVersion.version >= atLeastVersion)
InsnNode(Opcodes.ICONST_1)
else
InsnNode(Opcodes.ICONST_0)
methodNode.instructions.run {
remove(prev1)
@@ -65,29 +65,29 @@ class ApiVersionCallsPreprocessingMethodTransformer(private val targetApiVersion
}
private fun AbstractInsnNode.isApiVersionIsAtLeastCall(): Boolean =
isMethodInsnWith(Opcodes.INVOKESTATIC) {
owner.startsWith("kotlin/internal") &&
name == "apiVersionIsAtLeast" &&
desc == "(III)Z"
}
isMethodInsnWith(Opcodes.INVOKESTATIC) {
owner.startsWith("kotlin/internal") &&
name == "apiVersionIsAtLeast" &&
desc == "(III)Z"
}
private fun AbstractInsnNode.getIntConstValue(): Int? =
when (this) {
is InsnNode ->
if (opcode in Opcodes.ICONST_M1..Opcodes.ICONST_5)
opcode - Opcodes.ICONST_0
else
null
when (this) {
is InsnNode ->
if (opcode in Opcodes.ICONST_M1..Opcodes.ICONST_5)
opcode - Opcodes.ICONST_0
else
null
is IntInsnNode ->
when (opcode) {
Opcodes.BIPUSH -> operand
Opcodes.SIPUSH -> operand
else -> null
}
is IntInsnNode ->
when (opcode) {
Opcodes.BIPUSH -> operand
Opcodes.SIPUSH -> operand
else -> null
}
is LdcInsnNode -> cst as? Int
is LdcInsnNode -> cst as? Int
else -> null
}
else -> null
}
}

View File

@@ -17,13 +17,7 @@
package org.jetbrains.kotlin.codegen.optimization
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.codegen.optimization.common.ProperTrackedReferenceValue
import org.jetbrains.kotlin.codegen.optimization.common.ReferenceTrackingInterpreter
import org.jetbrains.kotlin.codegen.optimization.common.ReferenceValueDescriptor
import org.jetbrains.kotlin.codegen.optimization.common.TrackedReferenceValue
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.removeEmptyCatchBlocks
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
import org.jetbrains.kotlin.codegen.optimization.common.*
import org.jetbrains.kotlin.codegen.optimization.fixStack.peek
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
@@ -71,10 +65,10 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
var cleanVarInstruction: VarInsnNode? = null
fun canRewrite(): Boolean =
!hazard &&
initCallInsn != null &&
localVar != null &&
localVarIndex >= 0
!hazard &&
initCallInsn != null &&
localVar != null &&
localVarIndex >= 0
override fun onUseAsTainted() {
hazard = true
@@ -118,10 +112,10 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
private inner class Interpreter : ReferenceTrackingInterpreter() {
override fun newOperation(insn: AbstractInsnNode): BasicValue =
refValuesByNewInsn[insn]?.let { descriptor ->
ProperTrackedReferenceValue(descriptor.refType, descriptor)
}
?: super.newOperation(insn)
refValuesByNewInsn[insn]?.let { descriptor ->
ProperTrackedReferenceValue(descriptor.refType, descriptor)
}
?: super.newOperation(insn)
override fun processRefValueUsage(value: TrackedReferenceValue, insn: AbstractInsnNode, position: Int) {
for (descriptor in value.descriptors) {
@@ -179,7 +173,7 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
}
private fun BasicValue.getCapturedVarOrNull() =
safeAs<ProperTrackedReferenceValue>()?.descriptor?.safeAs<CapturedVarDescriptor>()
safeAs<ProperTrackedReferenceValue>()?.descriptor?.safeAs<CapturedVarDescriptor>()
private fun assignLocalVars() {
for (localVar in methodNode.localVariables) {
@@ -195,8 +189,7 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
if (descriptor.localVar == null) {
descriptor.localVar = localVar
}
else {
} else {
descriptor.hazard = true
}
}
@@ -210,8 +203,7 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
refValue.localVarIndex = methodNode.maxLocals
methodNode.maxLocals += 2
localVar.index = refValue.localVarIndex
}
else {
} else {
refValue.localVarIndex = localVar.index
}
@@ -223,7 +215,7 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
}
val cleanInstructions = findCleanInstructions(refValue, oldVarIndex, methodNode.instructions)
if (cleanInstructions.size > 1 ) {
if (cleanInstructions.size > 1) {
refValue.hazard = true
continue
}
@@ -235,12 +227,14 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
return InsnSequence(instructions).filterIsInstance<VarInsnNode>().filter {
it.opcode == Opcodes.ASTORE && it.`var` == oldVarIndex
}.filter {
it.previous?.opcode == Opcodes.ACONST_NULL
}.filter {
val operationIndex = instructions.indexOf(it)
val localVariableNode = refValue.localVar!!
instructions.indexOf(localVariableNode.start) < operationIndex && operationIndex < instructions.indexOf(localVariableNode.end)
}.toList()
it.previous?.opcode == Opcodes.ACONST_NULL
}.filter {
val operationIndex = instructions.indexOf(it)
val localVariableNode = refValue.localVar!!
instructions.indexOf(localVariableNode.start) < operationIndex && operationIndex < instructions.indexOf(
localVariableNode.end
)
}.toList()
}
private fun rewrite() {

View File

@@ -48,20 +48,20 @@ class ConstantConditionEliminationMethodTransformer : MethodTransformer() {
}
private fun collectRewriteActions(): List<() -> Unit> =
arrayListOf<() -> Unit>().also { actions ->
val frames = analyze(internalClassName, methodNode, ConstantPropagationInterpreter())
val insns = methodNode.instructions.toArray()
for (i in frames.indices) {
val frame = frames[i] ?: continue
val insn = insns[i] as? JumpInsnNode ?: continue
when (insn.opcode) {
in Opcodes.IFEQ .. Opcodes.IFLE ->
tryRewriteComparisonWithZero(insn, frame, actions)
in Opcodes.IF_ICMPEQ .. Opcodes.IF_ICMPLE ->
tryRewriteBinaryComparison(insn, frame, actions)
}
arrayListOf<() -> Unit>().also { actions ->
val frames = analyze(internalClassName, methodNode, ConstantPropagationInterpreter())
val insns = methodNode.instructions.toArray()
for (i in frames.indices) {
val frame = frames[i] ?: continue
val insn = insns[i] as? JumpInsnNode ?: continue
when (insn.opcode) {
in Opcodes.IFEQ..Opcodes.IFLE ->
tryRewriteComparisonWithZero(insn, frame, actions)
in Opcodes.IF_ICMPEQ..Opcodes.IF_ICMPLE ->
tryRewriteBinaryComparison(insn, frame, actions)
}
}
}
private fun tryRewriteComparisonWithZero(insn: JumpInsnNode, frame: Frame<BasicValue>, actions: ArrayList<() -> Unit>) {
val top = frame.top()!!.safeAs<IConstValue>() ?: return
@@ -93,8 +93,7 @@ class ConstantConditionEliminationMethodTransformer : MethodTransformer() {
if (arg1 is IConstValue && arg2 is IConstValue) {
rewriteBinaryComparisonOfConsts(insn, arg1.value, arg2.value, actions)
}
else if (arg2 is IConstValue && arg2.value == 0) {
} else if (arg2 is IConstValue && arg2.value == 0) {
rewriteBinaryComparisonWith0(insn, actions)
}
}
@@ -144,8 +143,8 @@ class ConstantConditionEliminationMethodTransformer : MethodTransformer() {
private class IConstValue private constructor(val value: Int) : StrictBasicValue(Type.INT_TYPE) {
override fun equals(other: Any?): Boolean =
other === this ||
other is IConstValue && other.value == this.value
other === this ||
other is IConstValue && other.value == this.value
override fun hashCode(): Int = value
@@ -155,34 +154,34 @@ class ConstantConditionEliminationMethodTransformer : MethodTransformer() {
private val ICONST_CACHE = Array(7) { IConstValue(it - 1) }
fun of(value: Int) =
if (value in -1 .. 5)
ICONST_CACHE[value + 1]
else
IConstValue(value)
if (value in -1..5)
ICONST_CACHE[value + 1]
else
IConstValue(value)
}
}
private class ConstantPropagationInterpreter : OptimizationBasicInterpreter() {
override fun newOperation(insn: AbstractInsnNode): BasicValue =
when (insn.opcode) {
in Opcodes.ICONST_M1 .. Opcodes.ICONST_5 ->
IConstValue.of(insn.opcode - Opcodes.ICONST_0)
Opcodes.BIPUSH, Opcodes.SIPUSH ->
IConstValue.of(insn.cast<IntInsnNode>().operand)
Opcodes.LDC -> {
val operand = insn.cast<LdcInsnNode>().cst
if (operand is Int)
IConstValue.of(operand)
else
super.newOperation(insn)
}
else -> super.newOperation(insn)
when (insn.opcode) {
in Opcodes.ICONST_M1..Opcodes.ICONST_5 ->
IConstValue.of(insn.opcode - Opcodes.ICONST_0)
Opcodes.BIPUSH, Opcodes.SIPUSH ->
IConstValue.of(insn.cast<IntInsnNode>().operand)
Opcodes.LDC -> {
val operand = insn.cast<LdcInsnNode>().cst
if (operand is Int)
IConstValue.of(operand)
else
super.newOperation(insn)
}
else -> super.newOperation(insn)
}
override fun merge(v: BasicValue, w: BasicValue): BasicValue =
if (v is IConstValue && w is IConstValue && v == w)
v
else
super.merge(v, w)
if (v is IConstValue && w is IConstValue && v == w)
v
else
super.merge(v, w)
}
}

View File

@@ -55,15 +55,15 @@ class DeadCodeEliminationMethodTransformer : MethodTransformer() {
}
private fun shouldRemove(insn: AbstractInsnNode, index: Int, frames: Array<out Any?>): Boolean =
when (insn) {
is LabelNode ->
// Do not remove label nodes because they can be referred by try/catch blocks or local variables table
false
is LineNumberNode ->
isDeadLineNumber(insn, index, frames)
else ->
frames[index] == null
}
when (insn) {
is LabelNode ->
// Do not remove label nodes because they can be referred by try/catch blocks or local variables table
false
is LineNumberNode ->
isDeadLineNumber(insn, index, frames)
else ->
frames[index] == null
}
private fun isDeadLineNumber(insn: LineNumberNode, index: Int, frames: Array<out Any?>): Boolean {
// Line number node is "dead" if the corresponding line number interval

View File

@@ -18,10 +18,8 @@ package org.jetbrains.kotlin.codegen.optimization
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.transformer.CompositeMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.tree.MethodNode
class FixStackWithLabelNormalizationMethodTransformer : CompositeMethodTransformer(
LabelNormalizationMethodTransformer(),
FixStackMethodTransformer()
LabelNormalizationMethodTransformer(),
FixStackMethodTransformer()
)

View File

@@ -49,13 +49,11 @@ class LabelNormalizationMethodTransformer : MethodTransformer() {
newLabelNodes[thisNode.label] = prevNode
removedAnyLabels = true
thisNode = instructions.removeNodeGetNext(thisNode)
}
else {
} else {
newLabelNodes[thisNode.label] = thisNode
thisNode = thisNode.next
}
}
else {
} else {
thisNode = thisNode.next
}
}
@@ -83,19 +81,19 @@ class LabelNormalizationMethodTransformer : MethodTransformer() {
}
private fun rewriteLineNumberNode(oldLineNode: LineNumberNode): AbstractInsnNode? =
instructions.replaceNodeGetNext(oldLineNode, oldLineNode.rewriteLabels())
instructions.replaceNodeGetNext(oldLineNode, oldLineNode.rewriteLabels())
private fun rewriteJumpInsn(oldJumpNode: JumpInsnNode): AbstractInsnNode? =
instructions.replaceNodeGetNext(oldJumpNode, oldJumpNode.rewriteLabels())
instructions.replaceNodeGetNext(oldJumpNode, oldJumpNode.rewriteLabels())
private fun rewriteLookupSwitchInsn(oldSwitchNode: LookupSwitchInsnNode): AbstractInsnNode? =
instructions.replaceNodeGetNext(oldSwitchNode, oldSwitchNode.rewriteLabels())
instructions.replaceNodeGetNext(oldSwitchNode, oldSwitchNode.rewriteLabels())
private fun rewriteTableSwitchInsn(oldSwitchNode: TableSwitchInsnNode): AbstractInsnNode? =
instructions.replaceNodeGetNext(oldSwitchNode, oldSwitchNode.rewriteLabels())
instructions.replaceNodeGetNext(oldSwitchNode, oldSwitchNode.rewriteLabels())
private fun rewriteFrameNode(oldFrameNode: FrameNode): AbstractInsnNode? =
instructions.replaceNodeGetNext(oldFrameNode, oldFrameNode.rewriteLabels())
instructions.replaceNodeGetNext(oldFrameNode, oldFrameNode.rewriteLabels())
private fun rewriteTryCatchBlocks() {
methodNode.tryCatchBlocks = methodNode.tryCatchBlocks.map { oldTcb ->
@@ -109,21 +107,21 @@ class LabelNormalizationMethodTransformer : MethodTransformer() {
private fun rewriteLocalVars() {
methodNode.localVariables = methodNode.localVariables.map { oldVar ->
LocalVariableNode(
oldVar.name,
oldVar.desc,
oldVar.signature,
getNew(oldVar.start),
getNew(oldVar.end),
oldVar.index
oldVar.name,
oldVar.desc,
oldVar.signature,
getNew(oldVar.start),
getNew(oldVar.end),
oldVar.index
)
}
}
private fun LineNumberNode.rewriteLabels(): AbstractInsnNode =
LineNumberNode(line, getNewOrOld(start))
LineNumberNode(line, getNewOrOld(start))
private fun JumpInsnNode.rewriteLabels(): AbstractInsnNode =
JumpInsnNode(opcode, getNew(label))
JumpInsnNode(opcode, getNew(label))
private fun LookupSwitchInsnNode.rewriteLabels(): AbstractInsnNode {
val switchNode = LookupSwitchInsnNode(getNew(dflt), keys.toIntArray(), emptyArray())
@@ -145,10 +143,10 @@ class LabelNormalizationMethodTransformer : MethodTransformer() {
}
private fun getNew(oldLabelNode: LabelNode): LabelNode =
newLabelNodes[oldLabelNode.label]!!
newLabelNodes[oldLabelNode.label]!!
private fun getNewOrOld(oldLabelNode: LabelNode): LabelNode =
newLabelNodes[oldLabelNode.label] ?: oldLabelNode
newLabelNodes[oldLabelNode.label] ?: oldLabelNode
}
}

View File

@@ -24,8 +24,7 @@ class MethodVerifier(private val checkPoint: String) : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) {
try {
analyze(internalClassName, methodNode, BasicVerifier())
}
catch (e: Throwable) {
} catch (e: Throwable) {
throw AssertionError("$checkPoint: incorrect bytecode", e)
}
}

View File

@@ -28,17 +28,17 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.tree.MethodNode
class OptimizationMethodVisitor(
delegate: MethodVisitor,
private val disableOptimization: Boolean,
private val constructorCallNormalizationMode: JVMConstructorCallNormalizationMode,
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<String>?
delegate: MethodVisitor,
private val disableOptimization: Boolean,
private val constructorCallNormalizationMode: JVMConstructorCallNormalizationMode,
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<String>?
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {
private val constructorCallNormalizationTransformer =
UninitializedStoresMethodTransformer(constructorCallNormalizationMode)
UninitializedStoresMethodTransformer(constructorCallNormalizationMode)
override fun performTransformations(methodNode: MethodNode) {
normalizationMethodTransformer.transform("fake", methodNode)
@@ -55,22 +55,22 @@ class OptimizationMethodVisitor(
private val MEMORY_LIMIT_BY_METHOD_MB = 50
val normalizationMethodTransformer = CompositeMethodTransformer(
FixStackWithLabelNormalizationMethodTransformer(),
MethodVerifier("AFTER mandatory stack transformations")
FixStackWithLabelNormalizationMethodTransformer(),
MethodVerifier("AFTER mandatory stack transformations")
)
val optimizationTransformer = CompositeMethodTransformer(
CapturedVarsOptimizationMethodTransformer(),
RedundantNullCheckMethodTransformer(),
RedundantCheckCastEliminationMethodTransformer(),
ConstantConditionEliminationMethodTransformer(),
RedundantBoxingMethodTransformer(),
StackPeepholeOptimizationsTransformer(),
PopBackwardPropagationTransformer(),
DeadCodeEliminationMethodTransformer(),
RedundantGotoMethodTransformer(),
RedundantNopsCleanupMethodTransformer(),
MethodVerifier("AFTER optimizations")
CapturedVarsOptimizationMethodTransformer(),
RedundantNullCheckMethodTransformer(),
RedundantCheckCastEliminationMethodTransformer(),
ConstantConditionEliminationMethodTransformer(),
RedundantBoxingMethodTransformer(),
StackPeepholeOptimizationsTransformer(),
PopBackwardPropagationTransformer(),
DeadCodeEliminationMethodTransformer(),
RedundantGotoMethodTransformer(),
RedundantNopsCleanupMethodTransformer(),
MethodVerifier("AFTER optimizations")
)
fun canBeOptimized(node: MethodNode): Boolean {

View File

@@ -22,7 +22,8 @@ import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode
class RedundantCheckCastEliminationMethodTransformer : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) {
@@ -57,7 +58,7 @@ class RedundantCheckCastEliminationMethodTransformer : MethodTransformer() {
}
private fun isTrivialSubtype(superType: Type, subType: Type) =
superType == subType
superType == subType
private fun isMultiArrayType(type: Type) = type.sort == Type.ARRAY && type.dimensions != 1
}

View File

@@ -16,13 +16,13 @@
package org.jetbrains.kotlin.codegen.optimization
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
class RedundantGotoMethodTransformer : MethodTransformer() {
/**
@@ -38,7 +38,7 @@ class RedundantGotoMethodTransformer : MethodTransformer() {
insn is LabelNode ->
currentLabels.add(insn)
insn.opcode == Opcodes.GOTO &&
(insn as JumpInsnNode).label in currentLabels ->
(insn as JumpInsnNode).label in currentLabels ->
insnsToRemove.add(insn)
insn.isMeaningful ->
currentLabels.clear()

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