Compare commits

..

90 Commits

Author SHA1 Message Date
Andrey Breslav
15dbfa7184 ++ android-ide-plugin module extracted 2014-10-08 18:23:51 +04:00
Andrey Breslav
b0196ac1ad ++ Logic related to command-line options moved to android-compiler-plugin 2014-10-08 18:18:29 +04:00
Andrey Breslav
0e07cb9872 ++ Expression codegen extension: receiver passed through 2014-10-07 23:58:38 +04:00
Andrey Breslav
0c6622489b ~ read actions added here and there 2014-10-01 16:43:01 +04:00
Andrey Breslav
a4bbf9b3ec Artifact for Android extensions plugin 2014-10-01 16:43:00 +04:00
Andrey Breslav
bb0141b85f Missing public added 2014-10-01 16:43:00 +04:00
Andrey Breslav
abc17943d7 Find Usages extension extracted 2014-10-01 16:42:59 +04:00
Andrey Breslav
5f209d4351 ExpressionCodegenExtension extracted 2014-10-01 16:42:59 +04:00
Andrey Breslav
a1989dc5e0 ExternalDeclarationsProvider introduced 2014-10-01 16:42:58 +04:00
Andrey Breslav
da32f47d2a android-ide-plugin module extracted 2014-10-01 16:42:58 +04:00
Andrey Breslav
78b3613cf5 Logic related to command-line options moved to android-compiler-plugin 2014-10-01 16:42:56 +04:00
Andrey Breslav
eae40ab965 Compiler plugins can provide extra command line parameters in JPS 2014-10-01 16:42:56 +04:00
Andrey Breslav
18ff58e4e7 CommandLineProcessor infrastructure added 2014-10-01 16:42:55 +04:00
Andrey Breslav
2d6ec5bd5d frontend.android renamed to android-compiler-plugin 2014-10-01 16:42:55 +04:00
Andrey Breslav
50ec0d7f8d Plugin component registrar introduced
CompilerConfiguration moved to plugin-api
2014-09-30 21:52:52 +04:00
Andrey Breslav
01b22a1dd1 plugin-api module introduced 2014-09-30 21:52:52 +04:00
Mikhail Mutcianko
73c2db8f44 fix android jps build test case
- add proper way of setting up android sdk for jps
- add missing android plugin runtime library
2014-09-30 21:52:51 +04:00
Mikhail Mutcianko
84690dd9ee add android bytecode persistence test 2014-09-30 21:52:51 +04:00
Mikhail Mutcianko
7402cf8356 add android find usages test 2014-09-30 21:52:50 +04:00
Mikhail Mutcianko
5a3186a7f8 fix find usage handler not returning android property as secondary element 2014-09-30 21:52:50 +04:00
Mikhail Mutcianko
9e75390895 add reverse renaming to android rename tests 2014-09-30 21:52:49 +04:00
Mikhail Mutcianko
0c180275f1 add android rename tests 2014-09-30 21:52:49 +04:00
Mikhail Mutcianko
06d173ca44 eliminate idToXml cache leftovers from android resource manger 2014-09-30 21:52:48 +04:00
Mikhail Mutcianko
f8dcbd8477 fix kotlin property renamer npe
- fix npe when element usage has no reference(e.g. xml cross usage)
2014-09-30 21:52:48 +04:00
Mikhail Mutcianko
cc6a9d5183 factor base android test case
- move common initialization code to base class
2014-09-30 21:52:47 +04:00
Mikhail Mutcianko
67a3932615 add all goto tests
- fix base test case failing when no res directory present
- get rid of JetProperty -> XmlAttr caching
2014-09-30 21:52:47 +04:00
Mikhail Mutcianko
b934402b55 fix android kotlin test framework
- fix android jars not indexed by java indexer
- fix goto test
2014-09-30 21:52:46 +04:00
Mikhail Mutcianko
1e25af94c0 add android jps builder test stub
wtf
2014-09-30 21:52:46 +04:00
Mikhail Mutcianko
ab7177e251 add android goto declaration test stub 2014-09-30 21:52:45 +04:00
Mikhail Mutcianko
52e0bf88f7 regenerate android tests after rebase 2014-09-30 21:52:45 +04:00
Mikhail Mutcianko
bbd4cb93ed fix android resource path arguments after rebase 2014-09-30 21:52:44 +04:00
Mikhail Mutcianko
4866168a21 fix android cross parser tests
- reorganize tests folder structure
- fix class attribute ignored in ide xml parser
2014-09-30 21:52:44 +04:00
Mikhail Mutcianko
fd125e07b6 refactor android kotlin fixture test
- move more setup code to base class
2014-09-30 21:52:43 +04:00
Mikhail Mutcianko
74b1017fcf delete obsolete android test 2014-09-30 21:52:42 +04:00
Mikhail Mutcianko
c3a668c8ca fix R class field resolving
- resolve by class name and package defined in AndroidManifest.xml
2014-09-30 21:52:42 +04:00
Mikhail Mutcianko
f20731548d add android completion tests
- add android plugin test classes as test library
- add base android test cases for kotlin, setting up android facet and sdk
2014-09-30 21:52:41 +04:00
Mikhail Mutcianko
b9b3575eb4 add android properties box tests 2014-09-30 21:52:41 +04:00
dedoz
28b8c8b5d6 add generated tests 2014-09-30 21:52:40 +04:00
Mikhail Mutcianko
8eba35cd76 optimize imports
tmp

stmp
2014-09-30 21:52:40 +04:00
Mikhail Mutcianko
530d6caa47 minor refactorings 2014-09-30 21:52:39 +04:00
Mikhail Mutcianko
6211485143 update android synthetic properties completion test
- add missing android classes as text into fixture
2014-09-30 21:52:39 +04:00
Mikhail Mutcianko
82cfb218e0 fix android plugin libs dependencies 2014-09-30 21:52:38 +04:00
Mikhail Mutcianko
9deea1caad fix cli argument tests 2014-09-30 21:52:38 +04:00
Mikhail Mutcianko
ca701f40e9 fix android plugin dependencies not unpacked 2014-09-30 21:52:37 +04:00
dedoz
e92f26123f add kotlin gradle plugin integration 2014-09-30 21:52:37 +04:00
dedoz
785a2d4200 add android xml to properties completion test 2014-09-30 21:52:36 +04:00
Mikhail Mutcianko
6554258166 add configuration key to pass android manifest file 2014-09-30 21:52:36 +04:00
Mikhail Mutcianko
7a06c8176e add android layout file searching to kotlin jps plugin 2014-09-30 21:52:35 +04:00
Mikhail Mutcianko
f582159d72 delegate android resource and manifest reading in ide to android support plugin 2014-09-30 21:52:35 +04:00
Mikhail Mutcianko
a84b3e82e6 correct interpretation of android id usage mixed with id declarations 2014-09-30 21:52:34 +04:00
Mikhail Mutcianko
7834423136 implement find usages action for android synthetic properties 2014-09-30 21:52:34 +04:00
Mikhail Mutcianko
aef7523b79 add android xml reference and rename handling to JetSimpleNameReference 2014-09-30 21:52:33 +04:00
Mikhail Mutcianko
b516cdffa8 android goto declaration handler reference fix
- goto handler now utilizes full featured reference resolving instead of simple name based resolving
2014-09-30 21:52:33 +04:00
Mikhail Mutcianko
7857302c47 fix excess xml parsing when renaming resources
- rebuild resource name -> xml attribute mappings same time as rebuilding synthetic properties
- update mappings during rename
2014-09-30 21:52:32 +04:00
Mikhail Mutcianko
b6bc9a92d6 add synthetic property renaming by renaming R light class field 2014-09-30 21:52:32 +04:00
Mikhail Mutcianko
ffd3d1ffa3 add bound property renaming by renaming xml attribute value 2014-09-30 21:52:31 +04:00
Mikhail Mutcianko
a18c97e6c5 refactor AndroidResourceManager
- move more common methods from xml processor implementations to resource manager
- optimize imports, reformat code
2014-09-30 21:52:31 +04:00
Mikhail Mutcianko
89908524ab fix double renaming issue
- rebuild resource mapping cache on external layout file changes
- move duplicated code to AndroidResourceManager
2014-09-30 21:52:31 +04:00
Mikhail Mutcianko
f3875cfde6 add missing android plugin dependency 2014-09-30 21:52:30 +04:00
Mikhail Mutcianko
c5d412e496 move android rename handler out of kotlin property renamer, extract resource manager class 2014-09-30 21:52:30 +04:00
Mikhail Mutcianko
c5689f5c26 reformat code, optimize imports 2014-09-30 21:31:12 +04:00
Mikhail Mutcianko
70253a61b6 revert cli converter to stream parsing 2014-09-30 21:31:12 +04:00
Mikhail Mutcianko
6e7c27d9fd add goto declaration support for synthetic android properties 2014-09-30 21:31:11 +04:00
Mikhail Mutcianko
5a994db798 rename android synthetic id property also renames respective xml resource 2014-09-30 21:31:08 +04:00
Mikhail Mutcianko
d959d4dbd0 add android synthetic element detecting helpers 2014-09-30 21:30:17 +04:00
dedoz
7a8bbccda3 replace sax with psi based android ui xml parsing in plugin 2014-09-30 21:30:17 +04:00
Mikhail Mutcianko
795177ca80 fix xml resolving
- replace VirtualFileListener based approach with direct PsiFile reading
2014-09-30 21:30:16 +04:00
Mikhail Mutcianko
8a191bb1a2 check if android metadata is present before inlining property 2014-09-30 21:30:16 +04:00
Mikhail Mutcianko
b7308b9b7c fix compiler argument tests 2014-09-30 21:30:15 +04:00
Mikhail Mutcianko
cc31520089 insert missing copyrights, move ByteArrayClassLoader up 2014-09-30 21:30:14 +04:00
dedoz
80547cf292 add android xml bridge invocation test 2014-09-30 21:30:14 +04:00
Mikhail Mutcianko
2a0a03e011 add byte code generation 2014-09-30 21:30:13 +04:00
Mikhail Mutcianko
ffbe0a3e4e add android manifest support 2014-09-30 21:30:12 +04:00
Mikhail Mutcianko
8a7bc4fa71 fix R class not resolved in dummy file 2014-09-30 21:30:12 +04:00
Mikhail Mutcianko
a682a1d208 refactor XmlHandler, optimize imports, remove unused files 2014-09-30 21:30:11 +04:00
Mikhail Mutcianko
d955cc87dc add missing module and build dependencies 2014-09-30 21:30:04 +04:00
Mikhail Mutcianko
cb1da3b07b add writePackage to KotlinWriter 2014-09-30 21:29:08 +04:00
Mikhail Mutcianko
e2ef7efcb4 refactor converter initialization
- push lazyInit() down to IDE and Cli implementations
- no file listeners created in cli implementation anymore
- fix tests
2014-09-30 21:29:07 +04:00
Mikhail Mutcianko
ee46064f02 event based file processing
- use VirtualFileListener to wait for ui xml file updates
- optimize imports
2014-09-30 21:29:07 +04:00
Mikhail Mutcianko
770a732449 suppress xml errors in converter
- simply ignore malformed layouts, xml editor in ide will highlight them anyway
2014-09-30 21:29:06 +04:00
Mikhail Mutcianko
03732ac606 add converter output caching
- add two level caching: per xml conversion result and complete resulting JetFile,
  so that only modified xmls are actually converted, and if no change has been
  made to any of those, last successfully built psi file is returned
- merge AndroidUIXmlPathProvider and AndroidUIXmlParser
- update tests
2014-09-30 21:29:05 +04:00
Mikhail Mutcianko
9683bc385a fix ant build
- add frontend.android content to sources path
2014-09-30 21:29:05 +04:00
Mikhail Mutcianko
e35cb603f9 add compiler key for providing android resources path 2014-09-30 21:29:04 +04:00
Mikhail Mutcianko
71edc602c8 fix npe when layout xml search path does not exist 2014-09-30 21:29:04 +04:00
Mikhail Mutcianko
958ea49978 obey android project structure when searching for ui xmls
- search for android layout xmls in ProjectRoot/res/layout/ when using IDEPathProvider
2014-09-30 21:29:03 +04:00
Mikhail Mutcianko
86b2a3e5a5 missing files handling in converter
- silently continue if no files were found to convert
2014-09-30 21:29:02 +04:00
Mikhail Mutcianko
de56576d15 ide analyzer integration stub
- add android ui xml path providers/stubs
- add generated file injection during analysis
2014-09-30 21:29:02 +04:00
Mikhail Mutcianko
a5d1936393 auto cast widget to its original type
- change property return type signatures from View to actual widget type
- simplify and update tests
2014-09-30 21:29:01 +04:00
Mikhail Mutcianko
c63281f91a add converted result compilation test 2014-09-30 21:29:01 +04:00
Mikhail Mutcianko
f4c83d88eb android UI xml bridge initial
- add frontend.android module
- add xml ids to kotlin extension properties converter
- add converter basic functional test
2014-09-30 21:29:00 +04:00
6404 changed files with 61378 additions and 95861 deletions

View File

@@ -1,9 +1,9 @@
<component name="ArtifactManager">
<artifact type="jar" name="IdeLazyResolver">
<output-path>$PROJECT_DIR$/out/artifacts/internal/</output-path>
<root id="archive" name="kotlin-ide-common.jar">
<element id="module-output" name="ide-common" />
<element id="dir-copy" path="$PROJECT_DIR$/idea/ide-common" />
<output-path>$PROJECT_DIR$/out/artifacts/IdeLazyResolver</output-path>
<root id="archive" name="ide-lazy-resolver.jar">
<element id="module-output" name="ide-lazy-resolve" />
<element id="dir-copy" path="$PROJECT_DIR$/idea/ide-lazy-resolve" />
</root>
</artifact>
</component>

View File

@@ -1,6 +1,6 @@
<component name="ArtifactManager">
<artifact type="jar" name="InjectorGenerator">
<output-path>$PROJECT_DIR$/out/artifacts/internal/</output-path>
<output-path>$PROJECT_DIR$/out/artifacts/InjectorGenerator</output-path>
<root id="archive" name="injector-generator.jar">
<element id="module-output" name="injector-generator" />
<element id="dir-copy" path="$PROJECT_DIR$/injector-generator" />

View File

@@ -0,0 +1,18 @@
<component name="ArtifactManager">
<artifact name="KotlinAndroidExtensionsPlugin">
<output-path>$PROJECT_DIR$/out/artifacts/KotlinAndroidExtensionsPlugin</output-path>
<root id="root">
<element id="directory" name="lib">
<element id="archive" name="kotlin-android-extensions-plugin.jar">
<element id="module-output" name="android-compiler-plugin" />
<element id="module-output" name="android-idea-plugin" />
</element>
<element id="directory" name="jps">
<element id="archive" name="kotlin-android-extensions-jps.jar">
<element id="module-output" name="android-jps-plugin" />
</element>
</element>
</element>
</root>
</artifact>
</component>

View File

@@ -14,6 +14,7 @@
<element id="module-output" name="util" />
<element id="module-output" name="util.runtime" />
<element id="module-output" name="j2k" />
<element id="module-output" name="js.translator" />
<element id="module-output" name="js.frontend" />
<element id="module-output" name="cli-common" />
<element id="module-output" name="ide-compiler-runner" />
@@ -29,9 +30,9 @@
</element>
<element id="module-output" name="eval4j" />
<element id="module-output" name="idea-analysis" />
<element id="module-output" name="ide-common" />
<element id="file-copy" path="$PROJECT_DIR$/resources/manifest.properties" />
<element id="module-output" name="kotlin-android-plugin" />
<element id="module-output" name="ide-lazy-resolve" />
<element id="module-output" name="android-compiler-plugin" />
<element id="module-output" name="android-idea-plugin" />
</element>
<element id="library" level="project" name="javax.inject" />
<element id="directory" name="jps">

View File

@@ -2,9 +2,7 @@
<dictionary name="valentin">
<words>
<w>initializers</w>
<w>inserter</w>
<w>pparent</w>
<w>processings</w>
<w>rparenth</w>
</words>
</dictionary>

38
.idea/libraries/android.xml generated Normal file
View File

@@ -0,0 +1,38 @@
<component name="libraryTable">
<library name="android">
<ANNOTATIONS>
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/android.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/jps/android-jps-plugin.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/android-common.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/jps/android-gradle-jps.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/manifest-merger.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/builder-model-0.12.0.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/commons-compress-1.0.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/layoutlib-api.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/common.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/sdklib.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/resources_en.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/sdk-tools.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/jarutils.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/android-rt.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/gen" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/common/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/ultimate/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/guiTestSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/jps-plugin/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/android-gradle-jps/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/android-src.zip!/android-gradle-jps/testSrc" />
</SOURCES>
</library>
</component>

View File

@@ -1,19 +0,0 @@
<component name="libraryTable">
<library name="android-plugin">
<ANNOTATIONS>
<root url="file://$PROJECT_DIR$/annotations" />
</ANNOTATIONS>
<CLASSES>
<root url="file://$PROJECT_DIR$/ideaSDK/plugins/android/lib" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/android/android/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/android/android/common/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/android/android/rt/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/android/android/jps-plugin/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/android/android/ultimate/src" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/plugins/android/lib" recursive="false" />
</library>
</component>

9
.idea/libraries/android_tests.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="android_tests">
<CLASSES>
<root url="jar://$PROJECT_DIR$/dependencies/android_tests.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

11
.idea/modules.xml generated
View File

@@ -3,6 +3,9 @@
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Kotlin.iml" filepath="$PROJECT_DIR$/Kotlin.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/android-compiler-plugin/android-compiler-plugin.iml" filepath="$PROJECT_DIR$/plugins/android-compiler-plugin/android-compiler-plugin.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/android-idea-plugin/android-idea-plugin.iml" filepath="$PROJECT_DIR$/plugins/android-idea-plugin/android-idea-plugin.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/android-jps-plugin/android-jps-plugin.iml" filepath="$PROJECT_DIR$/plugins/android-jps-plugin/android-jps-plugin.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/android-studio/android-studio.iml" filepath="$PROJECT_DIR$/android-studio/android-studio.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/compiler/android-tests/android-tests.iml" filepath="$PROJECT_DIR$/compiler/android-tests/android-tests.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/compiler/backend/backend.iml" filepath="$PROJECT_DIR$/compiler/backend/backend.iml" group="compiler/java" />
@@ -22,8 +25,8 @@
<module fileurl="file://$PROJECT_DIR$/compiler/frontend.java/frontend.java.iml" filepath="$PROJECT_DIR$/compiler/frontend.java/frontend.java.iml" group="compiler/java" />
<module fileurl="file://$PROJECT_DIR$/generators/generators.iml" filepath="$PROJECT_DIR$/generators/generators.iml" group="infrastructure" />
<module fileurl="file://$PROJECT_DIR$/grammar/grammar.iml" filepath="$PROJECT_DIR$/grammar/grammar.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/idea/ide-common/ide-common.iml" filepath="$PROJECT_DIR$/idea/ide-common/ide-common.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/ide-compiler-runner/ide-compiler-runner.iml" filepath="$PROJECT_DIR$/ide-compiler-runner/ide-compiler-runner.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/idea/ide-lazy-resolve/ide-lazy-resolve.iml" filepath="$PROJECT_DIR$/idea/ide-lazy-resolve/ide-lazy-resolve.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/idea/idea-analysis/idea-analysis.iml" filepath="$PROJECT_DIR$/idea/idea-analysis/idea-analysis.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/idea_runner/idea_runner.iml" filepath="$PROJECT_DIR$/idea_runner/idea_runner.iml" group="ide" />
@@ -34,11 +37,10 @@
<module fileurl="file://$PROJECT_DIR$/jps-plugin/jps-plugin.iml" filepath="$PROJECT_DIR$/jps-plugin/jps-plugin.iml" group="ide/jps" />
<module fileurl="file://$PROJECT_DIR$/js/js.dart-ast/js.dart-ast.iml" filepath="$PROJECT_DIR$/js/js.dart-ast/js.dart-ast.iml" group="compiler/js" />
<module fileurl="file://$PROJECT_DIR$/js/js.frontend/js.frontend.iml" filepath="$PROJECT_DIR$/js/js.frontend/js.frontend.iml" group="compiler/js" />
<module fileurl="file://$PROJECT_DIR$/js/js.inliner/js.inliner.iml" filepath="$PROJECT_DIR$/js/js.inliner/js.inliner.iml" group="compiler/js" />
<module fileurl="file://$PROJECT_DIR$/js/js.tests/js.tests.iml" filepath="$PROJECT_DIR$/js/js.tests/js.tests.iml" group="compiler/js" />
<module fileurl="file://$PROJECT_DIR$/js/js.translator/js.translator.iml" filepath="$PROJECT_DIR$/js/js.translator/js.translator.iml" group="compiler/js" />
<module fileurl="file://$PROJECT_DIR$/jps-plugin/kannotator-jps-plugin-test/kannotator-jps-plugin-test.iml" filepath="$PROJECT_DIR$/jps-plugin/kannotator-jps-plugin-test/kannotator-jps-plugin-test.iml" group="ide/jps" />
<module fileurl="file://$PROJECT_DIR$/idea/kotlin-android-plugin/kotlin-android-plugin.iml" filepath="$PROJECT_DIR$/idea/kotlin-android-plugin/kotlin-android-plugin.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/compiler/plugin-api/plugin-api.iml" filepath="$PROJECT_DIR$/compiler/plugin-api/plugin-api.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/compiler/preloader/preloader.iml" filepath="$PROJECT_DIR$/compiler/preloader/preloader.iml" group="compiler/cli" />
<module fileurl="file://$PROJECT_DIR$/core/reflection/reflection.iml" filepath="$PROJECT_DIR$/core/reflection/reflection.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" filepath="$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" group="core" />
@@ -48,4 +50,5 @@
<module fileurl="file://$PROJECT_DIR$/core/util.runtime/util.runtime.iml" filepath="$PROJECT_DIR$/core/util.runtime/util.runtime.iml" group="core" />
</modules>
</component>
</project>
</project>

View File

@@ -10,13 +10,7 @@
<option name="PASS_PARENT_ENVS" value="true" />
<module name="generators" />
<envs />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="" />
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" />
<method />
</configuration>

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="IDEA" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true" />
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin:$PROJECT_DIR$/out/artifacts/KotlinAndroidExtensionsPlugin -Dkotlin.internal.mode.enabled=true" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="IDEA (No ProcessCanceledException)" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=250m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true" />
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=250m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin:$PROJECT_DIR$/out/artifacts/KotlinAndroidExtensionsPlugin -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />

View File

@@ -5,9 +5,9 @@
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" value="" />
<option name="PACKAGE_NAME" value="org.jetbrains.jet.jps.build" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="org.jetbrains.jet.jps.build.IncrementalJpsTestGenerated" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="pattern" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-ea -Xmx512m -XX:MaxPermSize=320m -Dkotlin.incremental.compilation=true" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
@@ -19,10 +19,7 @@
<envs>
<env name="kotlin.tests.actually.compile" value="false" />
</envs>
<patterns>
<pattern testClass="org.jetbrains.jet.jps.build.IncrementalJpsTestGenerated" />
<pattern testClass="org.jetbrains.jet.jps.build.IncrementalCacheVersionChangedTest" />
</patterns>
<patterns />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="" />
<option name="TRANSPORT" value="0" />

4
.idea/vcs.xml generated
View File

@@ -7,10 +7,6 @@
<option name="issueRegexp" value="[A-Z]+\-\d+" />
<option name="linkRegexp" value="http://youtrack.jetbrains.com/issue/$0" />
</IssueNavigationLink>
<IssueNavigationLink>
<option name="issueRegexp" value="EA\-(\d+)" />
<option name="linkRegexp" value="http://ea.jetbrains.com/browser/ea_problems/$1" />
</IssueNavigationLink>
</list>
</option>
</component>

View File

@@ -8,6 +8,7 @@
<excludeFolder url="file://$MODULE_DIR$/android.tests.dependencies" />
<excludeFolder url="file://$MODULE_DIR$/dependencies" />
<excludeFolder url="file://$MODULE_DIR$/dist" />
<excludeFolder url="file://$MODULE_DIR$/ideaSDK/androidSDK" />
<excludeFolder url="file://$MODULE_DIR$/ideaSDK/config" />
<excludeFolder url="file://$MODULE_DIR$/ideaSDK/config-idea" />
<excludeFolder url="file://$MODULE_DIR$/ideaSDK/system" />

View File

@@ -2,7 +2,7 @@
Welcome to [Kotlin](http://kotlinlang.org/)! Some handy links:
* [Getting Started Guide](http://kotlinlang.org/docs/tutorials/getting-started.html)
* [Getting Started Guide](http://confluence.jetbrains.net/display/Kotlin/Getting+Started)
* [Web Demo](http://kotlin-demo.jetbrains.com/)
* [Kotlin Site](http://jetbrains.github.com/kotlin/)
* [API](http://jetbrains.github.com/kotlin/versions/snapshot/apidocs/index.html)
@@ -10,7 +10,7 @@ Welcome to [Kotlin](http://kotlinlang.org/)! Some handy links:
* [Forum](http://devnet.jetbrains.net/community/kotlin?view=discussions)
* [Kotlin Blog](http://blog.jetbrains.com/kotlin/)
* [follow Kotlin on twitter](http://twitter.com/#!/project_kotlin)
* [TeamCity CI build](https://teamcity.jetbrains.com/project.html?tab=projectOverview&projectId=Kotlin)
* [TeamCity CI build](http://teamcity.jetbrains.com/project.html?projectId=project67&tab=projectOverview)
## Editing Kotlin
@@ -52,7 +52,7 @@ then choose the `tools.jar` in the JDK's `lib` directory.
If you are not dealing with Android, you may need to disable the Android Plugin in order to compile the project.
Since Kotlin project contains code written in Kotlin itself, you will also need a Kotlin plugin to build the project in IntelliJ IDEA.
To keep the plugin version in sync with the rest of the team and our [Continuous Integration server](https://teamcity.jetbrains.com/project.html?projectId=Kotlin&tab=projectOverview)
To keep the plugin version in sync with the rest of the team and our [Continuous Integration server](http://teamcity.jetbrains.com/project.html?projectId=Kotlin&tab=projectOverview)
you should install the according to the [instructions below](#plugin-for-contributors).
If you want to have an IDEA installation without the Kotlin plugin which is separate to your default IDEA installation which has the Kotlin
@@ -72,7 +72,7 @@ There are several options for getting Kotlin plugin. A stable version can be obt
Preferences -> Plugins -> Browse Repositories -> Search with "Kotlin" string
The most recent version of the plugin can be downloaded from the
[IDEA Plugin and Tests CI build](https://teamcity.jetbrains.com/project.html?projectId=project67&tab=projectOverview). When downloading is
[IDEA Plugin and Tests CI build](http://teamcity.jetbrains.com/project.html?projectId=project67&tab=projectOverview). When downloading is
finished you can install it with "Install plugin from disk...":
Preferences -> Plugins -> Install plugin from disk...
@@ -89,15 +89,15 @@ Open
and add the following URL to your repositories:
https://teamcity.jetbrains.com/guestAuth/repository/download/bt345/bootstrap.tcbuildtag/updatePlugins.xml
http://teamcity.jetbrains.com/guestAuth/repository/download/bt345/bootstrap.tcbuildtag/updatePlugins.xml
Then update the list of plugins in "Browse Repositories", you'll see two versions of Kotlin there, install the one with the higher version number.
# Contributing
We love contributions! There's [lots to do on kotlin](http://youtrack.jetbrains.com/issues/KT) and on the [standard library](https://youtrack.jetbrains.com/issues/KT?q=Subtask+of%3A+KT-2554+%23Unresolved) so why not chat with us on the [forum](http://devnet.jetbrains.net/community/kotlin?view=discussions) about what you're interested in doing?
We love contributions! There's [lots to do on kotlin](http://youtrack.jetbrains.com/issues/KT) and on the [standard library](http://youtrack.jetbrains.com/issues/KT?q=%23%7BStandard+Library%7D+-Resolved) so why not chat with us on the [forum](http://devnet.jetbrains.net/community/kotlin?view=discussions) about what you're interested in doing?
If you want to find some issues to start off with, try [this query](https://youtrack.jetbrains.com/issues?q=tag%3A+%7BUp+For+Grabs%7D+%23Unresolved) which should find all issues that marked as "up-for-grabs".
If you want to find some issues to start off with, try [this query](http://youtrack.jetbrains.com/issues?q=tag%3A+%7BUp+For+Grabs%7D) which should find all issues that marked as "up-for-grabs".
Currently only committers can assign issues to themselves so just add a comment if you're starting work on it.

View File

@@ -1,9 +0,0 @@
<root>
<item
name='com.android.tools.idea.gradle.output.parser.PatternAwareOutputParser boolean parse(java.lang.String, com.android.tools.idea.gradle.output.parser.OutputLineReader, java.util.List&lt;com.android.tools.idea.gradle.output.GradleMessage&gt;)'>
<annotation name='kotlin.jvm.KotlinSignature'>
<val name="value"
val="&quot;fun parse(line: String, reader: OutputLineReader, messages: MutableList&lt;GradleMessage&gt;): Boolean&quot;"/>
</annotation>
</item>
</root>

View File

@@ -168,20 +168,4 @@
name='com.intellij.codeInsight.editorActions.CopyPasteReferenceProcessor void restoreReferences(com.intellij.codeInsight.editorActions.ReferenceData[], TRef[]) 1'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate int tryJoinLines(com.intellij.openapi.editor.Document, com.intellij.psi.PsiFile, int, int) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate int tryJoinLines(com.intellij.openapi.editor.Document, com.intellij.psi.PsiFile, int, int) 1'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.codeInsight.editorActions.JoinRawLinesHandlerDelegate int tryJoinRawLines(com.intellij.openapi.editor.Document, com.intellij.psi.PsiFile, int, int) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.codeInsight.editorActions.JoinRawLinesHandlerDelegate int tryJoinRawLines(com.intellij.openapi.editor.Document, com.intellij.psi.PsiFile, int, int) 1'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>

View File

@@ -1,121 +1,117 @@
<root>
<item
name='com.intellij.formatting.DependentSpacingRule com.intellij.formatting.DependentSpacingRule registerData(com.intellij.formatting.DependentSpacingRule.Anchor, int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.Spacing com.intellij.formatting.Spacing createKeepingFirstColumnSpacing(int, int, boolean, int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.Spacing com.intellij.formatting.Spacing createSpacing(int, int, int, boolean, int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder append(com.intellij.formatting.SpacingBuilder)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder after(com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder afterInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder afterInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder afterInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder around(com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder around(com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder aroundInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder aroundInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder aroundInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder aroundInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder before(com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder beforeInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder beforeInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder between(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder between(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder between(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder between(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder betweenInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder betweenInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder withinPair(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder withinPairInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder blankLines(int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder lineBreakInCode()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder lineBreakInCodeIf(boolean)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder none()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder spaceIf(boolean)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder spaces(int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder spacing(int, int, int, boolean, int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.Spacing com.intellij.formatting.Spacing createKeepingFirstColumnSpacing(int, int, boolean, int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.Spacing com.intellij.formatting.Spacing createSpacing(int, int, int, boolean, int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder append(com.intellij.formatting.SpacingBuilder)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder after(com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder afterInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder afterInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder afterInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder around(com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder around(com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder aroundInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder aroundInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder aroundInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder aroundInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder before(com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder beforeInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder beforeInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder between(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder between(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder between(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder between(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.TokenSet)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder betweenInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder betweenInside(com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.TokenSet, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder withinPair(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder com.intellij.formatting.SpacingBuilder.RuleBuilder withinPairInside(com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType, com.intellij.psi.tree.IElementType)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder blankLines(int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder lineBreakInCode()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder lineBreakInCodeIf(boolean)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder none()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder spaceIf(boolean)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder spaces(int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.formatting.SpacingBuilder.RuleBuilder com.intellij.formatting.SpacingBuilder spacing(int, int, int, boolean, int)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>

View File

@@ -8,7 +8,4 @@
<item name='com.intellij.ide.util.PsiElementListCellRenderer java.lang.String getElementText(T) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.ide.util.PsiElementListCellRenderer java.util.Comparator&lt;T&gt; getComparator()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>

View File

@@ -1,6 +0,0 @@
<root>
<item
name='com.intellij.openapi.project.DumbService com.intellij.openapi.project.DumbService getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>

View File

@@ -22,11 +22,7 @@
<item name='com.intellij.openapi.roots.OrderEnumerator com.intellij.openapi.roots.OrderEnumerator recursively()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.openapi.roots.OrderEnumerator com.intellij.openapi.roots.OrderEnumerator satisfying(com.intellij.openapi.util.Condition&lt;com.intellij.openapi.roots.OrderEntry&gt;)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
<item
name='com.intellij.openapi.roots.ProjectFileIndex.SERVICE com.intellij.openapi.roots.ProjectFileIndex getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>

View File

@@ -1,5 +0,0 @@
<root>
<item name='com.intellij.openapi.util.text.StringUtil java.lang.String decapitalize(java.lang.String)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>

View File

@@ -21,8 +21,4 @@
<item name='com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler void updateMovedFile(com.intellij.psi.PsiFile) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler$1 void retargetUsages(java.util.List&lt;com.intellij.usageView.UsageInfo&gt;, java.util.Map&lt;com.intellij.psi.PsiElement,com.intellij.psi.PsiElement&gt;) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>

View File

@@ -1,8 +1,5 @@
<root>
<item name='org.apache.tools.ant.types.Path java.lang.String[] list()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='org.apache.tools.ant.types.Path org.apache.tools.ant.types.Path createPath()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>
</root>

View File

@@ -0,0 +1,151 @@
/*
* Copyright 2010-2013 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.jet.buildtools.ant;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.jetbrains.jet.buildtools.core.BytecodeCompiler;
import org.jetbrains.jet.buildtools.core.Util;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.jetbrains.jet.buildtools.core.Util.getPath;
/**
* Kotlin bytecode compiler Ant task.
* <p/>
* See
* http://evgeny-goldin.org/javadoc/ant/tutorial-writing-tasks.html
* http://evgeny-goldin.org/javadoc/ant/develop.html
* http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javac.java?view=markup.
*/
public class BytecodeCompilerTask extends Task {
private File output;
private File stdlib;
private Path src;
private Path externalAnnotations;
private Path compileClasspath;
private boolean includeRuntime = true;
private final List<Commandline.Argument> additionalArguments = new ArrayList<Commandline.Argument>();
public void setOutput(File output) {
this.output = output;
}
public void setStdlib(File stdlib) {
this.stdlib = stdlib;
}
public void setSrc(Path src) {
this.src = src;
}
public Path createSrc() {
if (src == null) {
src = new Path(getProject());
}
return src.createPath();
}
public void setExternalAnnotations(Path externalAnnotations) {
this.externalAnnotations = externalAnnotations;
}
public Path createExternalAnnotations() {
if (externalAnnotations == null) {
externalAnnotations = new Path(getProject());
}
return externalAnnotations.createPath();
}
public void setIncludeRuntime(boolean includeRuntime) {
this.includeRuntime = includeRuntime;
}
public Commandline.Argument createCompilerArg() {
Commandline.Argument argument = new Commandline.Argument();
additionalArguments.add(argument);
return argument;
}
/**
* Set the classpath to be used for this compilation.
*
* @param classpath an Ant Path object containing the compilation classpath.
*/
public void setClasspath(Path classpath) {
if (this.compileClasspath == null) {
this.compileClasspath = classpath;
}
else {
this.compileClasspath.append(classpath);
}
}
/**
* Adds a reference to a classpath defined elsewhere.
*
* @param ref a reference to a classpath.
*/
public void setClasspathRef(Reference ref) {
if (this.compileClasspath == null) {
this.compileClasspath = new Path(getProject());
}
this.compileClasspath.createPath().setRefid(ref);
}
/**
* Set the nested {@code <classpath>} to be used for this compilation.
*
* @param classpath an Ant Path object containing the compilation classpath.
*/
public void addConfiguredClasspath(Path classpath) {
setClasspath(classpath);
}
@Override
public void execute() {
String stdlibPath = stdlib != null ? getPath(stdlib) : null;
String[] classpath = compileClasspath != null ? compileClasspath.list() : null;
String[] externalAnnotationsPath = externalAnnotations != null ? externalAnnotations.list() : null;
List<String> args = new ArrayList<String>();
for (Commandline.Argument argument : additionalArguments) {
args.addAll(Arrays.asList(argument.getParts()));
}
if (src == null) {
throw new BuildException("\"src\" should be specified");
}
if (output == null) {
throw new BuildException("\"output\" should be specified");
}
String[] source = Util.getPaths(src.list());
String destination = getPath(output);
log(String.format("Compiling [%s] => [%s]", Arrays.toString(source), destination));
BytecodeCompiler.compileSources(source, destination, includeRuntime, stdlibPath, classpath, externalAnnotationsPath, args);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
* Copyright 2010-2013 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.
@@ -16,7 +16,10 @@
package org.jetbrains.jet.buildtools.ant
import org.apache.tools.ant.Task
import org.apache.tools.ant.types.Path
import org.apache.tools.ant.types.Reference
import org.jetbrains.jet.buildtools.core.Util
import org.jetbrains.jet.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.jet.cli.common.messages.MessageCollectorPlainTextToStream
import org.jetbrains.jet.cli.js.K2JSCompiler
@@ -29,10 +32,9 @@ import org.jetbrains.jet.config.Services
* Kotlin JavaScript compiler Ant task.
* http://evgeny-goldin.org/javadoc/ant/tutorial-writing-tasks.html
*/
public class Kotlin2JsTask : KotlinCompilerBaseTask<K2JSCompilerArguments>() {
override val arguments = K2JSCompilerArguments()
override val compiler = K2JSCompiler()
public class Kotlin2JsCompilerTask : Task() {
public var src: Path? = null
public var output: File? = null
public var library: Path? = null
public var outputPrefix: File? = null
public var outputPostfix: File? = null
@@ -44,6 +46,21 @@ public class Kotlin2JsTask : KotlinCompilerBaseTask<K2JSCompilerArguments>() {
*/
public var main: String? = null
public fun createSrc(): Path {
val srcPath = src
if (srcPath == null) {
val t = Path(getProject())
src = t
return t
}
return srcPath.createPath()
}
public fun setSrcRef(ref: Reference) {
createSrc().setRefid(ref)
}
public fun createLibrary(): Path {
val libraryPath = library
if (libraryPath == null) {
@@ -55,13 +72,28 @@ public class Kotlin2JsTask : KotlinCompilerBaseTask<K2JSCompilerArguments>() {
return libraryPath.createPath()
}
override fun fillSpecificArguments() {
arguments.outputFile = getPath(output!!)
override fun execute(): Unit {
val arguments = K2JSCompilerArguments()
val sourcePaths = src ?: throw BuildException("\"src\" should be specified")
arguments.freeArgs = Util.getPaths(sourcePaths.list()).toList()
val outputFile = output ?: throw BuildException("\"output\" should be specified")
arguments.outputFile = outputFile.canonicalPath
arguments.outputPrefix = outputPrefix?.canonicalPath
arguments.outputPostfix = outputPostfix?.canonicalPath
arguments.main = main
arguments.sourceMap = sourceMap
log("Compiling ${arguments.freeArgs} => [${arguments.outputFile}]");
val compiler = K2JSCompiler()
val exitCode = compiler.exec(MessageCollectorPlainTextToStream.PLAIN_TEXT_TO_SYSTEM_ERR, Services.EMPTY, arguments)
if (exitCode != ExitCode.OK) {
throw BuildException("Compilation finished with exit code $exitCode")
}
}
}

View File

@@ -1,108 +0,0 @@
/*
* Copyright 2010-2014 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.jet.buildtools.ant
import org.apache.tools.ant.types.Path
import org.apache.tools.ant.types.Reference
import java.io.File
import java.io.File.pathSeparator
import org.jetbrains.jet.cli.jvm.K2JVMCompiler
import org.jetbrains.jet.cli.common.arguments.K2JVMCompilerArguments
import com.intellij.openapi.util.io.FileUtilRt
/**
* Kotlin bytecode compiler Ant task.
* <p/>
* See
* http://evgeny-goldin.org/javadoc/ant/tutorial-writing-tasks.html
* http://evgeny-goldin.org/javadoc/ant/develop.html
* http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javac.java?view=markup.
*/
public class Kotlin2JvmTask : KotlinCompilerBaseTask<K2JVMCompilerArguments>() {
override val arguments = K2JVMCompilerArguments()
override val compiler = K2JVMCompiler()
public var noStdlib: Boolean = false
public var externalAnnotations: Path? = null
public var includeRuntime: Boolean = true
private var compileClasspath: Path? = null
public fun createExternalAnnotations(): Path {
if (externalAnnotations == null) {
externalAnnotations = Path(getProject())
}
return externalAnnotations!!.createPath()
}
/**
* Set the classpath to be used for this compilation.
*
* @param classpath an Ant Path object containing the compilation classpath.
*/
public fun setClasspath(classpath: Path) {
if (this.compileClasspath == null) {
this.compileClasspath = classpath
}
else {
this.compileClasspath!!.append(classpath)
}
}
/**
* Adds a reference to a classpath defined elsewhere.
*
* @param ref a reference to a classpath.
*/
public fun setClasspathRef(ref: Reference) {
if (this.compileClasspath == null) {
this.compileClasspath = Path(getProject())
}
this.compileClasspath!!.createPath().setRefid(ref)
}
/**
* Set the nested {@code <classpath>} to be used for this compilation.
*
* @param classpath an Ant Path object containing the compilation classpath.
*/
public fun addConfiguredClasspath(classpath: Path) {
setClasspath(classpath)
}
override fun fillSpecificArguments() {
arguments.destination = getPath(output!!)
val classpath = arrayListOf<String>()
compileClasspath?.let { classpath.addAll(it.list()) }
arguments.freeArgs?.forEach {
val file = File(it)
if (file.isDirectory() || file.extension != "kt") {
classpath.add(it)
}
}
arguments.classpath = classpath.join(pathSeparator)
arguments.annotations = externalAnnotations?.list()?.join(pathSeparator)
arguments.noStdlib = noStdlib
arguments.includeRuntime = includeRuntime
}
}

View File

@@ -40,7 +40,7 @@ public class KotlinCompilerAdapter extends DefaultCompilerAdapter {
public boolean execute() throws BuildException {
Javac javac = getJavac();
Kotlin2JvmTask kotlinTask = new Kotlin2JvmTask();
BytecodeCompilerTask kotlinTask = new BytecodeCompilerTask();
kotlinTask.setOutput(javac.getDestdir());
kotlinTask.setClasspath(javac.getClasspath());
kotlinTask.setSrc(javac.getSrcdir());

View File

@@ -1,124 +0,0 @@
/*
* Copyright 2010-2014 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.jet.buildtools.ant
import org.apache.tools.ant.Task
import org.apache.tools.ant.types.Path
import org.apache.tools.ant.types.Reference
import org.jetbrains.jet.cli.common.messages.MessageCollectorPlainTextToStream
import java.io.File
import org.apache.tools.ant.BuildException
import org.jetbrains.jet.cli.common.ExitCode
import org.jetbrains.jet.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.jet.cli.common.CLICompiler
import org.apache.tools.ant.types.Commandline
import com.sampullara.cli.Args
import java.io.IOException
import org.jetbrains.jet.config
import org.jetbrains.jet.cli.common.messages.PrintingMessageCollector
import org.jetbrains.jet.cli.common.messages.MessageRenderer
/**
* {@code file.getCanonicalPath()} convenience wrapper.
*
* @param file - file to get its canonical path.
* @return file's canonical path
*/
fun getPath(file: File): String {
try {
return file.getCanonicalPath()
}
catch (e: IOException) {
throw RuntimeException("Failed to resolve canonical file of [$file]: $e", e)
}
}
/**
* Base class for Kotlin compiler Ant tasks.
* http://evgeny-goldin.org/javadoc/ant/tutorial-writing-tasks.html
*/
public abstract class KotlinCompilerBaseTask<T : CommonCompilerArguments> : Task() {
protected abstract val arguments: T
protected abstract val compiler: CLICompiler<T>
public var src: Path? = null
public var output: File? = null
public var nowarn: Boolean = false
public var verbose: Boolean = false
public var printVersion: Boolean = false
public val additionalArguments: MutableList<Commandline.Argument> = arrayListOf()
public fun createSrc(): Path {
val srcPath = src
if (srcPath == null) {
val t = Path(getProject())
src = t
return t
}
return srcPath.createPath()
}
public fun setSrcRef(ref: Reference) {
createSrc().setRefid(ref)
}
public fun createCompilerArg(): Commandline.Argument {
val argument = Commandline.Argument()
additionalArguments.add(argument)
return argument
}
abstract fun fillSpecificArguments()
private fun fillArguments() {
val sourcePaths = src ?: throw BuildException("\"src\" should be specified")
arguments.freeArgs = sourcePaths.list().map { getPath(File(it)) }
output ?: throw BuildException("\"output\" should be specified")
arguments.suppressWarnings = nowarn
arguments.verbose = verbose
arguments.version = printVersion
val args = additionalArguments.flatMap { it.getParts()!!.toList() }
try {
Args.parse(arguments, args.copyToArray())
}
catch (e: IllegalArgumentException) {
throw BuildException(e.getMessage())
}
fillSpecificArguments()
}
final override fun execute(): Unit {
fillArguments()
val outputPath = getPath(output!!)
log("Compiling ${arguments.freeArgs} => [${outputPath}]");
val collector = PrintingMessageCollector(System.err, MessageRenderer.PLAIN, arguments.verbose)
val exitCode = compiler.exec(collector, config.Services.EMPTY, arguments)
if (exitCode != ExitCode.OK) {
throw BuildException("Compilation finished with exit code $exitCode")
}
}
}

View File

@@ -5,10 +5,10 @@
<antlib>
<taskdef
name = "kotlinc"
classname = "org.jetbrains.jet.buildtools.ant.Kotlin2JvmTask"/>
classname = "org.jetbrains.jet.buildtools.ant.BytecodeCompilerTask"/>
<taskdef
name = "kotlin2js"
classname = "org.jetbrains.jet.buildtools.ant.Kotlin2JsTask"/>
classname = "org.jetbrains.jet.buildtools.ant.Kotlin2JsCompilerTask"/>
<typedef
name = "withKotlin"
classname = "org.jetbrains.jet.buildtools.ant.KotlinCompilerAdapter"/>

View File

@@ -0,0 +1,177 @@
/*
* Copyright 2010-2013 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.jet.buildtools.core;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.sampullara.cli.Args;
import org.apache.tools.ant.BuildException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.cli.common.CLIConfigurationKeys;
import org.jetbrains.jet.cli.common.arguments.K2JVMCompilerArguments;
import org.jetbrains.jet.cli.common.messages.MessageCollectorPlainTextToStream;
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentException;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.config.CompilerConfiguration;
import org.jetbrains.jet.utils.KotlinPaths;
import org.jetbrains.jet.utils.KotlinPathsFromHomeDir;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import static org.jetbrains.jet.cli.jvm.JVMConfigurationKeys.ANNOTATIONS_PATH_KEY;
import static org.jetbrains.jet.cli.jvm.JVMConfigurationKeys.CLASSPATH_KEY;
public class BytecodeCompiler {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
@NotNull
private static CompilerConfiguration createConfiguration(
@Nullable String stdlib,
@Nullable String[] classpath,
@Nullable String[] externalAnnotationsPath,
@NotNull String[] sourceRoots,
@NotNull List<String> args
) {
KotlinPaths paths = getKotlinPathsForAntTask();
CompilerConfiguration configuration = new CompilerConfiguration();
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollectorPlainTextToStream.PLAIN_TEXT_TO_SYSTEM_ERR);
configuration.addAll(CLASSPATH_KEY, PathUtil.getJdkClassesRoots());
if ((stdlib != null) && (stdlib.trim().length() > 0)) {
configuration.add(CLASSPATH_KEY, new File(stdlib));
}
else {
File path = paths.getRuntimePath();
if (path.exists()) {
configuration.add(CLASSPATH_KEY, path);
}
}
if ((classpath != null) && (classpath.length > 0)) {
for (String path : classpath) {
configuration.add(CLASSPATH_KEY, new File(path));
}
}
if ((externalAnnotationsPath != null) && (externalAnnotationsPath.length > 0)) {
for (String path : externalAnnotationsPath) {
configuration.add(ANNOTATIONS_PATH_KEY, new File(path));
}
}
File jdkAnnotationsPath = paths.getJdkAnnotationsPath();
if (jdkAnnotationsPath.exists()) {
configuration.add(ANNOTATIONS_PATH_KEY, jdkAnnotationsPath);
}
CompileEnvironmentUtil.addSourceFilesCheckingForDuplicates(configuration, Arrays.asList(sourceRoots));
for (String sourceRoot : sourceRoots) {
File file = new File(sourceRoot);
if (!file.isFile() || !"kt".equals(FileUtilRt.getExtension(file.getName()))) {
configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, file);
}
}
// TODO: use K2JVMCompiler directly, don't duplicate this code here
K2JVMCompilerArguments arguments = new K2JVMCompilerArguments();
try {
Args.parse(arguments, ArrayUtil.toStringArray(args));
}
catch (IllegalArgumentException e) {
throw new BuildException(e.getMessage());
}
K2JVMCompiler.putAdvancedOptions(configuration, arguments);
return configuration;
}
private static String errorMessage(@NotNull String[] source, boolean exceptionThrown) {
return String.format("Compilation of the following source roots failed:" + LINE_SEPARATOR +
getAbsolutePaths(source) +
(exceptionThrown ? "" : LINE_SEPARATOR + "see \"ERROR:\" messages above for more details."));
}
private static String getAbsolutePaths(String[] source) {
return StringUtil.join(
source,
new Function<String, String>() {
@Override
public String fun(String s) {
return " * " + new File(s).getAbsolutePath();
}
},
LINE_SEPARATOR
);
}
/**
* {@code KotlinToJVMBytecodeCompiler#compileBunchOfSources} wrapper.
* @param src compilation source (directory or file)
* @param destination compilation destination (directory or jar)
* @param includeRuntime whether Kotlin runtime library is included in destination jar
* @param stdlib "kotlin-runtime.jar" path
* @param args additional command line arguments to Kotlin compiler
*/
public static void compileSources(
@NotNull String[] src,
@NotNull String destination,
boolean includeRuntime,
@Nullable String stdlib,
@Nullable String[] classpath,
@Nullable String[] externalAnnotationsPath,
@NotNull List<String> args
) {
try {
JetCoreEnvironment environment = JetCoreEnvironment.createForProduction(
Disposer.newDisposable(),
createConfiguration(stdlib, classpath, externalAnnotationsPath, src, args)
);
// TODO: use K2JVMCompiler directly, don't duplicate this code here
boolean isJar = destination.endsWith(".jar");
File jar = isJar ? new File(destination) : null;
File outputDir = isJar ? null : new File(destination);
boolean success = KotlinToJVMBytecodeCompiler.compileBunchOfSources(environment, jar, outputDir, includeRuntime);
if (!success) {
throw new CompileEnvironmentException(errorMessage(src, false));
}
}
catch (BuildException e) {
throw e;
}
catch (CompileEnvironmentException e) {
throw e;
}
catch (Exception e) {
throw new CompileEnvironmentException(errorMessage(src, true), e);
}
}
private static KotlinPaths getKotlinPathsForAntTask() {
return new KotlinPathsFromHomeDir(PathUtil.getJarPathForClass(BytecodeCompiler.class).getParentFile().getParentFile());
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2010-2013 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.jet.buildtools.core;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
public final class Util {
private Util() {
}
/**
* {@code file.getCanonicalPath()} convenience wrapper.
*
* @param f file to get its canonical path.
* @return file's canonical path
*/
@NotNull
public static String getPath(@NotNull File f) {
try {
return f.getCanonicalPath();
}
catch (IOException e) {
throw new RuntimeException(String.format("Failed to resolve canonical file of [%s]: %s", f, e), e);
}
}
@NotNull
public static String[] getPaths(String[] paths) {
String[] result = new String[paths.length];
for (int i = 0; i < paths.length; i++) {
String path = paths[i];
result[i] = getPath(new File(path));
}
return result;
}
}

View File

@@ -1,6 +1,4 @@
<project name="Kotlin" default="dist">
<include file="jslib_files.xml" />
<property file="resources/manifest.properties"/>
<!-- Set to false to disable proguard run on kotlin-compiler.jar. Speeds up the build -->
@@ -65,6 +63,7 @@
<include name="core/serialization/src"/>
<include name="core/descriptor.loader.java/src"/>
<include name="compiler/frontend.java/src"/>
<include name="compiler/frontend.android/src"/>
<include name="core/serialization.java/src"/>
<include name="compiler/backend-common/src"/>
<include name="compiler/backend/src"/>
@@ -79,7 +78,6 @@
<include name="js/js.dart-ast/src"/>
<include name="js/js.translator/src"/>
<include name="js/js.frontend/src"/>
<include name="js/js.inliner/src"/>
</dirset>
<property name="idea.out" value="${basedir}/out/production"/>
@@ -89,6 +87,7 @@
<include name="serialization/**"/>
<include name="descriptor.loader.java/**"/>
<include name="frontend.java/**"/>
<include name="frontend.android/**"/>
<include name="serialization.java/**"/>
<include name="backend/**"/>
<include name="backend-common/**"/>
@@ -102,7 +101,6 @@
<include name="js.dart-ast/**"/>
<include name="js.translator/**"/>
<include name="js.frontend/**"/>
<include name="js.inliner/**"/>
</patternset>
<path id="compilerSources.path">
@@ -167,7 +165,6 @@
<fileset dir="js/js.dart-ast/src"/>
<fileset dir="js/js.translator/src"/>
<fileset dir="js/js.frontend/src"/>
<fileset dir="js/js.inliner/src"/>
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
<manifest>
@@ -218,18 +215,17 @@
</target>
<target name="jslib">
<property name="compiled.stdlib.js" value="stdlib.js" />
<property name="stdlib.js.dir" value="${basedir}/js/js.translator/testData" />
<kotlin2js output="${output}/${compiled.stdlib.js}" main="noCall">
<src>
<fileset refid="kotlin.builtin.files" />
<resources refid="js.lib.files" />
</src>
</kotlin2js>
<jar jarfile="${kotlin-home}/lib/kotlin-jslib.jar">
<resources refid="js.lib.files" />
<fileset dir="${basedir}/js/js.libraries/src">
<include name="core/**"/>
<include name="jquery/**"/>
<include name="dom/**"/>
<include name="html5/**"/>
<include name="stdlib/TuplesCode.kt"/>
</fileset>
<fileset dir="${basedir}/core/reflection/src">
<include name="kotlin/**"/>
</fileset>
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
<manifest>
@@ -245,36 +241,21 @@
classname="com.google.javascript.jscomp.ant.CompileTask"
classpath="${dependencies.dir}/closure-compiler.jar"/>
<!-- value should be one of: whitespace, simple, advanced -->
<property name="compilationLevel" value="simple" />
<!-- value should be one of: default, quiet, verbose -->
<property name="warningLevel" value="default" />
<closure-compiler
compilationLevel="${compilationLevel}"
compilationLevel="simple"
prettyprint="true"
languagein="ECMASCRIPT5_STRICT"
warning="${warningLevel}"
output="${kotlin-home}/lib/kotlin.js" >
warning="verbose"
debug="false"
output="${kotlin-home}/lib/kotlin.js">
<sources dir="${stdlib.js.dir}">
<sources dir="${basedir}/js/js.translator/testData">
<file name="kotlin_lib_ecma5.js"/>
<file name="kotlin_lib.js"/>
<file name="maps.js"/>
<file name="long.js"/>
</sources>
<sources dir="${output}">
<file name="${compiled.stdlib.js}"/>
</sources>
<sources dir="${stdlib.js.dir}">
<file name="export_Kotlin_if_possible.js"/>
</sources>
<externs dir="${stdlib.js.dir}">
<file name="externs.js"/>
</externs>
</closure-compiler>
</target>
@@ -351,7 +332,6 @@
</fileset>
<fileset dir="${basedir}/compiler/frontend.java/src" includes="META-INF/services/**"/>
<fileset dir="${basedir}/compiler/backend/src" includes="META-INF/services/**"/>
<fileset dir="${basedir}/resources" includes="manifest.properties"/>
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
<zipgroupfileset dir="${basedir}/ideaSDK/core" includes="*.jar" excludes="util.jar"/>
@@ -677,7 +657,7 @@
depends="init,prepareDist,preloader,builtins,compiler_quick"
description="Builds compiler jar from project out dir"/>
<target name="zip-compiler" depends="dist">
<target name="zip" depends="dist">
<zip destfile="${output}/${output.name}.zip">
<zipfileset prefix="kotlinc" dir="${kotlin-home}" excludes="bin/*"/>
<zipfileset prefix="kotlinc/bin" dir="${kotlin-home}/bin" includes="*.bat" filemode="644"/>
@@ -692,7 +672,7 @@
source="${java.target}" target="${java.target}">
<withKotlin externalannotations="${external.annotations.path}"/>
<src>
<dirset dir="${basedir}/idea/ide-common">
<dirset dir="${basedir}/idea/ide-lazy-resolve">
<include name="src"/>
</dirset>
<dirset dir="${basedir}/idea/idea-analysis">
@@ -766,9 +746,7 @@
<fileset dir="js/js.dart-ast/src"/>
<fileset dir="js/js.translator/src"/>
<fileset dir="js/js.frontend/src"/>
<fileset dir="js/js.inliner/src"/>
<fileset dir="idea/idea-analysis/src"/>
<fileset dir="idea/ide-common/src"/>
<manifest>
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
@@ -780,12 +758,5 @@
</target>
<target name="zip-test-data">
<zip destfile="${output}/kotlin-test-data.zip">
<zipfileset dir="compiler/testData" prefix="compiler"/>
<zipfileset dir="idea/testData" prefix="ide"/>
</zip>
</target>
<target name="build-artifacts" depends="zip-compiler,kotlin-for-upsource,zip-test-data"/>
<target name="build-artifacts" depends="zip,kotlin-for-upsource"/>
</project>

View File

@@ -16,7 +16,6 @@
package org.jetbrains.jet.compiler;
import com.intellij.util.PlatformUtils;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jetbrains.annotations.NotNull;
@@ -180,13 +179,11 @@ public class CodegenTestsOnAndroidRunner {
downloader.downloadAll();
downloader.unzipAll();
String platformPrefixProperty = System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, "Idea");
PermissionManager.setPermissions(pathManager);
antRunner.packLibraries();
try {
PermissionManager.setPermissions(pathManager);
antRunner.packLibraries();
emulator.createEmulator();
emulator.startEmulator();
@@ -210,12 +207,6 @@ public class CodegenTestsOnAndroidRunner {
throw e;
}
finally {
if (platformPrefixProperty != null) {
System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, platformPrefixProperty);
}
else {
System.clearProperty(PlatformUtils.PLATFORM_PREFIX_KEY);
}
emulator.finishEmulatorProcesses();
}
}

View File

@@ -73,8 +73,6 @@ public class SpecialFiles {
excludedFiles.add("invokeOnClassObjectOfNestedClass2.kt"); // Cannot change package name
excludedFiles.add("invokeOnImportedEnum1.kt"); // Cannot change package name
excludedFiles.add("invokeOnImportedEnum2.kt"); // Cannot change package name
excludedFiles.add("sortEnumEntries.kt"); // Cannot change package name
excludedFiles.add("assertionStackTrace.kt"); // Cannot change package name
excludedFiles.add("kt326.kt"); // Commented
excludedFiles.add("kt1213.kt"); // Commented

View File

@@ -87,7 +87,7 @@ public fun findTraitImplementation(descriptor: CallableMemberDescriptor): Callab
// If this implementation is already generated into one of the superclasses, we need not generate it again, it'll be inherited
val containingClass = descriptor.getContainingDeclaration() as ClassDescriptor
val implClassType = implementation!!.getDispatchReceiverParameter()!!.getType()
val implClassType = implementation!!.getExpectedThisObject()!!.getType()
for (supertype in containingClass.getDefaultType().getConstructor().getSupertypes()) {
if (!DescriptorUtils.isTrait(supertype.getConstructor().getDeclarationDescriptor()!!) &&
TypeUtils.getAllSupertypes(supertype).contains(implClassType)) {

View File

@@ -18,7 +18,6 @@ package org.jetbrains.jet.backend.common;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.bridges.BridgesPackage;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
import org.jetbrains.jet.lang.psi.JetExpression;
@@ -126,32 +125,18 @@ public class CodegenUtil {
Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor));
}
@NotNull
public static Map<FunctionDescriptor, FunctionDescriptor> getTraitMethods(ClassDescriptor descriptor) {
Map<FunctionDescriptor, FunctionDescriptor> result = new LinkedHashMap<FunctionDescriptor, FunctionDescriptor>();
public static Map<CallableMemberDescriptor, CallableMemberDescriptor> getDelegates(ClassDescriptor descriptor, ClassDescriptor toClass) {
Map<CallableMemberDescriptor, CallableMemberDescriptor> result = new LinkedHashMap<CallableMemberDescriptor, CallableMemberDescriptor>();
for (DeclarationDescriptor declaration : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
if (!(declaration instanceof CallableMemberDescriptor)) continue;
CallableMemberDescriptor inheritedMember = (CallableMemberDescriptor) declaration;
CallableMemberDescriptor traitMember = BridgesPackage.findTraitImplementation(inheritedMember);
if (traitMember == null) continue;
assert traitMember.getModality() != Modality.ABSTRACT : "Cannot delegate to abstract trait method: " + inheritedMember;
// inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here
// with traitMember's modality
CallableMemberDescriptor copy =
inheritedMember.copy(inheritedMember.getContainingDeclaration(), traitMember.getModality(), Visibilities.PUBLIC,
CallableMemberDescriptor.Kind.DECLARATION, true);
if (traitMember instanceof SimpleFunctionDescriptor) {
result.put((FunctionDescriptor) traitMember, (FunctionDescriptor) copy);
}
else if (traitMember instanceof PropertyDescriptor) {
for (PropertyAccessorDescriptor traitAccessor : ((PropertyDescriptor) traitMember).getAccessors()) {
for (PropertyAccessorDescriptor inheritedAccessor : ((PropertyDescriptor) copy).getAccessors()) {
if (inheritedAccessor.getClass() == traitAccessor.getClass()) { // same accessor kind
result.put(traitAccessor, inheritedAccessor);
if (declaration instanceof CallableMemberDescriptor) {
CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) declaration;
if (callableMemberDescriptor.getKind() == CallableMemberDescriptor.Kind.DELEGATION) {
Set<? extends CallableMemberDescriptor> overriddenDescriptors = callableMemberDescriptor.getOverriddenDescriptors();
for (CallableMemberDescriptor overriddenDescriptor : overriddenDescriptors) {
if (overriddenDescriptor.getContainingDeclaration() == toClass) {
assert !result.containsKey(callableMemberDescriptor) :
"overridden is already set for " + callableMemberDescriptor;
result.put(callableMemberDescriptor, overriddenDescriptor);
}
}
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright 2010-2014 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.jet.backend.common
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.types.JetType
import kotlin.platform.platformStatic
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.utils.keysToMapExceptNulls
import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.lang.resolve.MemberComparator
import java.util.Comparator
public object CodegenUtilKt {
// class Foo : Bar by baz
// descriptor = Foo
// toTrait = Bar
// delegateExpressionType = typeof(baz)
// return Map<member of Foo, corresponding member of typeOf(baz)>
public [platformStatic] fun getDelegates(
descriptor: ClassDescriptor,
toTrait: ClassDescriptor,
delegateExpressionType: JetType? = null
): Map<CallableMemberDescriptor, CallableDescriptor> {
return descriptor.getDefaultType().getMemberScope().getAllDescriptors().stream()
.filterIsInstance(javaClass<CallableMemberDescriptor>())
.filter { it.getKind() == CallableMemberDescriptor.Kind.DELEGATION }
.toList()
.sortBy(MemberComparator.INSTANCE as Comparator<CallableMemberDescriptor>) // Workaround for KT-6030
.keysToMapExceptNulls {
delegatingMember ->
val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember)
.filter { it.getContainingDeclaration() == toTrait }
.map {
overriddenDescriptor ->
val scope = (delegateExpressionType ?: toTrait.getDefaultType()).getMemberScope()
val name = overriddenDescriptor.getName()
// this is the actual member of delegateExpressionType that we are delegating to
(scope.getFunctions(name) + scope.getProperties(name))
.first {
(listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it)).map { it.getOriginal() }.contains(overriddenDescriptor.getOriginal())
}
}
assert(actualDelegates.size <= 1) { "Meny delegates found for $delegatingMember: $actualDelegates" }
actualDelegates.firstOrNull()
}
}
}

View File

@@ -44,8 +44,8 @@ public class AccessorForFunctionDescriptor extends SimpleFunctionDescriptorImpl
Kind.DECLARATION, SourceElement.NO_SOURCE);
this.calleeDescriptor = descriptor;
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
descriptor instanceof ConstructorDescriptor ? NO_RECEIVER_PARAMETER : descriptor.getDispatchReceiverParameter(),
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getReceiverParameter()),
descriptor instanceof ConstructorDescriptor ? NO_RECEIVER_PARAMETER : descriptor.getExpectedThisObject(),
copyTypeParameters(descriptor),
copyValueParameters(descriptor),
descriptor.getReturnType(),

View File

@@ -34,14 +34,14 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
private final PropertyDescriptor calleeDescriptor;
public AccessorForPropertyDescriptor(@NotNull PropertyDescriptor pd, @NotNull DeclarationDescriptor containingDeclaration, int index) {
this(pd, pd.getType(), DescriptorUtils.getReceiverParameterType(pd.getExtensionReceiverParameter()), pd.getDispatchReceiverParameter(), containingDeclaration, index);
this(pd, pd.getType(), DescriptorUtils.getReceiverParameterType(pd.getReceiverParameter()), pd.getExpectedThisObject(), containingDeclaration, index);
}
protected AccessorForPropertyDescriptor(
@NotNull PropertyDescriptor original,
@NotNull JetType propertyType,
@Nullable JetType receiverType,
@Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
@Nullable ReceiverParameterDescriptor expectedThisObject,
@NotNull DeclarationDescriptor containingDeclaration,
int index
) {
@@ -50,7 +50,7 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
Kind.DECLARATION, SourceElement.NO_SOURCE);
this.calleeDescriptor = original;
setType(propertyType, Collections.<TypeParameterDescriptorImpl>emptyList(), dispatchReceiverParameter, receiverType);
setType(propertyType, Collections.<TypeParameterDescriptorImpl>emptyList(), expectedThisObject, receiverType);
initialize(new Getter(this), new Setter(this));
}

View File

@@ -37,9 +37,7 @@ import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaCallableMemberDescriptor;
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.Approximation;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypesPackage;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.org.objectweb.asm.*;
@@ -486,28 +484,29 @@ public class AsmUtil {
v.xor(Type.INT_TYPE);
}
@NotNull
public static StackValue genEqualsForExpressionsOnStack(
@NotNull InstructionAdapter v,
@NotNull IElementType opToken,
@NotNull Type leftType,
@NotNull Type rightType
InstructionAdapter v,
IElementType opToken,
Type leftType,
Type rightType
) {
if (isPrimitive(leftType) && leftType == rightType) {
if ((isNumberPrimitive(leftType) || leftType.getSort() == Type.BOOLEAN) && leftType == rightType) {
return StackValue.cmp(opToken, leftType);
}
else {
if (opToken == JetTokens.EQEQEQ || opToken == JetTokens.EXCLEQEQEQ) {
return StackValue.cmp(opToken, leftType);
}
else {
v.invokestatic("kotlin/jvm/internal/Intrinsics", "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
if (opToken == JetTokens.EQEQEQ || opToken == JetTokens.EXCLEQEQEQ) {
return StackValue.cmp(opToken, leftType);
if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
genInvertBoolean(v);
}
return StackValue.onStack(Type.BOOLEAN_TYPE);
}
}
v.invokestatic("kotlin/jvm/internal/Intrinsics", "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
genInvertBoolean(v);
}
return StackValue.onStack(Type.BOOLEAN_TYPE);
}
public static void genIncrement(Type expectedType, int myDelta, InstructionAdapter v) {
@@ -609,15 +608,12 @@ public class AsmUtil {
@NotNull CallableDescriptor descriptor,
@NotNull String assertMethodToCall
) {
// Assertions are generated elsewhere for platform types
if (JavaPackage.getPLATFORM_TYPES()) return;
if (!state.isCallAssertionsEnabled()) return;
if (!isDeclaredInJava(descriptor)) return;
JetType type = descriptor.getReturnType();
if (type == null || isNullableType(TypesPackage.lowerIfFlexible(type))) return;
if (type == null || isNullableType(type)) return;
Type asmType = state.getTypeMapper().mapReturnType(descriptor);
if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) {
@@ -629,30 +625,6 @@ public class AsmUtil {
}
}
@NotNull
public static StackValue genNotNullAssertions(
@NotNull GenerationState state,
@NotNull final StackValue stackValue,
@Nullable final Approximation.Info approximationInfo
) {
if (!state.isCallAssertionsEnabled()) return stackValue;
if (approximationInfo == null || !TypesPackage.assertNotNull(approximationInfo)) return stackValue;
return new StackValue(stackValue.type) {
@Override
public void put(Type type, InstructionAdapter v) {
stackValue.put(type, v);
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
v.dup();
v.visitLdcInsn(approximationInfo.getMessage());
v.invokestatic("kotlin/jvm/internal/Intrinsics", "checkExpressionValueIsNotNull",
"(Ljava/lang/Object;Ljava/lang/String;)V", false);
}
}
};
}
private static boolean isDeclaredInJava(@NotNull CallableDescriptor callableDescriptor) {
CallableDescriptor descriptor = callableDescriptor;
while (true) {
@@ -695,7 +667,7 @@ public class AsmUtil {
}
public static int getVisibilityForSpecialPropertyBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null;
if (isDelegate || isExtensionProperty) {
return ACC_PRIVATE;
}
@@ -716,7 +688,7 @@ public class AsmUtil {
}
public static boolean isPropertyWithBackingFieldCopyInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null;
DeclarationDescriptor propertyContainer = propertyDescriptor.getContainingDeclaration();
return !propertyDescriptor.isVar()
&& !isExtensionProperty

View File

@@ -28,7 +28,6 @@ import org.jetbrains.jet.codegen.signature.BothSignatureWriter;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
@@ -55,7 +54,6 @@ import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class ClosureCodegen extends ParentCodegenAware {
private final PsiElement fun;
private final FunctionDescriptor funDescriptor;
private final ClassDescriptor classDescriptor;
private final SamType samType;
private final JetType superClassType;
private final List<JetType> superInterfaceTypes;
@@ -88,7 +86,7 @@ public class ClosureCodegen extends ParentCodegenAware {
this.syntheticClassKind = syntheticClassKind;
this.strategy = strategy;
this.classDescriptor = anonymousClassForFunction(bindingContext, funDescriptor);
ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, funDescriptor);
if (samType == null) {
this.superInterfaceTypes = new ArrayList<JetType>();
@@ -166,21 +164,6 @@ public class ClosureCodegen extends ParentCodegenAware {
FunctionCodegen fc = new FunctionCodegen(context, cv, state, getParentCodegen());
fc.generateMethod(OtherOrigin(fun, funDescriptor), jvmMethodSignature, funDescriptor, strategy);
//TODO: rewrite cause ugly hack
if (samType != null) {
SimpleFunctionDescriptorImpl descriptorForBridges = SimpleFunctionDescriptorImpl
.create(funDescriptor.getContainingDeclaration(), funDescriptor.getAnnotations(), erasedInterfaceFunction.getName(),
CallableMemberDescriptor.Kind.DECLARATION, funDescriptor.getSource());
descriptorForBridges
.initialize(null, erasedInterfaceFunction.getDispatchReceiverParameter(), erasedInterfaceFunction.getTypeParameters(),
erasedInterfaceFunction.getValueParameters(), erasedInterfaceFunction.getReturnType(), Modality.OPEN,
erasedInterfaceFunction.getVisibility());
descriptorForBridges.addOverriddenDescriptor(erasedInterfaceFunction);
fc.generateBridges(descriptorForBridges);
}
this.constructor = generateConstructor(cv, superClassAsmType);
if (isConst(closure)) {
@@ -197,7 +180,7 @@ public class ClosureCodegen extends ParentCodegenAware {
null);
AsmUtil.writeOuterClassAndEnclosingMethod(classDescriptor, funDescriptor, typeMapper, cv);
AsmUtil.writeOuterClassAndEnclosingMethod(anonymousClassForFunction(bindingContext, funDescriptor), funDescriptor, typeMapper, cv);
cv.done();
}
@@ -210,7 +193,7 @@ public class ClosureCodegen extends ParentCodegenAware {
v.anew(asmType);
v.dup();
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
codegen.pushClosureOnStack(closure, false, codegen.defaultCallGenerator);
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
}
return StackValue.onStack(asmType);
@@ -247,7 +230,7 @@ public class ClosureCodegen extends ParentCodegenAware {
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, asmType);
ReceiverParameterDescriptor receiver = funDescriptor.getExtensionReceiverParameter();
ReceiverParameterDescriptor receiver = funDescriptor.getReceiverParameter();
int count = 1;
if (receiver != null) {
StackValue.local(count, bridge.getArgumentTypes()[count - 1]).put(typeMapper.mapType(receiver.getType()), iv);
@@ -345,7 +328,7 @@ public class ClosureCodegen extends ParentCodegenAware {
@NotNull
public static FunctionDescriptor getErasedInvokeFunction(@NotNull FunctionDescriptor funDescriptor) {
int arity = funDescriptor.getValueParameters().size();
ClassDescriptor funClass = funDescriptor.getExtensionReceiverParameter() == null
ClassDescriptor funClass = funDescriptor.getReceiverParameter() == null
? KotlinBuiltIns.getInstance().getFunction(arity)
: KotlinBuiltIns.getInstance().getExtensionFunction(arity);
return funClass.getDefaultType().getMemberScope().getFunctions(Name.identifier("invoke")).iterator().next();

View File

@@ -50,11 +50,4 @@ public class CodegenStatementVisitor extends JetVisitor<StackValue, StackValue>
public StackValue visitBlockExpression(@NotNull JetBlockExpression expression, StackValue data) {
return codegen.generateBlock(expression, true);
}
@Override
public StackValue visitLabeledExpression(@NotNull JetLabeledExpression expression, StackValue receiver) {
JetExpression baseExpression = expression.getBaseExpression();
assert baseExpression != null : "Label expression should have base one: " + expression.getText();
return baseExpression.accept(this, receiver);
}
}

View File

@@ -1,232 +0,0 @@
/*
* Copyright 2010-2014 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.jet.codegen
import org.jetbrains.jet.codegen.state.GenerationState
import org.jetbrains.jet.lang.descriptors.*
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.*
import org.jetbrains.jet.lang.descriptors.impl.*
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.types.*
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.resolve.OverrideResolver
import org.jetbrains.jet.lang.resolve.OverridingUtil
import java.util.LinkedHashSet
import org.jetbrains.jet.lang.resolve.name.Name
import java.util.ArrayList
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
import java.util.HashSet
/**
* Generates exception-throwing stubs for methods from mutable collection classes not implemented in Kotlin classes which inherit only from
* Kotlin's read-only collections. This is required on JVM because Kotlin's read-only collections are mapped to mutable JDK collections
*/
class CollectionStubMethodGenerator(
state: GenerationState,
private val descriptor: ClassDescriptor,
private val functionCodegen: FunctionCodegen,
private val v: ClassBuilder
) {
private val typeMapper = state.getTypeMapper()
fun generate() {
val superCollectionClasses = findRelevantSuperCollectionClasses()
if (superCollectionClasses.isEmpty()) return
val methodStubsToGenerate = LinkedHashSet<String>()
val syntheticStubsToGenerate = LinkedHashSet<String>()
for ((readOnlyClass, mutableClass) in superCollectionClasses) {
// To determine which method stubs we need to generate, we create a synthetic class (named 'child' here) which inherits from
// our class ('descriptor') and the corresponding MutableCollection class (for example; the process is the same for every
// built-in read-only/mutable class pair). We then construct and bind fake overrides in this synthetic class with the usual
// override resolution process. Resulting fake overrides with originals in MutableCollection are considered as candidates for
// method stubs or bridges to the actual implementation that happened to be present in the class
val (child, typeParameters) = createSyntheticSubclass()
// If the original class has any type parameters, we copied them and now we need to substitute types of the newly created type
// parameters as arguments for the type parameters of the original class
val parentType = newType(descriptor, typeParameters.map { TypeProjectionImpl(it.getDefaultType()) })
// Now we need to determine the arguments which should be substituted for the MutableCollection super class. To do that,
// we look for type arguments which were substituted in the inheritance of the original class from Collection and use them
// to construct the needed MutableCollection type. Since getAllSupertypes() may return several types which correspond to the
// Collection class descriptor, we find the most specific one (which is guaranteed to exist by front-end)
val readOnlyCollectionType = TypeUtils.getAllSupertypes(parentType).findMostSpecificTypeForClass(readOnlyClass)
val mutableCollectionType = newType(mutableClass, readOnlyCollectionType.getArguments())
child.addSupertype(parentType)
child.addSupertype(mutableCollectionType)
child.createTypeConstructor()
// Bind fake overrides and for each fake override originated from the MutableCollection, save its signature to generate a stub
// or save its descriptor to generate all the needed bridges
for (method in findFakeOverridesForMethodsFromMutableCollection(child, mutableClass)) {
if (method.getModality() == Modality.ABSTRACT) {
// If the fake override is abstract and it's _declared_ as abstract in the class, skip it because the method is already
// present in the bytecode (abstract) and we don't want a duplicate signature error
if (method.findOverriddenFromDirectSuperClass(descriptor)?.getKind() == DECLARATION) continue
// Otherwise we can safely generate the stub with the substituted signature
val signature = method.signature()
methodStubsToGenerate.add(signature)
// If the substituted signature differs from the original one in MutableCollection, we should also generate a stub with
// the original (erased) signature. It doesn't really matter if this is a bridge method delegating to the first stub or
// a method with its own exception-throwing code, for simplicity we do the latter here.
// What _does_ matter though, is that these two methods can't be both non-synthetic at once: javac issues compilation
// errors when compiling Java against such classes because one of them doesn't seem to override the generic method
// declared in the Java Collection interface (can't override generic with erased). So we maintain an additional set of
// methods which need to be generated with the ACC_SYNTHETIC flag
val originalSignature = method.findOverriddenFromDirectSuperClass(mutableClass)!!.getOriginal().signature()
if (originalSignature != signature) {
syntheticStubsToGenerate.add(originalSignature)
}
}
else {
// If the fake override is non-abstract, its implementation is already present in the class or inherited from one of its
// super classes, but is not related to the MutableCollection hierarchy. So maybe it uses more specific return types
// and we may need to generate some bridges
functionCodegen.generateBridges(method)
}
}
}
for (signature in methodStubsToGenerate) {
generateMethodStub(signature, synthetic = false)
}
for (signature in syntheticStubsToGenerate) {
generateMethodStub(signature, synthetic = true)
}
}
private data class CollectionClassPair(
val readOnlyClass: ClassDescriptor,
val mutableClass: ClassDescriptor
)
private fun findRelevantSuperCollectionClasses(): Collection<CollectionClassPair> {
fun pair(readOnlyClass: ClassDescriptor, mutableClass: ClassDescriptor) = CollectionClassPair(readOnlyClass, mutableClass)
val collectionClasses = with(KotlinBuiltIns.getInstance()) {
listOf(
pair(getCollection(), getMutableCollection()),
pair(getSet(), getMutableSet()),
pair(getList(), getMutableList()),
pair(getMap(), getMutableMap()),
pair(getMapEntry(), getMutableMapEntry()),
pair(getIterable(), getMutableIterable()),
pair(getIterator(), getMutableIterator()),
pair(getListIterator(), getMutableListIterator())
)
}
val allSuperClasses = TypeUtils.getAllSupertypes(descriptor.getDefaultType()).classes().toHashSet()
val ourSuperCollectionClasses = collectionClasses.filter { pair ->
pair.readOnlyClass in allSuperClasses && pair.mutableClass !in allSuperClasses
}
if (ourSuperCollectionClasses.isEmpty()) return listOf()
// Filter out built-in classes which are overridden by other built-in classes in the list, to avoid duplicating methods.
val redundantClasses = ourSuperCollectionClasses.flatMapTo(HashSet<ClassDescriptor>()) { pair ->
pair.readOnlyClass.getTypeConstructor().getSupertypes().classes()
}
return ourSuperCollectionClasses.filter { klass -> klass.readOnlyClass !in redundantClasses }
}
private fun Collection<JetType>.classes(): Collection<ClassDescriptor> =
this.map { it.getConstructor().getDeclarationDescriptor() as ClassDescriptor }
private fun findFakeOverridesForMethodsFromMutableCollection(
klass: ClassDescriptor,
mutableCollectionClass: ClassDescriptor
): List<FunctionDescriptor> {
val result = ArrayList<FunctionDescriptor>()
OverrideResolver.generateOverridesInAClass(klass, listOf(), object : OverridingUtil.DescriptorSink {
override fun addToScope(fakeOverride: CallableMemberDescriptor) {
if (fakeOverride !is FunctionDescriptor) return
if (fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionClass) != null) {
result.add(fakeOverride)
}
}
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
// Ignore conflicts here
// TODO: report a warning that javac will prohibit use/inheritance from such class
}
})
return result
}
private fun Collection<JetType>.findMostSpecificTypeForClass(klass: ClassDescriptor): JetType {
val types = this.filter { it.getConstructor().getDeclarationDescriptor() == klass }
if (types.isEmpty()) error("No supertype of $klass in $this")
if (types.size == 1) return types.first()
// Find the first type in the list such that it's a subtype of every other type in that list
return types.first { type ->
types.all { other -> JetTypeChecker.DEFAULT.isSubtypeOf(type, other) }
}
}
private fun createSyntheticSubclass(): Pair<MutableClassDescriptor, List<TypeParameterDescriptor>> {
val child = MutableClassDescriptor(descriptor.getContainingDeclaration(), JetScope.EMPTY, ClassKind.CLASS, false,
Name.special("<synthetic inheritor of ${descriptor.getName()}>"), descriptor.getSource())
child.setModality(Modality.FINAL)
child.setVisibility(Visibilities.PUBLIC)
val typeParameters = descriptor.getTypeConstructor().getParameters()
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size())
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitutor.EMPTY, child, newTypeParameters)
child.setTypeParameterDescriptors(typeParameters)
return Pair(child, newTypeParameters)
}
private fun FunctionDescriptor.findOverriddenFromDirectSuperClass(classDescriptor: ClassDescriptor): FunctionDescriptor? {
return this.getOverriddenDescriptors().firstOrNull { it.getContainingDeclaration() == classDescriptor }
}
private fun newType(classDescriptor: ClassDescriptor, typeArguments: List<TypeProjection>): JetType {
return JetTypeImpl(Annotations.EMPTY, classDescriptor.getTypeConstructor(), false, typeArguments,
classDescriptor.getMemberScope(typeArguments))
}
private fun FunctionDescriptor.signature(): String {
val method = typeMapper.mapSignature(this).getAsmMethod()
return method.getName() + method.getDescriptor()
}
private fun generateMethodStub(signature: String, synthetic: Boolean) {
// TODO: investigate if it makes sense to generate abstract stubs in traits
var access = ACC_PUBLIC
if (descriptor.getKind() == ClassKind.TRAIT) access = access or ACC_ABSTRACT
if (synthetic) access = access or ACC_SYNTHETIC
val paren = signature.indexOf('(')
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, signature.substring(0, paren), signature.substring(paren), null, null)
if (descriptor.getKind() != ClassKind.TRAIT) {
mv.visitCode()
AsmUtil.genThrow(InstructionAdapter(mv), "java/lang/UnsupportedOperationException", "Mutating immutable collection")
FunctionCodegen.endVisit(mv, "built-in stub for $signature", null)
}
}
}

View File

@@ -29,7 +29,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
import org.jetbrains.jet.codegen.binding.CodegenBinding;
import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.codegen.context.*;
import org.jetbrains.jet.codegen.extensions.ExpressionCodegenExtension;
import org.jetbrains.jet.codegen.inline.InlineCodegen;
import org.jetbrains.jet.codegen.inline.InlineCodegenUtil;
import org.jetbrains.jet.codegen.inline.NameGenerator;
@@ -60,7 +62,6 @@ import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
import org.jetbrains.jet.lang.types.Approximation;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
@@ -88,7 +89,6 @@ import static org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage.getR
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.TraitImpl;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.jetbrains.org.objectweb.asm.Opcodes.GETFIELD;
@@ -184,7 +184,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
@NotNull
public ClassDescriptor generateObjectLiteral(@NotNull JetObjectLiteralExpression literal) {
public CalculatedClosure generateObjectLiteral(@NotNull JetObjectLiteralExpression literal) {
JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration();
ClassDescriptor classDescriptor = bindingContext.get(CLASS, objectDeclaration);
@@ -197,10 +197,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
literal.getContainingFile()
);
ClassContext objectContext = context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION);
ClassContext objectContext = context.intoAnonymousClass(classDescriptor, this);
new ImplementationBodyCodegen(objectDeclaration, objectContext, classBuilder, state, getParentCodegen()).generate();
return classDescriptor;
//noinspection ConstantConditions
return bindingContext.get(CLOSURE, classDescriptor);
}
@NotNull
@@ -239,14 +242,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
}
StackValue stackValue = selector.accept(visitor, receiver);
Approximation.Info approximationInfo = null;
if (selector instanceof JetExpression) {
approximationInfo = bindingContext.get(BindingContext.EXPRESSION_RESULT_APPROXIMATION, (JetExpression) selector);
}
return genNotNullAssertions(state, stackValue, approximationInfo);
return selector.accept(visitor, receiver);
}
catch (ProcessCanceledException e) {
throw e;
@@ -290,16 +286,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type asmType = asmTypeForAnonymousClass(bindingContext, declaration);
ClassBuilder classBuilder = state.getFactory().newVisitor(OtherOrigin(declaration, descriptor), asmType, declaration.getContainingFile());
ClassContext objectContext = context.intoAnonymousClass(descriptor, this, OwnerKind.IMPLEMENTATION);
ClassContext objectContext = context.intoAnonymousClass(descriptor, this);
new ImplementationBodyCodegen(declaration, objectContext, classBuilder, state, getParentCodegen()).generate();
if (declaration instanceof JetClass && ((JetClass) declaration).isTrait()) {
Type traitImplType = state.getTypeMapper().mapTraitImpl(descriptor);
ClassBuilder traitImplBuilder = state.getFactory().newVisitor(TraitImpl(declaration, descriptor), traitImplType, declaration.getContainingFile());
ClassContext traitImplContext = context.intoAnonymousClass(descriptor, this, OwnerKind.TRAIT_IMPL);
new TraitImplBodyCodegen(declaration, traitImplContext, traitImplBuilder, state, parentCodegen).generate();
}
return StackValue.none();
}
@@ -661,8 +650,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
public void afterBody(@NotNull Label loopExit) {
markLineNumber(forExpression);
increment(loopExit);
v.mark(bodyEnd);
@@ -1340,16 +1327,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override
public StackValue visitObjectLiteralExpression(@NotNull JetObjectLiteralExpression expression, StackValue receiver) {
ClassDescriptor classDescriptor = generateObjectLiteral(expression);
Type type = typeMapper.mapType(classDescriptor);
CalculatedClosure closure = generateObjectLiteral(expression);
ConstructorDescriptor constructorDescriptor = bindingContext.get(CONSTRUCTOR, expression.getObjectDeclaration());
assert constructorDescriptor != null : "Unresolved constructor: " + expression.getText();
JvmMethodSignature constructor = typeMapper.mapSignature(constructorDescriptor);
Type type = typeMapper.mapType(constructorDescriptor.getContainingDeclaration());
v.anew(type);
v.dup();
pushClosureOnStack(classDescriptor, true, defaultCallGenerator);
pushClosureOnStack(closure, false, defaultCallGenerator);
//noinspection ConstantConditions
ResolvedCall<ConstructorDescriptor> superCall = bindingContext.get(CLOSURE, classDescriptor).getSuperCall();
ResolvedCall<ConstructorDescriptor> superCall = closure.getSuperCall();
if (superCall != null) {
// For an anonymous object, we should also generate all non-default arguments that it captures for its super call
ConstructorDescriptor superConstructor = superCall.getResultingDescriptor();
@@ -1357,7 +1348,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
int params = superValueParameters.size();
List<Type> superMappedTypes = typeMapper.mapToCallableMethod(superConstructor).getValueParameterTypes();
assert superMappedTypes.size() >= params : String.format("Incorrect number of mapped parameters vs arguments: %d < %d for %s",
superMappedTypes.size(), params, classDescriptor);
superMappedTypes.size(), params, constructorDescriptor);
List<ResolvedValueArgument> valueArguments = new ArrayList<ResolvedValueArgument>(params);
List<ValueParameterDescriptor> valueParameters = new ArrayList<ValueParameterDescriptor>(params);
@@ -1375,33 +1366,33 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
argumentGenerator.generate(valueArguments);
}
ConstructorDescriptor constructorDescriptor = bindingContext.get(CONSTRUCTOR, expression.getObjectDeclaration());
assert constructorDescriptor != null : "Unresolved constructor: " + expression.getText();
JvmMethodSignature constructor = typeMapper.mapSignature(constructorDescriptor);
v.invokespecial(type.getInternalName(), "<init>", constructor.getAsmMethod().getDescriptor(), false);
return StackValue.onStack(type);
}
public void pushClosureOnStack(@NotNull ClassDescriptor classDescriptor, boolean putThis, @NotNull CallGenerator callGenerator) {
CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor);
public void pushClosureOnStack(
@Nullable CalculatedClosure closure,
boolean ignoreThisAndReceiver,
@NotNull CallGenerator callGenerator
) {
if (closure == null) return;
int paramIndex = 0;
if (putThis) {
if (!ignoreThisAndReceiver) {
ClassDescriptor captureThis = closure.getCaptureThis();
if (captureThis != null) {
StackValue thisOrOuter = generateThisOrOuter(captureThis, false);
assert !isPrimitive(thisOrOuter.type) : "This or outer should be non primitive: " + thisOrOuter.type;
callGenerator.putCapturedValueOnStack(thisOrOuter, thisOrOuter.type, paramIndex++);
}
}
JetType captureReceiver = closure.getCaptureReceiverType();
if (captureReceiver != null) {
Type asmType = typeMapper.mapType(captureReceiver);
StackValue.Local capturedReceiver = StackValue.local(AsmUtil.getReceiverIndex(context, context.getContextDescriptor()), asmType);
callGenerator.putCapturedValueOnStack(capturedReceiver, capturedReceiver.type, paramIndex++);
JetType captureReceiver = closure.getCaptureReceiverType();
if (captureReceiver != null) {
Type asmType = typeMapper.mapType(captureReceiver);
StackValue.Local capturedReceiver = StackValue.local(AsmUtil.getReceiverIndex(context, context.getContextDescriptor()), asmType);
callGenerator.putCapturedValueOnStack(capturedReceiver, capturedReceiver.type, paramIndex++);
}
}
for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closure.getCaptureVariables().entrySet()) {
@@ -1415,11 +1406,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
ResolvedCall<ConstructorDescriptor> superCall = closure.getSuperCall();
if (superCall != null) {
pushClosureOnStack(
superCall.getResultingDescriptor().getContainingDeclaration(),
putThis && closure.getCaptureThis() == null,
callGenerator
);
MutableClosure superClosure = bindingContext.get(CLOSURE, superCall.getResultingDescriptor().getContainingDeclaration());
pushClosureOnStack(superClosure, ignoreThisAndReceiver, callGenerator);
}
}
@@ -1435,12 +1423,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
StackValue answer = StackValue.none();
for (Iterator<JetElement> iterator = statements.iterator(); iterator.hasNext(); ) {
JetElement possiblyLabeledStatement = iterator.next();
JetElement statement = possiblyLabeledStatement instanceof JetExpression
? JetPsiUtil.safeDeparenthesize((JetExpression) possiblyLabeledStatement, true)
: possiblyLabeledStatement;
JetElement statement = iterator.next();
if (statement instanceof JetNamedDeclaration) {
JetNamedDeclaration declaration = (JetNamedDeclaration) statement;
@@ -1469,7 +1452,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
v.mark(labelBeforeLastExpression);
}
StackValue result = isExpression ? gen(possiblyLabeledStatement) : genStatement(possiblyLabeledStatement);
StackValue result = isExpression ? gen(statement) : genStatement(statement);
if (!iterator.hasNext()) {
answer = result;
@@ -1748,6 +1731,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (descriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.OBJECT$.getInstances(state.getProject())) {
StackValue result = extension.apply(receiver, resolvedCall, new ExpressionCodegenExtension.Context(typeMapper, v));
if (result != null) return result;
}
boolean directToField =
expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL;
JetExpression r = getReceiverForSelector(expression);
@@ -1898,7 +1887,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
boolean isBackingFieldInAnotherClass = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
boolean isStatic = DescriptorUtils.isStaticDeclaration(propertyDescriptor);
boolean isSuper = superExpression != null;
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null;
JetType delegateType = getPropertyDelegateType(propertyDescriptor, bindingContext);
boolean isDelegatedProperty = delegateType != null;
@@ -2232,7 +2221,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
boolean isInline = state.isInlineEnabled() &&
descriptor instanceof SimpleFunctionDescriptor &&
((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline();
if (!isInline) return defaultCallGenerator;
SimpleFunctionDescriptor original = DescriptorUtils.unwrapFakeOverride((SimpleFunctionDescriptor) descriptor.getOriginal());
@@ -2283,7 +2271,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@NotNull
private StackValue generateReceiver(@NotNull CallableDescriptor descriptor) {
return context.generateReceiver(descriptor, state, false);
if (context.getCallableDescriptorWithReceiver() == descriptor) {
return context.getReceiverExpression(typeMapper);
}
return context.lookupInContext(descriptor, StackValue.local(0, OBJECT_TYPE), state, false);
}
// SCRIPT: generate script, move to ScriptingUtil
@@ -2494,7 +2486,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
PackageFragmentDescriptor containingPackage = (PackageFragmentDescriptor) descriptor.getContainingDeclaration();
String packageClassInternalName = PackageClassUtils.getPackageClassInternalName(containingPackage.getFqName());
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
Method factoryMethod;
if (receiverParameter != null) {
Type[] parameterTypes = new Type[] {JAVA_STRING_TYPE, K_PACKAGE_IMPL_TYPE, getType(Class.class)};
@@ -2571,21 +2563,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetCallExpression fakeExpression = constructFakeFunctionCall();
final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments();
final ReceiverValue dispatchReceiver = computeAndSaveReceiver(signature, codegen, referencedFunction.getDispatchReceiverParameter());
final ReceiverValue extensionReceiver = computeAndSaveReceiver(signature, codegen, referencedFunction.getExtensionReceiverParameter());
final ReceiverValue thisObject = computeAndSaveReceiver(signature, codegen, referencedFunction.getExpectedThisObject());
final ReceiverValue extensionReceiver = computeAndSaveReceiver(signature, codegen, referencedFunction.getReceiverParameter());
computeAndSaveArguments(fakeArguments, codegen);
ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) {
@NotNull
@Override
public ReceiverValue getExtensionReceiver() {
public ReceiverValue getReceiverArgument() {
return extensionReceiver;
}
@NotNull
@Override
public ReceiverValue getDispatchReceiver() {
return dispatchReceiver;
public ReceiverValue getThisObject() {
return thisObject;
}
@NotNull
@@ -3007,10 +2999,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
StackValue value = gen(lhs); // receiver
value.dupReceiver(v); // receiver receiver
value.put(lhsType, v); // receiver lhs
Type returnType = typeMapper.mapType(descriptor);
((IntrinsicMethod) callable).generate(this, v, returnType, expression,
((IntrinsicMethod) callable).generate(this, v, typeMapper.mapType(descriptor), expression,
Collections.singletonList(expression.getRight()), StackValue.onStack(lhsType));
value.store(returnType, v);
value.store(lhsType, v);
return StackValue.none();
}
else {
@@ -3054,8 +3045,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetExpression left = binaryExpression.getLeft();
JetExpression right = binaryExpression.getRight();
Type leftType = expressionType(left);
Type rightType = expressionType(right);
if (leftType.equals(JAVA_STRING_TYPE)) {
if (leftType.equals(JAVA_STRING_TYPE) && rightType.equals(JAVA_STRING_TYPE)) {
invokeAppend(left);
invokeAppend(right);
return;
@@ -3084,25 +3076,24 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override
public StackValue visitPrefixExpression(@NotNull JetPrefixExpression expression, StackValue receiver) {
DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
CallableDescriptor op = resolvedCall.getResultingDescriptor();
assert op instanceof FunctionDescriptor || originalOperation == null : String.valueOf(op);
DeclarationDescriptor op = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
assert op instanceof FunctionDescriptor : String.valueOf(op);
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
if (callable instanceof IntrinsicMethod) {
Type returnType = typeMapper.mapType(op);
Type returnType = typeMapper.mapType((FunctionDescriptor) op);
((IntrinsicMethod) callable).generate(this, v, returnType, expression,
Collections.singletonList(expression.getBaseExpression()), receiver);
return StackValue.onStack(returnType);
}
DeclarationDescriptor cls = op.getContainingDeclaration();
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
if (isPrimitiveNumberClassDescriptor(cls) || !(originalOperation.getName().asString().equals("inc") || originalOperation.getName().asString().equals("dec"))) {
if (isPrimitiveNumberClassDescriptor(cls) || !(op.getName().asString().equals("inc") || op.getName().asString().equals("dec"))) {
return invokeFunction(resolvedCall, receiver);
}
CallableMethod callableMethod = (CallableMethod) callable;
StackValue value = gen(expression.getBaseExpression());
value.dupReceiver(v);
@@ -3110,8 +3101,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type type = expressionType(expression.getBaseExpression());
value.put(type, v);
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(type));
value.store(result.type, v);
callableMethod.invokeWithNotNullAssertion(v, state, resolvedCall);
value.store(callableMethod.getReturnType(), v);
value.put(type, v);
return StackValue.onStack(type);
}
@@ -3132,33 +3124,29 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return StackValue.onStack(base.type);
}
DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
String originalOperationName = originalOperation != null ? originalOperation.getName().asString() : null;
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
DeclarationDescriptor op = resolvedCall.getResultingDescriptor();
if (!(op instanceof FunctionDescriptor) || originalOperation == null) {
throw new UnsupportedOperationException("Don't know how to generate this postfix expression: " + originalOperationName + " " + op);
DeclarationDescriptor op = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
if (!(op instanceof FunctionDescriptor)) {
throw new UnsupportedOperationException("Don't know how to generate this postfix expression: " + op);
}
Type asmResultType = expressionType(expression);
Type asmBaseType = expressionType(expression.getBaseExpression());
Type asmType = expressionType(expression);
DeclarationDescriptor cls = op.getContainingDeclaration();
int increment;
if (originalOperationName.equals("inc")) {
if (op.getName().asString().equals("inc")) {
increment = 1;
}
else if (originalOperationName.equals("dec")) {
else if (op.getName().asString().equals("dec")) {
increment = -1;
}
else {
throw new UnsupportedOperationException("Unsupported postfix operation: " + originalOperationName + " " + op);
throw new UnsupportedOperationException("Unsupported postfix operation: " + op);
}
boolean isPrimitiveNumberClassDescriptor = isPrimitiveNumberClassDescriptor(cls);
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
if (isPrimitiveNumberClassDescriptor) {
JetExpression operand = expression.getBaseExpression();
if (operand instanceof JetReferenceExpression && asmResultType == Type.INT_TYPE) {
if (operand instanceof JetReferenceExpression && asmType == Type.INT_TYPE) {
int index = indexOfLocal((JetReferenceExpression) operand);
if (index >= 0) {
return StackValue.postIncrement(index, increment);
@@ -3175,17 +3163,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
pushReceiverAndValueViaDup(value, type); // receiver and new value
Type storeType;
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
genIncrement(asmResultType, increment, v);
if (isPrimitiveNumberClassDescriptor) {
genIncrement(asmType, increment, v);
storeType = type;
}
else {
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(type));
storeType = result.type;
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
CallableMethod callableMethod = (CallableMethod) callable;
callableMethod.invokeWithNotNullAssertion(v, state, resolvedCall);
storeType = callableMethod.getReturnType();
}
value.store(storeType, v);
return StackValue.onStack(asmResultType); // old value
return StackValue.onStack(asmType); // old value
}
private void pushReceiverAndValueViaDup(StackValue value, Type type) {
@@ -3332,15 +3323,17 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
ConstructorDescriptor constructor = (ConstructorDescriptor) resolvedCall.getResultingDescriptor();
ReceiverParameterDescriptor dispatchReceiver = constructor.getDispatchReceiverParameter();
if (dispatchReceiver != null) {
Type receiverType = typeMapper.mapType(dispatchReceiver.getType());
generateReceiverValue(resolvedCall.getDispatchReceiver(), receiverType);
ReceiverParameterDescriptor expectedThisObject = constructor.getExpectedThisObject();
if (expectedThisObject != null) {
Type receiverType = typeMapper.mapType(expectedThisObject.getType());
generateReceiverValue(resolvedCall.getThisObject(), receiverType);
}
// Resolved call to local class constructor doesn't have dispatchReceiver, so we need to generate closure on stack
MutableClosure closure = bindingContext.get(CLOSURE, constructor.getContainingDeclaration());
// Resolved call to local class constructor doesn't have expectedThisObject, so we need to generate closure on stack
// See StackValue.receiver for more info
pushClosureOnStack(constructor.getContainingDeclaration(), dispatchReceiver == null, defaultCallGenerator);
pushClosureOnStack(closure, expectedThisObject != null, defaultCallGenerator);
ConstructorDescriptor originalOfSamAdapter = (ConstructorDescriptor) SamCodegenUtil.getOriginalIfSamAdapter(constructor);
CallableMethod method = typeMapper.mapToCallableMethod(originalOfSamAdapter == null ? constructor : originalOfSamAdapter);
@@ -3477,7 +3470,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
else {
gen(array, arrayType); // intrinsic method
int index = operationDescriptor.getExtensionReceiverParameter() != null ? 1 : 0;
int index = operationDescriptor.getReceiverParameter() != null ? 1 : 0;
for (JetExpression jetExpression : expression.getIndexExpressions()) {
gen(jetExpression, argumentTypes[index]);
@@ -3501,7 +3494,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
public StackValue visitThisExpression(@NotNull JetThisExpression expression, StackValue receiver) {
DeclarationDescriptor descriptor = bindingContext.get(REFERENCE_TARGET, expression.getInstanceReference());
if (descriptor instanceof ClassDescriptor) {
//TODO rewrite with context.lookupInContext()
return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor, false, true);
}
if (descriptor instanceof CallableDescriptor) {
@@ -3702,7 +3694,7 @@ The "returned" value of try expression with no finally is either the last expres
@Override
public StackValue visitIsExpression(@NotNull JetIsExpression expression, StackValue receiver) {
StackValue match = StackValue.expression(OBJECT_TYPE, expression.getLeftHandSide(), this);
return generateIsCheck(match, expression.getTypeReference(), expression.isNegated());
return generateIsCheck(match, expression.getTypeRef(), expression.isNegated());
}
private StackValue generateExpressionMatch(StackValue expressionToMatch, JetExpression patternExpression) {
@@ -3854,7 +3846,7 @@ The "returned" value of try expression with no finally is either the last expres
StackValue.Local match = subjectLocal == -1 ? null : StackValue.local(subjectLocal, subjectType);
if (condition instanceof JetWhenConditionIsPattern) {
JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition;
return generateIsCheck(match, patternCondition.getTypeReference(), patternCondition.isNegated());
return generateIsCheck(match, patternCondition.getTypeRef(), patternCondition.isNegated());
}
else if (condition instanceof JetWhenConditionWithExpression) {
JetExpression patternExpression = ((JetWhenConditionWithExpression) condition).getExpression();

View File

@@ -36,10 +36,10 @@ import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.ResolvePackage;
import org.jetbrains.jet.lang.resolve.annotations.AnnotationsPackage;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
import org.jetbrains.jet.lang.resolve.constants.ArrayValue;
@@ -50,8 +50,6 @@ import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.Approximation;
import org.jetbrains.jet.lang.types.TypesPackage;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.Label;
@@ -238,7 +236,7 @@ public class FunctionCodegen extends ParentCodegenAware {
}
if (kind == JvmMethodParameterKind.RECEIVER) {
ReceiverParameterDescriptor receiver = functionDescriptor.getExtensionReceiverParameter();
ReceiverParameterDescriptor receiver = functionDescriptor.getReceiverParameter();
nullableType = receiver == null || receiver.getType().isNullable();
}
else {
@@ -273,12 +271,12 @@ public class FunctionCodegen extends ParentCodegenAware {
@Nullable
private static Type getThisTypeForFunction(@NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context, @NotNull JetTypeMapper typeMapper) {
ReceiverParameterDescriptor dispatchReceiver = functionDescriptor.getDispatchReceiverParameter();
ReceiverParameterDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
if (functionDescriptor instanceof ConstructorDescriptor) {
return typeMapper.mapType(functionDescriptor);
}
else if (dispatchReceiver != null) {
return typeMapper.mapType(dispatchReceiver.getType());
else if (expectedThisObject != null) {
return typeMapper.mapType(expectedThisObject.getType());
}
else if (isFunctionLiteral(functionDescriptor) || isLocalNamedFun(functionDescriptor)) {
return typeMapper.mapType(context.getThisDescriptor());
@@ -485,7 +483,7 @@ public class FunctionCodegen extends ParentCodegenAware {
}
@NotNull
public static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull final JetTypeMapper mapper) {
private static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull final JetTypeMapper mapper) {
AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(new FqName("kotlin.throws"));
if (annotation == null) return ArrayUtil.EMPTY_STRING_ARRAY;
@@ -517,10 +515,9 @@ public class FunctionCodegen extends ParentCodegenAware {
@NotNull GenerationState state,
@NotNull CallableMethod method,
@NotNull ConstructorDescriptor constructorDescriptor,
@NotNull ClassBuilder classBuilder,
@NotNull JetClassOrObject classOrObject
@NotNull ClassBuilder classBuilder
) {
if (!isEmptyConstructorNeeded(state.getBindingContext(), constructorDescriptor, classOrObject)) {
if (!isDefaultConstructorNeeded(state.getBindingContext(), constructorDescriptor)) {
return;
}
int flags = getVisibilityAccessFlag(constructorDescriptor);
@@ -554,7 +551,7 @@ public class FunctionCodegen extends ParentCodegenAware {
String desc = JetTypeMapper.getDefaultDescriptor(method.getAsmMethod(), false);
v.invokespecial(methodOwner.getInternalName(), "<init>", desc, false);
v.areturn(Type.VOID_TYPE);
endVisit(mv, "default constructor for " + methodOwner.getInternalName(), classOrObject);
endVisit(mv, "default constructor for " + methodOwner.getInternalName(), null);
}
void generateDefaultIfNeeded(
@@ -743,15 +740,9 @@ public class FunctionCodegen extends ParentCodegenAware {
return needed;
}
private static boolean isEmptyConstructorNeeded(
@NotNull BindingContext context,
@NotNull ConstructorDescriptor constructorDescriptor,
@NotNull JetClassOrObject classOrObject
) {
private static boolean isDefaultConstructorNeeded(@NotNull BindingContext context, @NotNull ConstructorDescriptor constructorDescriptor) {
ClassDescriptor classDescriptor = constructorDescriptor.getContainingDeclaration();
if (classOrObject.isLocal()) return false;
if (CodegenBinding.canHaveOuter(context, classDescriptor)) return false;
if (classDescriptor.getVisibility() == Visibilities.PRIVATE ||
@@ -800,20 +791,21 @@ public class FunctionCodegen extends ParentCodegenAware {
}
public void genDelegate(FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenDescriptor, StackValue field) {
genDelegate(functionDescriptor, overriddenDescriptor.getOriginal(), (ClassDescriptor) overriddenDescriptor.getContainingDeclaration(), field
genDelegate(functionDescriptor, (ClassDescriptor) overriddenDescriptor.getContainingDeclaration(), field,
typeMapper.mapSignature(functionDescriptor),
typeMapper.mapSignature(overriddenDescriptor.getOriginal())
);
}
public void genDelegate(
final FunctionDescriptor delegateFunction,
final FunctionDescriptor delegatedTo,
FunctionDescriptor functionDescriptor,
final ClassDescriptor toClass,
final StackValue field
final StackValue field,
final JvmMethodSignature jvmDelegateMethodSignature,
final JvmMethodSignature jvmDelegatingMethodSignature
) {
final JvmMethodSignature jvmDelegateMethodSignature = typeMapper.mapSignature(delegateFunction);
final JvmMethodSignature jvmDelegateToMethodSignature = typeMapper.mapSignature(delegatedTo);
generateMethod(
OtherOrigin(delegateFunction), jvmDelegateMethodSignature, delegateFunction,
OtherOrigin(functionDescriptor), jvmDelegateMethodSignature, functionDescriptor,
new FunctionGenerationStrategy() {
@Override
public void generateBody(
@@ -823,11 +815,11 @@ public class FunctionCodegen extends ParentCodegenAware {
@NotNull MethodContext context,
@NotNull MemberCodegen<?> parentCodegen
) {
Method delegateToMethod = jvmDelegateToMethodSignature.getAsmMethod();
Method overriddenMethod = jvmDelegatingMethodSignature.getAsmMethod();
Method delegateMethod = jvmDelegateMethodSignature.getAsmMethod();
Type[] argTypes = delegateMethod.getArgumentTypes();
Type[] originalArgTypes = delegateToMethod.getArgumentTypes();
Type[] originalArgTypes = overriddenMethod.getArgumentTypes();
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, OBJECT_TYPE);
@@ -840,22 +832,13 @@ public class FunctionCodegen extends ParentCodegenAware {
String internalName = typeMapper.mapType(toClass).getInternalName();
if (toClass.getKind() == ClassKind.TRAIT) {
iv.invokeinterface(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor());
iv.invokeinterface(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
}
else {
iv.invokevirtual(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor());
iv.invokevirtual(internalName, overriddenMethod.getName(), overriddenMethod.getDescriptor());
}
StackValue stackValue = AsmUtil.genNotNullAssertions(
state,
StackValue.onStack(delegateToMethod.getReturnType()),
TypesPackage.getApproximationTo(
delegatedTo.getReturnType(),
delegateFunction.getReturnType(),
new Approximation.DataFlowExtras.OnlyMessage(delegatedTo.getName() + "(...)"))
);
stackValue.put(delegateMethod.getReturnType(), iv);
StackValue.onStack(overriddenMethod.getReturnType()).put(delegateMethod.getReturnType(), iv);
iv.areturn(delegateMethod.getReturnType());
}

View File

@@ -24,9 +24,9 @@ import kotlin.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.backend.common.CodegenUtil;
import org.jetbrains.jet.backend.common.CodegenUtilKt;
import org.jetbrains.jet.backend.common.DataClassMethodGenerator;
import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.codegen.bridges.BridgesPackage;
import org.jetbrains.jet.codegen.context.*;
import org.jetbrains.jet.codegen.signature.BothSignatureWriter;
import org.jetbrains.jet.codegen.state.GenerationState;
@@ -50,14 +50,13 @@ import org.jetbrains.jet.lang.resolve.calls.model.VarargValueArgument;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaCallableMemberDescriptor;
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmClassSignature;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
@@ -427,7 +426,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateFunctionsForDataClasses();
new CollectionStubMethodGenerator(state, descriptor, functionCodegen, v).generate();
generateBuiltinMethodStubs();
generateToArray();
@@ -485,7 +484,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.load(0, classAsmType);
iv.invokestatic("kotlin/jvm/internal/CollectionToArray", "toArray", "(Ljava/util/Collection;)[Ljava/lang/Object;", false);
iv.areturn(Type.getType("[Ljava/lang/Object;"));
iv.areturn(Type.getObjectType("[Ljava/lang/Object;"));
FunctionCodegen.endVisit(mv, "toArray", myClass);
}
@@ -499,17 +498,98 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
mv.visitCode();
iv.load(0, classAsmType);
iv.load(1, Type.getType("[Ljava/lang/Object;"));
iv.load(1, Type.getObjectType("[Ljava/lang/Object;"));
iv.invokestatic("kotlin/jvm/internal/CollectionToArray", "toArray",
"(Ljava/util/Collection;[Ljava/lang/Object;)[Ljava/lang/Object;", false);
iv.areturn(Type.getType("[Ljava/lang/Object;"));
iv.areturn(Type.getObjectType("[Ljava/lang/Object;"));
FunctionCodegen.endVisit(mv, "toArray", myClass);
}
}
}
private class MethodStubGenerator {
private final Set<String> generatedSignatures = new HashSet<String>();
public void generate(
@NotNull String name,
@NotNull String desc,
@NotNull ClassifierDescriptor returnedClassifier,
@NotNull ClassifierDescriptor... valueParameterClassifiers
) {
// avoid generating same signature twice
if (!generatedSignatures.add(name + desc)) return;
if (CodegenUtil.getDeclaredFunctionByRawSignature(
descriptor, Name.identifier(name), returnedClassifier, valueParameterClassifiers) == null) {
int access = descriptor.getKind() == ClassKind.TRAIT ?
ACC_PUBLIC | ACC_ABSTRACT :
ACC_PUBLIC;
MethodVisitor mv = v.newMethod(NO_ORIGIN, access, name, desc, null, null);
if (descriptor.getKind() != ClassKind.TRAIT) {
mv.visitCode();
genThrow(new InstructionAdapter(mv), "java/lang/UnsupportedOperationException", "Mutating immutable collection");
FunctionCodegen.endVisit(mv, "built-in stub for " + name + desc, null);
}
}
}
}
private void generateBuiltinMethodStubs() {
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
MethodStubGenerator methodStubs = new MethodStubGenerator();
if (isSubclass(descriptor, builtIns.getCollection())) {
ClassifierDescriptor classifier = getSubstituteForTypeParameterOf(builtIns.getCollection(), 0);
methodStubs.generate("add", "(Ljava/lang/Object;)Z", builtIns.getBoolean(), classifier);
methodStubs.generate("remove", "(Ljava/lang/Object;)Z", builtIns.getBoolean(), builtIns.getAny());
methodStubs.generate("addAll", "(Ljava/util/Collection;)Z", builtIns.getBoolean(), builtIns.getCollection());
methodStubs.generate("removeAll", "(Ljava/util/Collection;)Z", builtIns.getBoolean(), builtIns.getCollection());
methodStubs.generate("retainAll", "(Ljava/util/Collection;)Z", builtIns.getBoolean(), builtIns.getCollection());
methodStubs.generate("clear", "()V", builtIns.getUnit());
}
if (isSubclass(descriptor, builtIns.getList())) {
ClassifierDescriptor classifier = getSubstituteForTypeParameterOf(builtIns.getList(), 0);
methodStubs.generate("set", "(ILjava/lang/Object;)Ljava/lang/Object;", classifier, builtIns.getInt(), classifier);
methodStubs.generate("add", "(ILjava/lang/Object;)V", builtIns.getUnit(), builtIns.getInt(), classifier);
methodStubs.generate("remove", "(I)Ljava/lang/Object;", classifier, builtIns.getInt());
}
if (isSubclass(descriptor, builtIns.getMap())) {
ClassifierDescriptor keyClassifier = getSubstituteForTypeParameterOf(builtIns.getMap(), 0);
ClassifierDescriptor valueClassifier = getSubstituteForTypeParameterOf(builtIns.getMap(), 1);
methodStubs.generate("put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", valueClassifier, keyClassifier,
valueClassifier);
methodStubs.generate("remove", "(Ljava/lang/Object;)Ljava/lang/Object;", valueClassifier, builtIns.getAny());
methodStubs.generate("putAll", "(Ljava/util/Map;)V", builtIns.getUnit(), builtIns.getMap());
methodStubs.generate("clear", "()V", builtIns.getUnit());
}
if (isSubclass(descriptor, builtIns.getMapEntry())) {
ClassifierDescriptor valueClassifier = getSubstituteForTypeParameterOf(builtIns.getMapEntry(), 1);
methodStubs.generate("setValue", "(Ljava/lang/Object;)Ljava/lang/Object;", valueClassifier, valueClassifier);
}
if (isSubclass(descriptor, builtIns.getIterator())) {
methodStubs.generate("remove", "()V", builtIns.getUnit());
}
}
@NotNull
private ClassifierDescriptor getSubstituteForTypeParameterOf(@NotNull ClassDescriptor trait, int index) {
TypeParameterDescriptor listTypeParameter = trait.getTypeConstructor().getParameters().get(index);
TypeSubstitutor deepSubstitutor = SubstitutionUtils.buildDeepSubstitutor(descriptor.getDefaultType());
TypeProjection substitute = deepSubstitutor.substitute(new TypeProjectionImpl(listTypeParameter.getDefaultType()));
assert substitute != null : "Couldn't substitute: " + descriptor;
ClassifierDescriptor classifier = substitute.getType().getConstructor().getDeclarationDescriptor();
assert classifier != null : "No classifier: " + substitute.getType();
return classifier;
}
private void generateFunctionsForDataClasses() {
if (!KotlinBuiltIns.getInstance().isData(descriptor)) return;
@@ -564,23 +644,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
else {
iv.invokestatic("java/util/Arrays", "equals",
"(" + asmType.getDescriptor() + asmType.getDescriptor() + ")Z", false);
"([" + elementType.getDescriptor() + "[" + elementType.getDescriptor() + ")Z", false);
}
iv.ifeq(ne);
}
else if (asmType.getSort() == Type.FLOAT) {
iv.invokestatic("java/lang/Float", "compare", "(FF)I", false);
iv.ifne(ne);
}
else if (asmType.getSort() == Type.DOUBLE) {
iv.invokestatic("java/lang/Double", "compare", "(DD)I", false);
iv.ifne(ne);
}
else {
StackValue value = genEqualsForExpressionsOnStack(iv, JetTokens.EQEQ, asmType, asmType);
value.put(Type.BOOLEAN_TYPE, iv);
iv.ifeq(ne);
}
iv.ifeq(ne);
}
iv.mark(eq);
@@ -1080,7 +1152,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
DefaultParameterValueLoader.DEFAULT, null);
CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor);
FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v, myClass);
FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v);
if (isClassObject(descriptor)) {
context.recordSyntheticAccessorIfNeeded(constructorDescriptor, bindingContext);
@@ -1214,15 +1286,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
JetExpression expression = ((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
PropertyDescriptor propertyDescriptor = CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext);
ClassDescriptor superClassDescriptor = getSuperClass(specifier);
if (CodegenUtil.isFinalPropertyWithBackingField(propertyDescriptor, bindingContext)) {
result.addField((JetDelegatorByExpressionSpecifier) specifier, propertyDescriptor);
}
else {
JetType expressionType = state.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
Type asmType =
expressionType != null ? typeMapper.mapType(expressionType) : typeMapper.mapType(getSuperClass(specifier));
result.addField((JetDelegatorByExpressionSpecifier) specifier, asmType, "$delegate_" + n);
result.addField((JetDelegatorByExpressionSpecifier) specifier, typeMapper.mapType(superClassDescriptor), "$delegate_" + n);
}
n++;
}
@@ -1287,12 +1357,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getInstanceReference());
assert descriptor instanceof CallableDescriptor ||
descriptor instanceof ClassDescriptor : "'This' reference target should be class or callable descriptor but was " + descriptor;
if (descriptor instanceof ClassDescriptor) {
context.lookupInContext(descriptor, StackValue.local(0, OBJECT_TYPE), state, true);
}
if (descriptor instanceof CallableDescriptor) {
constructorContext.generateReceiver((CallableDescriptor) descriptor, state, true);
if (context.getCallableDescriptorWithReceiver() != descriptor) {
context.lookupInContext(descriptor, null, state, true);
}
}
};
@@ -1319,18 +1385,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
if (superCall != null) {
ResolvedCall<?> resolvedCall = CallUtilPackage.getResolvedCallWithAssert(superCall, bindingContext);
ClassDescriptor superClass = ((ConstructorDescriptor) resolvedCall.getResultingDescriptor()).getContainingDeclaration();
if (superClass.isInner()) {
constructorContext.lookupInContext(superClass.getContainingDeclaration(), StackValue.local(0, OBJECT_TYPE), state, true);
}
if (!isAnonymousObject(descriptor)) {
JetValueArgumentList argumentList = superCall.getValueArgumentList();
if (argumentList != null) {
argumentList.accept(visitor);
}
if (superCall != null && !isAnonymousObject(descriptor)) {
JetValueArgumentList argumentList = superCall.getValueArgumentList();
if (argumentList != null) {
argumentList.accept(visitor);
}
}
}
@@ -1351,11 +1409,32 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateTraitMethods() {
if (JetPsiUtil.isTrait(myClass)) return;
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getTraitMethods(descriptor).entrySet()) {
FunctionDescriptor traitFun = entry.getKey();
//skip java 8 default methods
if (!(traitFun instanceof JavaCallableMemberDescriptor)) {
generateDelegationToTraitImpl(traitFun, entry.getValue());
for (DeclarationDescriptor declaration : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
if (!(declaration instanceof CallableMemberDescriptor)) continue;
CallableMemberDescriptor inheritedMember = (CallableMemberDescriptor) declaration;
CallableMemberDescriptor traitMember = BridgesPackage.findTraitImplementation(inheritedMember);
if (traitMember == null) continue;
assert traitMember.getModality() != Modality.ABSTRACT : "Cannot delegate to abstract trait method: " + inheritedMember;
// inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here
// with traitMember's modality
CallableMemberDescriptor copy =
inheritedMember.copy(inheritedMember.getContainingDeclaration(), traitMember.getModality(), Visibilities.PUBLIC,
CallableMemberDescriptor.Kind.DECLARATION, true);
if (traitMember instanceof SimpleFunctionDescriptor) {
generateDelegationToTraitImpl((FunctionDescriptor) traitMember, (FunctionDescriptor) copy);
}
else if (traitMember instanceof PropertyDescriptor) {
for (PropertyAccessorDescriptor traitAccessor : ((PropertyDescriptor) traitMember).getAccessors()) {
for (PropertyAccessorDescriptor inheritedAccessor : ((PropertyDescriptor) copy).getAccessors()) {
if (inheritedAccessor.getClass() == traitAccessor.getClass()) { // same accessor kind
generateDelegationToTraitImpl(traitAccessor, inheritedAccessor);
}
}
}
}
}
}
@@ -1429,29 +1508,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (JvmMethodParameterSignature parameter : parameters) {
if (superIndex >= superParameters.size()) break;
JvmMethodParameterKind superKind = superParameters.get(superIndex).getKind();
JvmMethodParameterKind kind = parameter.getKind();
Type type = parameter.getAsmType();
if (superKind == JvmMethodParameterKind.VALUE && kind == JvmMethodParameterKind.SUPER_CALL_PARAM) {
// Stop when we reach the actual value parameters present in the code; they will be generated via ResolvedCall below
// Stop when we reach the actual value parameters present in the code; they will be generated via ResolvedCall below
if (superParameters.get(superIndex).getKind() == JvmMethodParameterKind.VALUE &&
kind == JvmMethodParameterKind.SUPER_CALL_PARAM) {
break;
}
if (superKind == JvmMethodParameterKind.OUTER) {
assert kind == JvmMethodParameterKind.OUTER || kind == JvmMethodParameterKind.SUPER_CALL_PARAM :
String.format("Non-outer parameter incorrectly mapped to outer for %s: %s vs %s",
constructorDescriptor, parameters, superParameters);
// Super constructor requires OUTER parameter, but our OUTER instance may be different from what is expected by the super
// constructor. We need to traverse our outer classes from the bottom up, to find the needed class
// TODO: isSuper should be "true" but this makes some tests on inner classes extending outer fail
// See innerExtendsOuter.kt, semantics of inner classes extending their outer should be changed to be as in Java
ClassDescriptor outerForSuper = (ClassDescriptor) superConstructor.getContainingDeclaration().getContainingDeclaration();
StackValue outer = codegen.generateThisOrOuter(outerForSuper, false);
outer.put(outer.type, codegen.v);
superIndex++;
}
else if (kind == JvmMethodParameterKind.SUPER_CALL_PARAM || kind == JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL) {
if (kind == JvmMethodParameterKind.SUPER_CALL_PARAM || kind == JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL ||
(kind == JvmMethodParameterKind.OUTER && superConstructor.getContainingDeclaration().isInner())) {
iv.load(offset, type);
superIndex++;
}
@@ -1598,9 +1665,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((JetDelegatorByExpressionSpecifier) specifier);
generateDelegateField(field);
JetExpression delegateExpression = ((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
JetType delegateExpressionType = state.getBindingContext().get(BindingContext.EXPRESSION_TYPE, delegateExpression);
generateDelegates(getSuperClass(specifier), delegateExpressionType, field);
generateDelegates(getSuperClass(specifier), field);
}
}
}
@@ -1612,17 +1677,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
fieldInfo.name, fieldInfo.type.getDescriptor(), /*TODO*/null, null);
}
protected void generateDelegates(ClassDescriptor toTrait, JetType delegateExpressionType, DelegationFieldsInfo.Field field) {
for (Map.Entry<CallableMemberDescriptor, CallableDescriptor> entry : CodegenUtilKt.getDelegates(descriptor, toTrait, delegateExpressionType).entrySet()) {
protected void generateDelegates(ClassDescriptor toClass, DelegationFieldsInfo.Field field) {
for (Map.Entry<CallableMemberDescriptor, CallableMemberDescriptor> entry : CodegenUtil.getDelegates(descriptor, toClass).entrySet()) {
CallableMemberDescriptor callableMemberDescriptor = entry.getKey();
CallableDescriptor delegateTo = entry.getValue();
CallableMemberDescriptor overriddenDescriptor = entry.getValue();
if (callableMemberDescriptor instanceof PropertyDescriptor) {
propertyCodegen
.genDelegate((PropertyDescriptor) callableMemberDescriptor, (PropertyDescriptor) delegateTo, field.getStackValue());
.genDelegate((PropertyDescriptor) callableMemberDescriptor, (PropertyDescriptor) overriddenDescriptor, field.getStackValue());
}
else if (callableMemberDescriptor instanceof FunctionDescriptor) {
functionCodegen
.genDelegate((FunctionDescriptor) callableMemberDescriptor, (FunctionDescriptor) delegateTo, field.getStackValue());
.genDelegate((FunctionDescriptor) callableMemberDescriptor, (FunctionDescriptor) overriddenDescriptor, field.getStackValue());
}
}
}

View File

@@ -166,13 +166,13 @@ public class JvmCodegenUtil {
if (JetTypeMapper.isAccessor(property)) return false;
// Inline functions can't use direct access because a field may not be visible at the call site
if (context.isInlineFunction() && property.getVisibility() != Visibilities.PRIVATE) return false;
if (context.isInlineFunction()) return false;
// Only properties of the same class can be directly accessed, except when we are evaluating expressions in the debugger
if (!isCallInsideSameClassAsDeclared(property, context) && !isDebuggerContext(context)) return false;
// Delegated and extension properties have no backing fields
if (isDelegated || property.getExtensionReceiverParameter() != null) return false;
if (isDelegated || property.getReceiverParameter() != null) return false;
// Class object properties cannot be accessed directly because their backing fields are stored in the containing class
if (DescriptorUtils.isClassObject(property.getContainingDeclaration())) return false;
@@ -203,7 +203,7 @@ public class JvmCodegenUtil {
}
@Nullable
public static ClassDescriptor getDispatchReceiverParameterForConstructorCall(
public static ClassDescriptor getExpectedThisObjectForConstructorCall(
@NotNull ConstructorDescriptor descriptor,
@Nullable CalculatedClosure closure
) {
@@ -214,10 +214,10 @@ public class JvmCodegenUtil {
//for compilation against binaries
//TODO: It's best to use this code also for compilation against sources
// but sometimes structures that have dispatchReceiver (bug?) mapped to static classes
ReceiverParameterDescriptor dispatchReceiver = descriptor.getDispatchReceiverParameter();
if (dispatchReceiver != null) {
ClassDescriptor expectedThisClass = (ClassDescriptor) dispatchReceiver.getContainingDeclaration();
// but sometimes structures that have expectedThisObject (bug?) mapped to static classes
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
if (expectedThisObject != null) {
ClassDescriptor expectedThisClass = (ClassDescriptor) expectedThisObject.getContainingDeclaration();
if (!expectedThisClass.getKind().isSingleton()) {
return expectedThisClass;
}

View File

@@ -91,7 +91,7 @@ public class JvmRuntimeTypes {
@NotNull
public Collection<JetType> getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) {
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(2);
@@ -127,21 +127,21 @@ public class JvmRuntimeTypes {
@NotNull
public Collection<JetType> getSupertypesForFunctionReference(@NotNull FunctionDescriptor descriptor) {
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
ReceiverParameterDescriptor dispatchReceiver = descriptor.getDispatchReceiverParameter();
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(2);
ClassDescriptor classDescriptor;
JetType receiverType;
if (extensionReceiver != null) {
if (receiverParameter != null) {
classDescriptor = kExtensionFunctionImpl;
receiverType = extensionReceiver.getType();
receiverType = receiverParameter.getType();
typeArguments.add(new TypeProjectionImpl(receiverType));
}
else if (dispatchReceiver != null) {
else if (expectedThisObject != null) {
classDescriptor = kMemberFunctionImpl;
receiverType = dispatchReceiver.getType();
receiverType = expectedThisObject.getType();
typeArguments.add(new TypeProjectionImpl(receiverType));
}
else {
@@ -165,7 +165,7 @@ public class JvmRuntimeTypes {
receiverType,
ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType(),
extensionReceiver != null
receiverParameter != null
);
return Arrays.asList(kFunctionImplType, kFunctionType);

View File

@@ -366,7 +366,7 @@ public class PackageCodegen {
SmartList<PackageFragmentDescriptor> fragments = new SmartList<PackageFragmentDescriptor>();
for (JetFile file : files) {
PackageFragmentDescriptor fragment = state.getBindingContext().get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, file);
assert fragment != null : "package fragment is null for " + file + "\n" + file.getText();
assert fragment != null : "package fragment is null for " + file;
assert expectedFqName.equals(fragment.getFqName()) :
"expected package fq name: " + expectedFqName + ", actual: " + fragment.getFqName();

View File

@@ -39,8 +39,7 @@ class PlatformStaticGenerator(
Opcodes.ACC_STATIC or AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION),
asmMethod.getName()!!,
asmMethod.getDescriptor()!!,
typeMapper.mapSignature(descriptor).getGenericsSignature(),
FunctionCodegen.getThrownExceptions(descriptor, typeMapper))
null, null)
AnnotationCodegen.forMethod(methodVisitor, typeMapper)!!.genAnnotations(descriptor, asmMethod.getReturnType())
@@ -49,7 +48,7 @@ class PlatformStaticGenerator(
val iv = InstructionAdapter(methodVisitor)
val classDescriptor = descriptor.getContainingDeclaration() as ClassDescriptor
val singletonValue = StackValue.singleton(classDescriptor, typeMapper)!!
singletonValue.put(singletonValue.type, iv);
singletonValue.put(singletonValue.`type`, iv);
var index = 0;
for (paramType in asmMethod.getArgumentTypes()) {
iv.load(index, paramType);

View File

@@ -142,7 +142,7 @@ public class PropertyCodegen {
if (declaration == null) return true;
// Delegated or extension properties can only be referenced via accessors
if (declaration.hasDelegate() || declaration.getReceiverTypeReference() != null) return true;
if (declaration.hasDelegate() || declaration.getReceiverTypeRef() != null) return true;
// Class object properties always should have accessors, because their backing fields are moved/copied to the outer class
if (isClassObject(descriptor.getContainingDeclaration())) return true;
@@ -206,7 +206,7 @@ public class PropertyCodegen {
private void generateSyntheticMethodIfNeeded(@NotNull PropertyDescriptor descriptor) {
if (descriptor.getAnnotations().isEmpty()) return;
ReceiverParameterDescriptor receiver = descriptor.getExtensionReceiverParameter();
ReceiverParameterDescriptor receiver = descriptor.getReceiverParameter();
String name = JvmAbi.getSyntheticMethodNameForAnnotatedProperty(descriptor.getName());
String desc = receiver == null ? "()V" : "(" + typeMapper.mapType(receiver.getType()) + ")V";
@@ -395,7 +395,7 @@ public class PropertyCodegen {
v.areturn(type);
}
else if (callableDescriptor instanceof PropertySetterDescriptor) {
ReceiverParameterDescriptor receiverParameter = propertyDescriptor.getExtensionReceiverParameter();
ReceiverParameterDescriptor receiverParameter = propertyDescriptor.getReceiverParameter();
if (receiverParameter != null) {
paramCode += codegen.typeMapper.mapType(receiverParameter.getType()).getSize();
}
@@ -484,19 +484,21 @@ public class PropertyCodegen {
return JvmAbi.SETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.asString());
}
public void genDelegate(@NotNull PropertyDescriptor delegate, @NotNull PropertyDescriptor delegateTo, @NotNull StackValue field) {
ClassDescriptor toClass = (ClassDescriptor) delegateTo.getContainingDeclaration();
public void genDelegate(@NotNull PropertyDescriptor delegate, @NotNull PropertyDescriptor overridden, @NotNull StackValue field) {
ClassDescriptor toClass = (ClassDescriptor) overridden.getContainingDeclaration();
PropertyGetterDescriptor getter = delegate.getGetter();
if (getter != null) {
//noinspection ConstantConditions
functionCodegen.genDelegate(getter, delegateTo.getGetter().getOriginal(), toClass, field);
functionCodegen.genDelegate(getter, toClass, field,
typeMapper.mapSignature(getter), typeMapper.mapSignature(overridden.getGetter().getOriginal()));
}
PropertySetterDescriptor setter = delegate.getSetter();
if (setter != null) {
//noinspection ConstantConditions
functionCodegen.genDelegate(setter, delegateTo.getSetter().getOriginal(), toClass, field);
functionCodegen.genDelegate(setter, toClass, field,
typeMapper.mapSignature(setter), typeMapper.mapSignature(overridden.getSetter().getOriginal()));
}
}
}

View File

@@ -22,7 +22,6 @@ import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
@@ -150,21 +149,6 @@ public class SamWrapperCodegen {
.getFunctions(Name.identifier("invoke")).iterator().next().getOriginal();
StackValue functionField = StackValue.field(functionType, ownerType, FUNCTION_FIELD_NAME, false);
codegen.genDelegate(erasedInterfaceFunction, invokeFunction, functionField);
// generate sam bridges
// TODO: erasedInterfaceFunction is actually not an interface function, but function in generated class
SimpleFunctionDescriptor originalInterfaceErased = samType.getAbstractMethod().getOriginal();
SimpleFunctionDescriptorImpl descriptorForBridges = SimpleFunctionDescriptorImpl
.create(erasedInterfaceFunction.getContainingDeclaration(), erasedInterfaceFunction.getAnnotations(), originalInterfaceErased.getName(),
CallableMemberDescriptor.Kind.DECLARATION, erasedInterfaceFunction.getSource());
descriptorForBridges
.initialize(null, originalInterfaceErased.getDispatchReceiverParameter(), originalInterfaceErased.getTypeParameters(),
originalInterfaceErased.getValueParameters(), originalInterfaceErased.getReturnType(), Modality.OPEN,
originalInterfaceErased.getVisibility());
descriptorForBridges.addOverriddenDescriptor(originalInterfaceErased);
codegen.generateBridges(descriptorForBridges);
}
@NotNull

View File

@@ -313,7 +313,7 @@ public abstract class StackValue {
public static StackValue thisOrOuter(ExpressionCodegen codegen, ClassDescriptor descriptor, boolean isSuper, boolean isExplicit) {
// Coerce this/super for traits to support traits with required classes.
// Coerce explicit 'this' for the case when it is smart cast.
// Coerce explicit 'this' for the case when it is smartcasted.
// Do not coerce for other classes due to the 'protected' access issues (JVMS 7, 4.9.2 Structural Constraints).
boolean coerceType = descriptor.getKind() == ClassKind.TRAIT || (isExplicit && !isSuper);
return new ThisOuter(codegen, descriptor, isSuper, coerceType);
@@ -333,7 +333,7 @@ public abstract class StackValue {
ExpressionCodegen codegen,
@Nullable CallableMethod callableMethod
) {
if (resolvedCall.getDispatchReceiver().exists() || resolvedCall.getExtensionReceiver().exists() || isLocalFunCall(callableMethod)) {
if (resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists() || isLocalFunCall(callableMethod)) {
return new CallReceiver(resolvedCall, receiver, codegen, callableMethod, true);
}
return receiver;
@@ -358,10 +358,6 @@ public abstract class StackValue {
return field(info.getFieldType(), Type.getObjectType(info.getOwnerInternalName()), info.getFieldName(), true);
}
public static boolean couldSkipReceiverOnStaticCall(StackValue value) {
return value instanceof Local || value instanceof Constant;
}
private static class None extends StackValue {
public static final None INSTANCE = new None();
@@ -417,17 +413,10 @@ public abstract class StackValue {
put(type, v);
}
else if (depth == 1) {
int size = this.type.getSize();
if (size == 1) {
v.swap();
} else if (size == 2) {
v.dupX2();
v.pop();
} else {
if (type.getSize() != 1) {
throw new UnsupportedOperationException("don't know how to move type " + type + " to top of stack");
}
coerceTo(type, v);
v.swap();
}
else {
throw new UnsupportedOperationException("unsupported move-to-top depth " + depth);
@@ -517,7 +506,7 @@ public abstract class StackValue {
opcode = jumpIfFalse ? IFGT : IFLE;
}
else {
throw new UnsupportedOperationException("Don't know how to generate this condJump: " + opToken);
throw new UnsupportedOperationException("don't know how to generate this condjump");
}
if (operandType == Type.FLOAT_TYPE || operandType == Type.DOUBLE_TYPE) {
if (opToken == JetTokens.GT || opToken == JetTokens.GTEQ) {
@@ -703,7 +692,7 @@ public abstract class StackValue {
v.store(firstParamIndex, type);
}
ReceiverValue receiverParameter = resolvedGetCall.getExtensionReceiver();
ReceiverValue receiverParameter = resolvedGetCall.getReceiverArgument();
int receiverIndex = -1;
if (receiverParameter.exists()) {
Type type = codegen.typeMapper.mapType(receiverParameter.getType());
@@ -711,9 +700,9 @@ public abstract class StackValue {
v.store(receiverIndex, type);
}
ReceiverValue dispatchReceiver = resolvedGetCall.getDispatchReceiver();
ReceiverValue thisObject = resolvedGetCall.getThisObject();
int thisIndex = -1;
if (dispatchReceiver.exists()) {
if (thisObject.exists()) {
thisIndex = frame.enterTemp(OBJECT_TYPE);
v.store(thisIndex, OBJECT_TYPE);
}
@@ -734,14 +723,14 @@ public abstract class StackValue {
throw new UnsupportedOperationException();
}
if (resolvedSetCall.getDispatchReceiver().exists()) {
if (resolvedSetCall.getExtensionReceiver().exists()) {
codegen.generateReceiverValue(resolvedSetCall.getDispatchReceiver(), OBJECT_TYPE);
if (resolvedSetCall.getThisObject().exists()) {
if (resolvedSetCall.getReceiverArgument().exists()) {
codegen.generateReceiverValue(resolvedSetCall.getThisObject(), OBJECT_TYPE);
}
v.load(realReceiverIndex, realReceiverType);
}
else {
if (resolvedSetCall.getExtensionReceiver().exists()) {
if (resolvedSetCall.getReceiverArgument().exists()) {
v.load(realReceiverIndex, realReceiverType);
}
else {
@@ -791,13 +780,13 @@ public abstract class StackValue {
}
}
if (call.getDispatchReceiver().exists()) {
if (call.getExtensionReceiver().exists()) {
if (call.getThisObject().exists()) {
if (call.getReceiverArgument().exists()) {
return false;
}
}
else {
if (codegen.typeMapper.mapType(call.getResultingDescriptor().getExtensionReceiverParameter().getType())
if (codegen.typeMapper.mapType(call.getResultingDescriptor().getReceiverParameter().getType())
.getSize() != 1) {
return false;
}
@@ -1118,14 +1107,14 @@ public abstract class StackValue {
) {
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
ReceiverParameterDescriptor dispatchReceiver = descriptor.getDispatchReceiverParameter();
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
if (extensionReceiver != null) {
return callableMethod != null ? callableMethod.getReceiverClass() : typeMapper.mapType(extensionReceiver.getType());
if (receiverParameter != null) {
return callableMethod != null ? callableMethod.getReceiverClass() : typeMapper.mapType(receiverParameter.getType());
}
else if (dispatchReceiver != null) {
return callableMethod != null ? callableMethod.getThisType() : typeMapper.mapType(dispatchReceiver.getType());
else if (expectedThisObject != null) {
return callableMethod != null ? callableMethod.getThisType() : typeMapper.mapType(expectedThisObject.getType());
}
else if (isLocalFunCall(callableMethod)) {
return callableMethod.getGenerateCalleeType();
@@ -1138,28 +1127,28 @@ public abstract class StackValue {
public void put(Type type, InstructionAdapter v) {
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
ReceiverValue dispatchReceiver = resolvedCall.getDispatchReceiver();
ReceiverValue extensionReceiver = resolvedCall.getExtensionReceiver();
ReceiverValue thisObject = resolvedCall.getThisObject();
ReceiverValue receiverArgument = resolvedCall.getReceiverArgument();
int depth = 0;
if (dispatchReceiver.exists()) {
if (thisObject.exists()) {
if (!AnnotationsPackage.isPlatformStaticInObject(descriptor)) {
if (extensionReceiver.exists()) {
if (receiverArgument.exists()) {
//noinspection ConstantConditions
Type resultType =
callableMethod != null ?
callableMethod.getOwner() :
codegen.typeMapper.mapType(descriptor.getDispatchReceiverParameter().getType());
codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType());
codegen.generateReceiverValue(dispatchReceiver, resultType);
codegen.generateReceiverValue(thisObject, resultType);
}
else {
genReceiver(v, dispatchReceiver, type, null, 0);
genReceiver(v, thisObject, type, null, 0);
}
depth = 1;
}
}
else if (isLocalFunCall(callableMethod)) {
assert receiver == none() || extensionReceiver.exists() :
assert receiver == none() || receiverArgument.exists() :
"Receiver should be present only for local extension function: " + callableMethod;
StackValue value = codegen.findLocalOrCapturedValue(descriptor.getOriginal());
assert value != null : "Local fun should be found in locals or in captured params: " + resolvedCall;
@@ -1168,8 +1157,8 @@ public abstract class StackValue {
depth = 1;
}
if (putReceiverArgumentOnStack && extensionReceiver.exists()) {
genReceiver(v, extensionReceiver, type, descriptor.getExtensionReceiverParameter(), depth);
if (putReceiverArgumentOnStack && receiverArgument.exists()) {
genReceiver(v, receiverArgument, type, descriptor.getReceiverParameter(), depth);
}
}

View File

@@ -75,7 +75,7 @@ public class TailRecursionCodegen {
}
assignParameterValues(fd, callable, arguments);
if (callable.getReceiverClass() != null) {
if (resolvedCall.getExtensionReceiver() != fd.getExtensionReceiverParameter().getValue()) {
if (resolvedCall.getReceiverArgument() != fd.getReceiverParameter().getValue()) {
StackValue expression = context.getReceiverExpression(codegen.typeMapper);
expression.store(callable.getReceiverClass(), v);
}

View File

@@ -180,12 +180,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
assert descriptor != null :
String.format("No descriptor for enum entry \n---\n%s\n---\n", JetPsiUtil.getElementTextWithContext(enumEntry));
if (enumEntry.getDeclarations().isEmpty()) {
for (JetDelegationSpecifier specifier : enumEntry.getDelegationSpecifiers()) {
specifier.accept(this);
}
}
else {
if (!enumEntry.getDeclarations().isEmpty()) {
bindingTrace.record(ENUM_ENTRY_CLASS_NEED_SUBCLASS, descriptor);
super.visitEnumEntry(enumEntry);
}

View File

@@ -33,7 +33,7 @@ public final class MutableClosure implements CalculatedClosure {
private final ResolvedCall<ConstructorDescriptor> superCall;
private final ClassDescriptor enclosingClass;
private final CallableDescriptor enclosingFunWithReceiverDescriptor;
private final CallableDescriptor enclosingReceiverDescriptor;
private boolean captureThis;
private boolean captureReceiver;
@@ -48,7 +48,7 @@ public final class MutableClosure implements CalculatedClosure {
) {
this.enclosingClass = enclosingClass;
this.superCall = superCall;
this.enclosingFunWithReceiverDescriptor = enclosingExtensionMemberForClass(classDescriptor);
this.enclosingReceiverDescriptor = enclosingExtensionMemberForClass(classDescriptor);
}
@Nullable
@@ -56,7 +56,7 @@ public final class MutableClosure implements CalculatedClosure {
DeclarationDescriptor classContainer = classDescriptor.getContainingDeclaration();
if (classContainer instanceof CallableMemberDescriptor) {
CallableMemberDescriptor member = getDirectMember((CallableMemberDescriptor) classContainer);
if (member.getExtensionReceiverParameter() != null) {
if (member.getReceiverParameter() != null) {
return member;
}
}
@@ -85,8 +85,9 @@ public final class MutableClosure implements CalculatedClosure {
@Override
public JetType getCaptureReceiverType() {
if (captureReceiver) {
ReceiverParameterDescriptor parameter = getEnclosingReceiverDescriptor();
assert parameter != null : "Receiver parameter should exist in " + enclosingFunWithReceiverDescriptor;
//noinspection ConstantConditions
ReceiverParameterDescriptor parameter = enclosingReceiverDescriptor.getReceiverParameter();
assert parameter != null : "Receiver parameter should exist in " + enclosingReceiverDescriptor;
return parameter.getType();
}
@@ -94,8 +95,8 @@ public final class MutableClosure implements CalculatedClosure {
}
public void setCaptureReceiver() {
if (enclosingFunWithReceiverDescriptor == null) {
throw new IllegalStateException("Extension receiver parameter should exist");
if (enclosingReceiverDescriptor == null) {
throw new IllegalStateException();
}
this.captureReceiver = true;
}
@@ -121,13 +122,12 @@ public final class MutableClosure implements CalculatedClosure {
public void captureVariable(EnclosedValueDescriptor value) {
if (captureVariables == null) {
captureVariables = new LinkedHashMap<DeclarationDescriptor, EnclosedValueDescriptor>();
captureVariables = new HashMap<DeclarationDescriptor, EnclosedValueDescriptor>();
}
captureVariables.put(value.getDescriptor(), value);
}
@Nullable
public ReceiverParameterDescriptor getEnclosingReceiverDescriptor() {
return enclosingFunWithReceiverDescriptor != null ? enclosingFunWithReceiverDescriptor.getExtensionReceiverParameter() : null;
public CallableDescriptor getEnclosingReceiverDescriptor() {
return enclosingReceiverDescriptor;
}
}

View File

@@ -31,7 +31,10 @@ import org.jetbrains.jet.storage.LockBasedStorageManager;
import org.jetbrains.jet.storage.NullableLazyValue;
import org.jetbrains.org.objectweb.asm.Type;
import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_THIS_FIELD;
import static org.jetbrains.jet.codegen.AsmUtil.getVisibilityAccessFlag;
@@ -106,7 +109,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
public final CallableDescriptor getCallableDescriptorWithReceiver() {
if (contextDescriptor instanceof CallableDescriptor) {
CallableDescriptor callableDescriptor = (CallableDescriptor) getContextDescriptor();
return callableDescriptor.getExtensionReceiverParameter() != null ? callableDescriptor : null;
return callableDescriptor.getReceiverParameter() != null ? callableDescriptor : null;
}
return null;
}
@@ -157,8 +160,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
@NotNull
public ClassContext intoAnonymousClass(@NotNull ClassDescriptor descriptor, @NotNull ExpressionCodegen codegen, @NotNull OwnerKind ownerKind) {
return new AnonymousClassContext(codegen.getState().getTypeMapper(), descriptor, ownerKind, this, codegen);
public ClassContext intoAnonymousClass(@NotNull ClassDescriptor descriptor, @NotNull ExpressionCodegen codegen) {
return new AnonymousClassContext(codegen.getState().getTypeMapper(), descriptor, OwnerKind.IMPLEMENTATION, this, codegen);
}
@NotNull
@@ -228,7 +231,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull
public DeclarationDescriptor getAccessor(@NotNull DeclarationDescriptor descriptor, boolean isForBackingFieldInOuterClass, @Nullable JetType delegateType) {
if (accessors == null) {
accessors = new LinkedHashMap<DeclarationDescriptor, DeclarationDescriptor>();
accessors = new HashMap<DeclarationDescriptor, DeclarationDescriptor>();
}
descriptor = descriptor.getOriginal();
DeclarationDescriptor accessor = accessors.get(descriptor);

View File

@@ -112,7 +112,7 @@ public interface LocalLookup {
RECEIVER {
@Override
public boolean isCase(DeclarationDescriptor d) {
return d instanceof ReceiverParameterDescriptor;
return d instanceof CallableDescriptor;
}
@Override
@@ -123,11 +123,9 @@ public interface LocalLookup {
MutableClosure closure,
Type classType
) {
if (closure.getEnclosingReceiverDescriptor() != d) {
return null;
}
if (closure.getEnclosingReceiverDescriptor() != d) return null;
JetType receiverType = closure.getEnclosingReceiverDescriptor().getType();
JetType receiverType = ((CallableDescriptor) d).getReceiverParameter().getType();
Type type = state.getTypeMapper().mapType(receiverType);
StackValue innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false);
closure.setCaptureReceiver();
@@ -139,7 +137,7 @@ public interface LocalLookup {
@Override
public StackValue outerValue(@NotNull EnclosedValueDescriptor d, @NotNull ExpressionCodegen codegen) {
CallableDescriptor descriptor = (CallableDescriptor) d.getDescriptor();
return StackValue.local(descriptor.getDispatchReceiverParameter() != null ? 1 : 0, d.getType());
return StackValue.local(descriptor.getExpectedThisObject() != null ? 1 : 0, d.getType());
}
};

View File

@@ -25,13 +25,14 @@ import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Type;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
private final boolean isInliningLambda;
private Label methodStartLabel;
@@ -58,7 +59,7 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
public StackValue getReceiverExpression(JetTypeMapper typeMapper) {
assert getCallableDescriptorWithReceiver() != null;
@SuppressWarnings("ConstantConditions")
Type asmType = typeMapper.mapType(getCallableDescriptorWithReceiver().getExtensionReceiverParameter().getType());
Type asmType = typeMapper.mapType(getCallableDescriptorWithReceiver().getReceiverParameter().getType());
return StackValue.local(AsmUtil.getReceiverIndex(this, getContextDescriptor()), asmType);
}
@@ -71,15 +72,6 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
return getParentContext().lookupInContext(d, result, state, ignoreNoOuter);
}
@Nullable
public StackValue generateReceiver(@NotNull CallableDescriptor descriptor, @NotNull GenerationState state, boolean ignoreNoOuter) {
if (getCallableDescriptorWithReceiver() == descriptor) {
return getReceiverExpression(state.getTypeMapper());
}
ReceiverParameterDescriptor parameter = descriptor.getExtensionReceiverParameter();
return lookupInContext(parameter, StackValue.local(0, OBJECT_TYPE), state, ignoreNoOuter);
}
@Override
public boolean isStatic() {
return getParentContext().isStatic();

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2010-2014 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.jet.codegen.extensions
import org.jetbrains.jet.extensions.ProjectExtensionDescriptor
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall
import org.jetbrains.jet.codegen.StackValue
import org.jetbrains.jet.codegen.state.JetTypeMapper
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public trait ExpressionCodegenExtension {
class object : ProjectExtensionDescriptor<ExpressionCodegenExtension>("org.jetbrains.kotlin.expressionCodegenExtension", javaClass<ExpressionCodegenExtension>())
public class Context(
public val typeMapper: JetTypeMapper,
public val v: InstructionAdapter
)
// return null if not applicable
public fun apply(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): StackValue?
}

View File

@@ -1,143 +0,0 @@
/*
* Copyright 2010-2014 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.jet.codegen.inline
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import com.google.common.collect.LinkedListMultimap
import org.jetbrains.org.objectweb.asm.Label
import java.util.ArrayList
import com.intellij.util.containers.Stack
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import com.google.common.collect.Lists
import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode
import java.util.Comparator
import java.util.Collections
public abstract class CoveringTryCatchNodeProcessor<T: IntervalWithHandler>() {
private val tryBlockStarts = LinkedListMultimap.create<LabelNode, T>()
private val tryBlockEnds = LinkedListMultimap.create<LabelNode, T>()
public val allTryCatchNodes: ArrayList<T> = arrayListOf()
private val currentCoveringBlocks: Stack<T> = Stack()
public val coveringFromInnermost: List<T>
get() = currentCoveringBlocks.reverse()
fun addNewTryCatchNode(newInfo: T) {
tryBlockStarts.put(newInfo.startLabel, newInfo)
tryBlockEnds.put(newInfo.endLabel, newInfo)
allTryCatchNodes.add(newInfo)
}
fun remapStartLabel(oldStart: LabelNode, remapped: T) {
tryBlockStarts.remove(oldStart, remapped)
tryBlockStarts.put(remapped.startLabel, remapped)
}
public fun getStartNodes(label: LabelNode): List<T> {
return tryBlockStarts.get(label)
}
public fun getEndNodes(label: LabelNode): List<T> {
return tryBlockEnds.get(label)
}
//Keep information about try blocks that cover current instruction -
// pushing and popping it to stack entering and exiting tryCatchBlock start and end labels
public open fun updateCoveringTryBlocks(curIns: AbstractInsnNode, directOrder: Boolean) {
if (curIns !is LabelNode) return
val infosToClose = if (!directOrder) getStartNodes(curIns) else getEndNodes(curIns)
for (startNode in infosToClose) {
val pop = currentCoveringBlocks.pop()
//Temporary disabled cause during patched structure of exceptions changed
// if (startNode != pop) {
// throw RuntimeException("Wrong try-catch structure " + startNode + " " + pop + " " + infosToClose.size())
// };
}
//Reversing list order cause we should pop external block before internal one
// (originally internal blocks goes before external one, such invariant preserved via sortTryCatchBlocks method)
val infoToOpen = if (!directOrder) getEndNodes(curIns) else getStartNodes(curIns)
for (info in infoToOpen.reverse()) {
currentCoveringBlocks.add(info)
}
}
public abstract fun instructionIndex(inst: AbstractInsnNode): Int
private fun isEmptyInterval(node: T): Boolean {
val start = node.startLabel
var end: AbstractInsnNode = node.endLabel
while (end != start && end is LabelNode) {
end = end.getPrevious()
}
return start == end;
}
public fun getNonEmptyNodes(): List<T> {
return allTryCatchNodes.filterNot { isEmptyInterval(it) }
}
public fun sortTryCatchBlocks() {
val comp = Comparator {(t1: T, t2: T): Int ->
var result = instructionIndex(t1.handler) - instructionIndex(t2.handler)
if (result == 0) {
result = instructionIndex(t1.startLabel) - instructionIndex(t2.startLabel)
if (result == 0) {
assert(false, "Error: support multicatch finallies!")
result = instructionIndex(t1.endLabel) - instructionIndex(t2.endLabel)
}
}
result
}
Collections.sort<T>(allTryCatchNodes, comp)
}
}
public class DefaultProcessor(val node: MethodNode) : CoveringTryCatchNodeProcessor<TryCatchBlockNodeWrapper>() {
{
node.tryCatchBlocks.forEach { addNode(it) }
}
fun addNode(node: TryCatchBlockNode) {
addNewTryCatchNode(TryCatchBlockNodeWrapper(node))
}
override fun instructionIndex(inst: AbstractInsnNode): Int {
return node.instructions.indexOf(inst)
}
}
public class TryCatchBlockNodeWrapper(val node: TryCatchBlockNode) : IntervalWithHandler {
override val startLabel: LabelNode
get() = node.start
override val endLabel: LabelNode
get() = node.end
override val handler: LabelNode
get() = node.handler
override val type: String?
get() = node.type
}

View File

@@ -18,7 +18,6 @@ package org.jetbrains.jet.codegen.inline;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.*;
@@ -32,6 +31,7 @@ import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedSimpl
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
@@ -42,26 +42,25 @@ import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.types.lang.InlineStrategy;
import org.jetbrains.jet.lang.types.lang.InlineUtil;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.Method;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.LabelNode;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode;
import java.io.IOException;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import static org.jetbrains.jet.codegen.AsmUtil.getMethodAsmFlags;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.codegen.AsmUtil.*;
import static org.jetbrains.jet.codegen.inline.InlineCodegenUtil.addInlineMarker;
public class InlineCodegen implements CallGenerator {
private final GenerationState state;
private final JetTypeMapper typeMapper;
private final BindingContext bindingContext;
private final SimpleFunctionDescriptor functionDescriptor;
private final JvmMethodSignature jvmSignature;
@@ -91,6 +90,7 @@ public class InlineCodegen implements CallGenerator {
this.codegen = codegen;
this.callElement = callElement;
this.functionDescriptor = functionDescriptor.getOriginal();
bindingContext = codegen.getBindingContext();
initialFrameSize = codegen.getFrameMap().getCurrentSize();
context = (MethodContext) getContext(functionDescriptor, state);
@@ -241,7 +241,7 @@ public class InlineCodegen implements CallGenerator {
}
}
};
List<MethodInliner.PointForExternalFinallyBlocks> infos = MethodInliner.processReturns(adapter, labelOwner, true, null);
List<MethodInliner.ExternalFinallyBlockInfo> infos = MethodInliner.processReturns(adapter, labelOwner, true, null);
generateAndInsertFinallyBlocks(adapter, infos);
adapter.accept(new InliningInstructionAdapter(codegen.v));
@@ -418,7 +418,7 @@ public class InlineCodegen implements CallGenerator {
private void putClosureParametersOnStack() {
for (LambdaInfo next : expressionMap.values()) {
activeLambda = next;
codegen.pushClosureOnStack(next.getClassDescriptor(), true, this);
codegen.pushClosureOnStack(next.closure, false, this);
}
activeLambda = null;
}
@@ -483,62 +483,19 @@ public class InlineCodegen implements CallGenerator {
}
public void generateAndInsertFinallyBlocks(MethodNode intoNode, List<MethodInliner.PointForExternalFinallyBlocks> insertPoints) {
public void generateAndInsertFinallyBlocks(MethodNode intoNode, List<MethodInliner.ExternalFinallyBlockInfo> insertPoints) {
if (!codegen.hasFinallyBlocks()) return;
Map<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks> extensionPoints =
new HashMap<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks>();
for (MethodInliner.PointForExternalFinallyBlocks insertPoint : insertPoints) {
extensionPoints.put(insertPoint.beforeIns, insertPoint);
}
for (MethodInliner.ExternalFinallyBlockInfo insertPoint : insertPoints) {
MethodNode finallyNode = InlineCodegenUtil.createEmptyMethodNode();
ExpressionCodegen finallyCodegen =
new ExpressionCodegen(finallyNode, codegen.getFrameMap(), codegen.getReturnType(),
codegen.getContext(), codegen.getState(), codegen.getParentCodegen());
finallyCodegen.addBlockStackElementsForNonLocalReturns(codegen.getBlockStackElements());
DefaultProcessor processor = new DefaultProcessor(intoNode);
finallyCodegen.generateFinallyBlocksIfNeeded(insertPoint.returnType);
AbstractInsnNode curInstr = intoNode.instructions.getFirst();
while (curInstr != null) {
processor.updateCoveringTryBlocks(curInstr, true);
MethodInliner.PointForExternalFinallyBlocks extension = extensionPoints.get(curInstr);
if (extension != null) {
Label start = new Label();
Label end = new Label();
MethodNode finallyNode = InlineCodegenUtil.createEmptyMethodNode();
finallyNode.visitLabel(start);
ExpressionCodegen finallyCodegen =
new ExpressionCodegen(finallyNode, codegen.getFrameMap(), codegen.getReturnType(),
codegen.getContext(), codegen.getState(), codegen.getParentCodegen());
finallyCodegen.addBlockStackElementsForNonLocalReturns(codegen.getBlockStackElements());
finallyCodegen.generateFinallyBlocksIfNeeded(extension.returnType);
finallyNode.visitLabel(end);
//Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method
InlineCodegenUtil.insertNodeBefore(finallyNode, intoNode, curInstr);
List<TryCatchBlockNodeWrapper> blocks = processor.getCoveringFromInnermost();
ListIterator<TryCatchBlockNodeWrapper> iterator = blocks.listIterator(blocks.size());
while (iterator.hasPrevious()) {
TryCatchBlockNodeWrapper previous = iterator.previous();
LabelNode oldStart = previous.getStartLabel();
TryCatchBlockNode node = previous.getNode();
node.start = (LabelNode) end.info;
processor.remapStartLabel(oldStart, previous);
TryCatchBlockNode additionalNode = new TryCatchBlockNode(oldStart, (LabelNode) start.info, node.handler, node.type);
processor.addNode(additionalNode);
}
}
curInstr = curInstr.getNext();
}
processor.sortTryCatchBlocks();
Iterable<TryCatchBlockNodeWrapper> nodes = processor.getNonEmptyNodes();
intoNode.tryCatchBlocks.clear();
for (TryCatchBlockNodeWrapper node : nodes) {
intoNode.tryCatchBlocks.add(node.getNode());
InlineCodegenUtil.insertNodeBefore(finallyNode, intoNode, insertPoint.beforeIns);
}
}

View File

@@ -17,25 +17,21 @@
package org.jetbrains.jet.codegen.inline;
import com.google.common.base.Objects;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.codegen.AsmUtil;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.tree.*;
import org.jetbrains.org.objectweb.asm.util.Textifier;
import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
import static org.jetbrains.jet.codegen.inline.InlineCodegenUtil.*;
public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<TryCatchBlockNodeInfo> {
public class InternalFinallyBlockInliner {
private static class FinallyBlockInfo {
@@ -47,18 +43,6 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
startIns = inclusiveStart;
endInsExclusive = exclusiveEnd;
}
public boolean isEmpty() {
if (!(startIns instanceof LabelNode)) {
return false;
}
AbstractInsnNode end = endInsExclusive;
while (end != startIns && end instanceof LabelNode) {
end = end.getPrevious();
}
return startIns == end;
}
}
public static void processInlineFunFinallyBlocks(@NotNull MethodNode inlineFun, int lambdaTryCatchBlockNodes) {
@@ -76,18 +60,22 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
@NotNull
private final MethodNode inlineFun;
private final List<TryCatchBlockNodeInfo> inlineFunTryBlockInfo;
private final ListMultimap<LabelNode, TryCatchBlockNodeInfo> tryBlockStarts = LinkedListMultimap.create();
private final ListMultimap<LabelNode, TryCatchBlockNodeInfo> tryBlockEnds = LinkedListMultimap.create();
//lambdaTryCatchBlockNodes is number of TryCatchBlockNodes that was inlined with lambdas into function
//due to code generation specific they placed before function TryCatchBlockNodes
private InternalFinallyBlockInliner(@NotNull MethodNode inlineFun, List<TryCatchBlockNodeInfo> inlineFunTryBlockInfo) {
this.inlineFun = inlineFun;
for (TryCatchBlockNodeInfo block : inlineFunTryBlockInfo) {
addNewTryCatchNode(block);
}
this.inlineFunTryBlockInfo = inlineFunTryBlockInfo;
}
private int initAndGetVarIndexForNonLocalReturnValue() {
//sortTryCatchBlocks();/*TODO maybe remove*/
mapLabelsToTryCatchBlocks();
MaxLocalsCalculator tempCalcNode = new MaxLocalsCalculator(
InlineCodegenUtil.API,
@@ -100,6 +88,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
private void processInlineFunFinallyBlocks() {
int nextTempNonLocalVarIndex = initAndGetVarIndexForNonLocalReturnValue();
Stack<TryCatchBlockNodeInfo> coveringTryCatchBlocks = new Stack<TryCatchBlockNodeInfo>();
InsnList instructions = inlineFun.instructions;
//As we do finally block code search after non-local return instruction
@@ -107,19 +96,10 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
// So we do instruction processing in reverse order!
AbstractInsnNode curIns = instructions.getLast();
while (curIns != null) {
updateCoveringTryBlocks(curIns);
updateCoveringTryBlocks(coveringTryCatchBlocks, curIns);
//At this point only global return is possible, local one already substituted with: goto endLabel
if (!InlineCodegenUtil.isReturnOpcode(curIns.getOpcode()) ||
!InlineCodegenUtil.isMarkedReturn(curIns)) {
curIns = curIns.getPrevious();
continue;
}
List<TryCatchBlockNodeInfo> currentCoveringNodes = getCoveringFromInnermost();
checkCoveringBlocksInvariant(currentCoveringNodes);
if (currentCoveringNodes.isEmpty() ||
currentCoveringNodes.get(currentCoveringNodes.size() - 1).getOnlyCopyNotProcess()) {
if (!InlineCodegenUtil.isReturnOpcode(curIns.getOpcode()) || !InlineCodegenUtil.isMarkedReturn(curIns)) {
curIns = curIns.getPrevious();
continue;
}
@@ -133,59 +113,69 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
// Each group that corresponds to try/*catches*/finally contains tryCatch block with default handler.
// For each such group we should insert corresponding finally before non-local return.
// So we split all try blocks on current instructions to groups and process them independently
List<TryBlockCluster<TryCatchBlockNodeInfo>> clustersFromInnermost = InlinePackage.doClustering(currentCoveringNodes);
Iterator<TryBlockCluster<TryCatchBlockNodeInfo>> tryCatchBlockIterator = clustersFromInnermost.iterator();
List<TryBlockCluster<TryCatchBlockNodeInfo>> clusters = InlinePackage.doClustering(coveringTryCatchBlocks);
ListIterator<TryBlockCluster<TryCatchBlockNodeInfo>> tryCatchBlockIterator = clusters.listIterator(clusters.size());
//Reverse visiting cause innermost tryCatchBlocks in the end
while (tryCatchBlockIterator.hasPrevious()) {
TryBlockCluster originalFinallyCluster = tryCatchBlockIterator.previous();
List<TryCatchBlockNodeInfo> clusterBlocks = originalFinallyCluster.getBlocks();
TryCatchBlockNodeInfo originalFinallyBlock = clusterBlocks.get(0);
checkClusterInvariant(clustersFromInnermost);
List<TryCatchBlockNodeInfo> additionalNodesToSplit = new ArrayList<TryCatchBlockNodeInfo>();
while (tryCatchBlockIterator.hasNext()) {
TryBlockCluster clusterToFindFinally = tryCatchBlockIterator.next();
List<TryCatchBlockNodeInfo> clusterBlocks = clusterToFindFinally.getBlocks();
TryCatchBlockNodeInfo nodeWithDefaultHandlerIfExists = clusterBlocks.get(clusterBlocks.size() - 1);
FinallyBlockInfo finallyInfo = findFinallyBlockBody(nodeWithDefaultHandlerIfExists, getAllTryCatchNodes());
FinallyBlockInfo finallyInfo = findFinallyBlockBody(originalFinallyBlock, inlineFunTryBlockInfo);
if (finallyInfo == null) continue;
if (nodeWithDefaultHandlerIfExists.getOnlyCopyNotProcess()) {
additionalNodesToSplit.addAll(clusterBlocks);
continue;
}
instructions.resetLabels();
List<TryCatchBlockNodePosition> tryCatchBlockInlinedInFinally = findTryCatchBlocksInlinedInFinally(finallyInfo);
//Keep some information about label nodes, we need it to understand whether it's jump inside finally block or outside
// in first case we do call VISIT on instruction otherwise recreating jump instruction (see below)
Set<LabelNode> labelsInsideFinally = rememberOriginalLabelNodes(finallyInfo);
//Creating temp node for finally block copy with some additional instruction
MethodNode finallyBlockCopy = createEmptyMethodNode();
Label newFinallyStart = new Label();
Label newFinallyEnd = new Label();
Label insertedBlockEnd = new Label();
boolean generateAloadAstore = nonLocalReturnType != Type.VOID_TYPE && !finallyInfo.isEmpty();
if (generateAloadAstore) {
if (nonLocalReturnType != Type.VOID_TYPE) {
finallyBlockCopy.visitVarInsn(nonLocalReturnType.getOpcode(Opcodes.ISTORE), nextTempNonLocalVarIndex);
}
finallyBlockCopy.visitLabel(newFinallyStart);
//Keep some information about label nodes, we need it to understand whether it's jump inside finally block or outside
// in first case we do call VISIT on instruction otherwise recreating jump instruction (see below)
Set<LabelNode> labelsInsideFinally = rememberOriginalLabelNodes(finallyInfo);
//Writing finally block body to temporary node
AbstractInsnNode currentIns = finallyInfo.startIns;
while (currentIns != finallyInfo.endInsExclusive) {
boolean isInsOrJumpInsideFinally =
!(currentIns instanceof JumpInsnNode) ||
labelsInsideFinally.contains(((JumpInsnNode) currentIns).label);
//This condition allows another model for non-local returns processing
if (false && InlineCodegenUtil.isReturnOpcode(currentIns.getOpcode()) && !InlineCodegenUtil.isMarkedReturn(currentIns)) {
//substitute all local returns in finally finallyInfo with non-local one lambdaFinallyBlocks try finallyInfo
//TODO same for jumps
Type localReturnType = InlineCodegenUtil.getReturnType(currentIns.getOpcode());
substituteReturnValueInFinally(nextTempNonLocalVarIndex, nonLocalReturnType, finallyBlockCopy,
localReturnType, true);
copyInstruction(nextTempNonLocalVarIndex, curIns, instrInsertFinallyBefore, nonLocalReturnType, finallyBlockCopy,
currentIns, isInsOrJumpInsideFinally);
instrInsertFinallyBefore.accept(finallyBlockCopy);
curIns.accept(finallyBlockCopy);
}
else {
boolean isInsOrJumpInsideFinally =
!(currentIns instanceof JumpInsnNode) ||
labelsInsideFinally.contains(((JumpInsnNode) currentIns).label);
if (isInsOrJumpInsideFinally) {
currentIns.accept(finallyBlockCopy); //VISIT
}
else {
//keep original jump: add currentIns clone
finallyBlockCopy.instructions.add(new JumpInsnNode(currentIns.getOpcode(), ((JumpInsnNode) currentIns).label));
}
}
currentIns = currentIns.getNext();
}
finallyBlockCopy.visitLabel(newFinallyEnd);
if (generateAloadAstore) {
if (nonLocalReturnType != Type.VOID_TYPE) {
finallyBlockCopy.visitVarInsn(nonLocalReturnType.getOpcode(Opcodes.ILOAD), nextTempNonLocalVarIndex);
nextTempNonLocalVarIndex += nonLocalReturnType.getSize(); //TODO: do more wise indexing
}
@@ -195,76 +185,15 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
//Copying finally body before non-local return instruction
InlineCodegenUtil.insertNodeBefore(finallyBlockCopy, inlineFun, instrInsertFinallyBefore);
updateExceptionTable(clusterBlocks, newFinallyStart, newFinallyEnd,
tryCatchBlockInlinedInFinally, labelsInsideFinally, (LabelNode) insertedBlockEnd.info, additionalNodesToSplit);
}
//skip just inserted finally
curIns = curIns.getPrevious();
while (curIns != null && curIns != nextPrev) {
updateCoveringTryBlocks(curIns);
curIns = curIns.getPrevious();
nextPrev = updateExceptionTable(coveringTryCatchBlocks, nextPrev, clusterBlocks, newFinallyStart, newFinallyEnd,
tryCatchBlockInlinedInFinally, labelsInsideFinally, (LabelNode) insertedBlockEnd.info);
}
curIns = nextPrev;
}
substituteTryBlockNodes();
}
private static void copyInstruction(
int nextTempNonLocalVarIndex,
@NotNull AbstractInsnNode curIns,
@NotNull AbstractInsnNode instrInsertFinallyBefore,
@NotNull Type nonLocalReturnType,
@NotNull MethodNode finallyBlockCopy,
@NotNull AbstractInsnNode currentIns,
boolean isInsOrJumpInsideFinally
) {
//This condition allows another model for non-local returns processing
if (false) {
boolean isReturnForSubstitution =
InlineCodegenUtil.isReturnOpcode(currentIns.getOpcode()) && !InlineCodegenUtil.isMarkedReturn(currentIns);
if (!isInsOrJumpInsideFinally || isReturnForSubstitution) {
//substitute all local returns and jumps outside finally with non-local return
Type localReturnType = InlineCodegenUtil.getReturnType(currentIns.getOpcode());
substituteReturnValueInFinally(nextTempNonLocalVarIndex, nonLocalReturnType, finallyBlockCopy,
localReturnType, isReturnForSubstitution);
instrInsertFinallyBefore.accept(finallyBlockCopy);
curIns.accept(finallyBlockCopy);
} else {
currentIns.accept(finallyBlockCopy); //VISIT
}
}
else {
if (isInsOrJumpInsideFinally) {
currentIns.accept(finallyBlockCopy); //VISIT
}
else {
//keep original jump: add currentIns clone
finallyBlockCopy.instructions.add(new JumpInsnNode(currentIns.getOpcode(), ((JumpInsnNode) currentIns).label));
}
}
}
private static void checkCoveringBlocksInvariant(List<TryCatchBlockNodeInfo> coveringTryCatchBlocks) {
boolean isWasOnlyLocal = false;
for (TryCatchBlockNodeInfo info : Lists.reverse(coveringTryCatchBlocks)) {
assert !isWasOnlyLocal || info.getOnlyCopyNotProcess();
if (info.getOnlyCopyNotProcess()) {
isWasOnlyLocal = true;
}
}
}
private static void checkClusterInvariant(List<TryBlockCluster<TryCatchBlockNodeInfo>> clusters) {
boolean isWasOnlyLocal;
isWasOnlyLocal = false;
for (TryBlockCluster<TryCatchBlockNodeInfo> cluster : Lists.reverse(clusters)) {
TryCatchBlockNodeInfo info = cluster.getBlocks().get(0);
assert !isWasOnlyLocal || info.getOnlyCopyNotProcess();
if (info.getOnlyCopyNotProcess()) {
isWasOnlyLocal = true;
}
inlineFun.tryCatchBlocks.clear();
for (TryCatchBlockNodeInfo info : inlineFunTryBlockInfo) {
inlineFun.tryCatchBlocks.add(info.getNode());
}
}
@@ -279,14 +208,17 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
return labelsInsideFinally;
}
private void updateExceptionTable(
@Nullable
private AbstractInsnNode updateExceptionTable(
@NotNull Stack<TryCatchBlockNodeInfo> coveringTryBlocks,
@Nullable AbstractInsnNode nextPrev,
@NotNull List<TryCatchBlockNodeInfo> updatingClusterBlocks,
@NotNull Label newFinallyStart,
@NotNull Label newFinallyEnd,
@NotNull List<TryCatchBlockNodePosition> tryCatchBlockPresentInFinally,
@NotNull Set<LabelNode> labelsInsideFinally,
@NotNull LabelNode insertedBlockEnd,
@NotNull List<TryCatchBlockNodeInfo> patched
@NotNull LabelNode insertedBlockEnd
) {
//copy tryCatchFinallies that totally in finally block
@@ -314,7 +246,9 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
assert inlineFun.instructions.indexOf(additionalTryCatchBlock.start) <= inlineFun.instructions.indexOf(additionalTryCatchBlock.end);
TryCatchBlockNodeInfo newInfo = new TryCatchBlockNodeInfo(additionalTryCatchBlock, true);
addNewTryCatchNode(newInfo);
tryBlockStarts.put(newInfo.getStartLabel(), newInfo);
tryBlockEnds.put(newInfo.getEndLabel(), newInfo);
inlineFunTryBlockInfo.add(newInfo);
}
}
else if (clusterPosition == TryCatchPosition.END) {
@@ -338,7 +272,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
assert Objects.equal(startNode.getType(), endNode.getType()) : "Different handler types : " + startNode.getType() + " " + endNode.getType();
patchTryBlocks((LabelNode) startNode.getStartLabel().getLabel().info, endNode);
patchTryBlocks((LabelNode) startNode.getStartLabel().getLabel().info, endNode, false);
}
}
}
@@ -350,7 +284,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
//TODO rewrite to clusters
for (TryCatchBlockNodePosition endBlockPosition : singleCluster.getBlocks()) {
TryCatchBlockNodeInfo endNode = endBlockPosition.getNodeInfo();
patchTryBlocks((LabelNode) insertedBlockEnd.getLabel().info, endNode);
patchTryBlocks((LabelNode) insertedBlockEnd.getLabel().info, endNode, true);
//nextPrev = (AbstractInsnNode) insertedBlockEnd.getLabel().info;
}
@@ -359,35 +293,38 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
}
assert handler2Cluster.isEmpty() : "Unmatched clusters " + handler2Cluster.size();
List<TryCatchBlockNodeInfo > toProcess = new ArrayList<TryCatchBlockNodeInfo>();
toProcess.addAll(patched);
toProcess.addAll(updatingClusterBlocks);
patched.clear();
// Inserted finally shouldn't be handled by corresponding catches,
// so we should split original interval by inserted finally one
for (TryCatchBlockNodeInfo block : toProcess) {
for (TryCatchBlockNodeInfo block : updatingClusterBlocks) {
//update exception mapping
LabelNode oldStartNode = block.getNode().start;
tryBlockStarts.remove(oldStartNode, block);
block.getNode().start = (LabelNode) newFinallyEnd.info;
remapStartLabel(oldStartNode, block);
patched.add(block);
//tryBlockStarts.put(block.getStartLabel(), block);
TryCatchBlockNode additionalTryCatchBlock =
new TryCatchBlockNode(oldStartNode, (LabelNode) newFinallyStart.info, block.getNode().handler, block.getNode().type);
TryCatchBlockNodeInfo newInfo = new TryCatchBlockNodeInfo(additionalTryCatchBlock, block.getOnlyCopyNotProcess());
addNewTryCatchNode(newInfo);
TryCatchBlockNodeInfo newInfo = new TryCatchBlockNodeInfo(additionalTryCatchBlock, false);
tryBlockStarts.put(additionalTryCatchBlock.start, newInfo);
tryBlockEnds.put(additionalTryCatchBlock.end, newInfo);
inlineFunTryBlockInfo.add(newInfo);
//TODO add assert
nextPrev = additionalTryCatchBlock.end;
coveringTryBlocks.pop();
}
sortTryCatchBlocks();
sortTryCatchBlocks(inlineFunTryBlockInfo);
return nextPrev;
}
private void patchTryBlocks(@NotNull LabelNode newStartLabelNode, @NotNull TryCatchBlockNodeInfo endNode) {
private void patchTryBlocks(@NotNull LabelNode newStartLabelNode, @NotNull TryCatchBlockNodeInfo endNode, boolean sort) {
LabelNode oldStart = endNode.getStartLabel();
endNode.getNode().start = newStartLabelNode;
remapStartLabel(oldStart, endNode);
tryBlockStarts.remove(oldStart, endNode);
tryBlockStarts.put(endNode.getNode().start, endNode);
TryCatchBlockNode endTryBlock = endNode.getNode();
TryCatchBlockNode additionalTryCatchBlock =
@@ -397,7 +334,10 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
endTryBlock.type);
TryCatchBlockNodeInfo newInfo = new TryCatchBlockNodeInfo(additionalTryCatchBlock, endNode.getOnlyCopyNotProcess());
addNewTryCatchNode(newInfo);
tryBlockStarts.put(newInfo.getStartLabel(), newInfo);
tryBlockEnds.put(newInfo.getEndLabel(), newInfo);
inlineFunTryBlockInfo.add(newInfo);
}
private static LabelNode getNewOrOldLabel(LabelNode oldHandler, @NotNull Set<LabelNode> labelsInsideFinally) {
@@ -410,9 +350,25 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
//Keep information about try blocks that cover current instruction -
// pushing and popping it to stack entering and exiting tryCatchBlock start and end labels
public void updateCoveringTryBlocks(@NotNull AbstractInsnNode curIns) {
super.updateCoveringTryBlocks(curIns, false);
checkCoveringBlocksInvariant(getCoveringFromInnermost());
private void updateCoveringTryBlocks(Stack<TryCatchBlockNodeInfo> coveringTryBlocks, AbstractInsnNode curIns) {
if (!(curIns instanceof LabelNode)) return;
List<TryCatchBlockNodeInfo> infos = tryBlockStarts.get((LabelNode) curIns);
for (TryCatchBlockNodeInfo startNode : infos) {
if (!startNode.getOnlyCopyNotProcess()) {
TryCatchBlockNodeInfo pop = coveringTryBlocks.pop();
//Temporary disabled cause during patched structure of exceptions changed
//assert startNode == pop : "Wrong try-catch structure " + startNode + " " + pop + " " + infos.size();
}
}
//Reversing list order cause we should pop external block before internal one
// (originally internal blocks goes before external one, such invariant preserved via sortTryCatchBlocks method)
for (TryCatchBlockNodeInfo info : Lists.reverse(tryBlockEnds.get((LabelNode) curIns))) {
if (!info.getOnlyCopyNotProcess()) {
coveringTryBlocks.add(info);
}
}
}
private static boolean hasFinallyBlocks(List<TryCatchBlockNodeInfo> inlineFunTryBlockInfo) {
@@ -424,6 +380,13 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
return false;
}
private void mapLabelsToTryCatchBlocks() {
for (TryCatchBlockNodeInfo block : inlineFunTryBlockInfo) {
tryBlockStarts.put(block.getNode().start, block);
tryBlockEnds.put(block.getNode().end, block);
}
}
//As described above all tryCatch group that have finally block also should contains tryCatchBlockNode with default handler.
//So we assume that instructions between end of tryCatchBlock and start of next tryCatchBlock with same default handler is required finally body.
//There is at least two tryCatchBlockNodes in list cause there is always tryCatchBlockNode on first instruction of default handler:
@@ -433,15 +396,6 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
@NotNull TryCatchBlockNodeInfo tryCatchBlock,
@NotNull List<TryCatchBlockNodeInfo> tryCatchBlocks
) {
if (tryCatchBlock.getOnlyCopyNotProcess()) {
AbstractInsnNode start = new LabelNode();
AbstractInsnNode end = new LabelNode();
InsnList insnList = new InsnList();
insnList.add(start);
insnList.add(end);
return new FinallyBlockInfo(start, end);
}
List<TryCatchBlockNodeInfo> sameDefaultHandler = new ArrayList<TryCatchBlockNodeInfo>();
LabelNode defaultHandler = null;
boolean afterStartBlock = false;
@@ -473,13 +427,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
AbstractInsnNode endFinallyChainExclusive = skipLastGotoIfNeeded(nextIntervalWithSameDefaultHandler.getNode().handler,
nextIntervalWithSameDefaultHandler.getNode().start);
FinallyBlockInfo finallyInfo = new FinallyBlockInfo(startFinallyChain.getNext(), endFinallyChainExclusive);
if (inlineFun.instructions.indexOf(finallyInfo.startIns) > inlineFun.instructions.indexOf(finallyInfo.endInsExclusive)) {
throw new AssertionError("Inconsistent finally: block end occurs before start " + traceInterval(finallyInfo.endInsExclusive, finallyInfo.startIns));
}
return finallyInfo;
return new FinallyBlockInfo(startFinallyChain.getNext(), endFinallyChainExclusive);
}
@NotNull
@@ -522,20 +470,22 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
private List<TryCatchBlockNodePosition> findTryCatchBlocksInlinedInFinally(@NotNull FinallyBlockInfo finallyInfo) {
List<TryCatchBlockNodePosition> result = new ArrayList<TryCatchBlockNodePosition>();
Map<TryCatchBlockNodeInfo, TryCatchBlockNodePosition> processedBlocks = new HashMap<TryCatchBlockNodeInfo, TryCatchBlockNodePosition>();
for (AbstractInsnNode curInstr = finallyInfo.startIns; curInstr != finallyInfo.endInsExclusive; curInstr = curInstr.getNext()) {
if (!(curInstr instanceof LabelNode)) continue;
LabelNode curLabel = (LabelNode) curInstr;
List<TryCatchBlockNodeInfo> startedTryBlocks = getStartNodes(curLabel);
for (TryCatchBlockNodeInfo block : startedTryBlocks) {
assert !processedBlocks.containsKey(block) : "Try catch block already processed before start label!!! " + block;
TryCatchBlockNodePosition info = new TryCatchBlockNodePosition(block, TryCatchPosition.START);
processedBlocks.put(block, info);
result.add(info);
List<TryCatchBlockNodeInfo> startedTryBlocks = tryBlockStarts.get(curLabel);
if (startedTryBlocks != null) {
for (TryCatchBlockNodeInfo block : startedTryBlocks) {
assert !processedBlocks.containsKey(block) : "Try catch block already processed before start label!!! " + block;
TryCatchBlockNodePosition info = new TryCatchBlockNodePosition(block, TryCatchPosition.START);
processedBlocks.put(block, info);
result.add(info);
}
}
List<TryCatchBlockNodeInfo> endedTryBlocks = getEndNodes(curLabel);
List<TryCatchBlockNodeInfo> endedTryBlocks = tryBlockEnds.get(curLabel);
if (endedTryBlocks == null) continue;
for (TryCatchBlockNodeInfo block : endedTryBlocks) {
TryCatchBlockNodePosition info = processedBlocks.get(block);
@@ -577,38 +527,21 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor<T
return result;
}
@Override
public int instructionIndex(@NotNull AbstractInsnNode inst) {
return inlineFun.instructions.indexOf(inst);
private void sortTryCatchBlocks(@NotNull List<TryCatchBlockNodeInfo> inlineFunTryBlockInfo) {
Comparator<TryCatchBlockNodeInfo> comp = new Comparator<TryCatchBlockNodeInfo>() {
@Override
public int compare(@NotNull TryCatchBlockNodeInfo t1, @NotNull TryCatchBlockNodeInfo t2) {
int result = inlineFun.instructions.indexOf(t1.getNode().handler) - inlineFun.instructions.indexOf(t2.getNode().handler);
if (result == 0) {
result = inlineFun.instructions.indexOf(t1.getNode().start) - inlineFun.instructions.indexOf(t2.getNode().start);
if (result == 0) {
assert false : "Error: support multicatch finallies!";
result = inlineFun.instructions.indexOf(t1.getNode().end) - inlineFun.instructions.indexOf(t2.getNode().end);
}
}
return result;
}
};
Collections.sort(inlineFunTryBlockInfo, comp);
}
private void substituteTryBlockNodes() {
inlineFun.tryCatchBlocks.clear();
for (TryCatchBlockNodeInfo info : getNonEmptyNodes()) {
inlineFun.tryCatchBlocks.add(info.getNode());
}
}
private static String traceInterval(AbstractInsnNode startNode, AbstractInsnNode stopNode) {
Textifier p = new Textifier();
TraceMethodVisitor visitor = new TraceMethodVisitor(p);
while (startNode != stopNode) {
startNode.accept(visitor);
startNode = startNode.getNext();
}
startNode.accept(visitor);
StringWriter out = new StringWriter();
p.print(new PrintWriter(out));
return out.toString();
}
@SuppressWarnings({"UnusedDeclaration", "UseOfSystemOutOrSystemErr"})
@TestOnly
private void flushCurrentState(@NotNull AbstractInsnNode curNonLocal) {
substituteTryBlockNodes();
System.out.println("Will process instruction at : " + inlineFun.instructions.indexOf(curNonLocal) + " " + curNonLocal.toString());
String text = getNodeText(inlineFun);
System.out.println(text);
}
}

View File

@@ -18,6 +18,9 @@ package org.jetbrains.jet.codegen.inline;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
import org.jetbrains.jet.codegen.AsmUtil;
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor;
@@ -29,15 +32,12 @@ import org.jetbrains.jet.lang.psi.JetFunctionLiteral;
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.CLOSURE;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.anonymousClassForFunction;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
public class LambdaInfo implements CapturedParamOwner, LabelOwner {
@@ -49,7 +49,7 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
@Nullable
public final String labelName;
private final CalculatedClosure closure;
public final CalculatedClosure closure;
private MethodNode node;

View File

@@ -356,6 +356,7 @@ public class MethodInliner {
AbstractInsnNode cur = node.instructions.getFirst();
int index = 0;
Set<LabelNode> possibleDeadLabels = new HashSet<LabelNode>();
while (cur != null) {
Frame<SourceValue> frame = sources[index];
@@ -415,12 +416,15 @@ public class MethodInliner {
if (frame == null) {
//clean dead code otherwise there is problems in unreachable finally block, don't touch label it cause try/catch/finally problems
if (prevNode.getType() == AbstractInsnNode.LABEL) {
//NB: Cause we generate exception table for default handler using gaps (see ExpressionCodegen.visitTryExpression)
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
//but as result all this labels will be merged into one (see KT-5863)
possibleDeadLabels.add((LabelNode) prevNode);
} else {
node.instructions.remove(prevNode);
}
} else {
//Cause we generate exception table for default handler using gaps (see ExpressionCodegen.visitTryExpression)
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
//but as result all this labels will be merged into one (see KT-5863)
possibleDeadLabels.remove(prevNode.getPrevious());
}
}
@@ -428,7 +432,7 @@ public class MethodInliner {
List<TryCatchBlockNode> blocks = node.tryCatchBlocks;
for (Iterator<TryCatchBlockNode> iterator = blocks.iterator(); iterator.hasNext(); ) {
TryCatchBlockNode block = iterator.next();
if (isEmptyTryInterval(block)) {
if (possibleDeadLabels.contains(block.start) && possibleDeadLabels.contains(block.end)) {
iterator.remove();
}
}
@@ -436,15 +440,6 @@ public class MethodInliner {
return node;
}
private static boolean isEmptyTryInterval(@NotNull TryCatchBlockNode tryCatchBlockNode) {
LabelNode start = tryCatchBlockNode.start;
AbstractInsnNode end = tryCatchBlockNode.end;
while (end != start && end instanceof LabelNode) {
end = end.getPrevious();
}
return start == end;
}
public LambdaInfo getLambdaIfExists(AbstractInsnNode insnNode) {
if (insnNode.getOpcode() == Opcodes.ALOAD) {
int varIndex = ((VarInsnNode) insnNode).var;
@@ -586,11 +581,11 @@ public class MethodInliner {
@NotNull
//process local and global returns (local substituted with goto end-label global kept unchanged)
public static List<PointForExternalFinallyBlocks> processReturns(@NotNull MethodNode node, @NotNull LabelOwner labelOwner, boolean remapReturn, Label endLabel) {
public static List<ExternalFinallyBlockInfo> processReturns(@NotNull MethodNode node, @NotNull LabelOwner labelOwner, boolean remapReturn, Label endLabel) {
if (!remapReturn) {
return Collections.emptyList();
}
List<PointForExternalFinallyBlocks> result = new ArrayList<PointForExternalFinallyBlocks>();
List<ExternalFinallyBlockInfo> result = new ArrayList<ExternalFinallyBlockInfo>();
InsnList instructions = node.instructions;
AbstractInsnNode insnNode = instructions.getFirst();
while (insnNode != null) {
@@ -621,7 +616,7 @@ public class MethodInliner {
}
//genetate finally block before nonLocalReturn flag/return/goto
result.add(new PointForExternalFinallyBlocks(isLocalReturn ? insnNode : insnNode.getPrevious(), getReturnType(insnNode.getOpcode())
result.add(new ExternalFinallyBlockInfo(isLocalReturn ? insnNode : insnNode.getPrevious(), getReturnType(insnNode.getOpcode())
));
}
insnNode = insnNode.getNext();
@@ -629,14 +624,13 @@ public class MethodInliner {
return result;
}
//Place to insert finally blocks from try blocks that wraps inline fun call
public static class PointForExternalFinallyBlocks {
public static class ExternalFinallyBlockInfo {
final AbstractInsnNode beforeIns;
final Type returnType;
public PointForExternalFinallyBlocks(AbstractInsnNode beforeIns, Type returnType) {
public ExternalFinallyBlockInfo(AbstractInsnNode beforeIns, Type returnType) {
this.beforeIns = beforeIns;
this.returnType = returnType;
}

View File

@@ -33,7 +33,7 @@ trait IntervalWithHandler {
val startLabel: LabelNode
val endLabel: LabelNode
val handler: LabelNode
val type: String?
val `type`: String?
}
class TryCatchBlockNodeInfo(val node: TryCatchBlockNode, val onlyCopyNotProcess: Boolean) : IntervalWithHandler {
@@ -43,16 +43,16 @@ class TryCatchBlockNodeInfo(val node: TryCatchBlockNode, val onlyCopyNotProcess:
override val endLabel: LabelNode
get() = node.end
override val handler: LabelNode
get() = node.handler
override val type: String?
get() = node.type
get() = node.handler!!
override val `type`: String?
get() = node.`type`
}
class TryCatchBlockNodePosition(val nodeInfo: TryCatchBlockNodeInfo, var position: TryCatchPosition): IntervalWithHandler by nodeInfo
class TryBlockCluster<T : IntervalWithHandler>(val blocks: MutableList<T>) {
val defaultHandler: T?
get() = blocks.firstOrNull() { it.type == null }
get() = blocks.firstOrNull() { it.`type` == null }
}

View File

@@ -39,18 +39,10 @@ public class ArrayGet extends IntrinsicMethod {
List<JetExpression> arguments,
StackValue receiver
) {
int argumentIndex;
if (receiver == null || receiver == StackValue.none()) {
receiver = codegen.gen(arguments.get(0));
argumentIndex = 1;
} else {
argumentIndex = 0;
}
receiver.put(receiver.type, v);
Type type = correctElementType(receiver.type);
codegen.gen(arguments.get(argumentIndex), Type.INT_TYPE);
codegen.gen(arguments.get(0), Type.INT_TYPE);
v.aload(type);

View File

@@ -58,8 +58,8 @@ public class Clone extends IntrinsicMethod {
}
private static boolean isSuperCall(@NotNull ResolvedCall<?> resolvedCall) {
ReceiverValue dispatchReceiver = resolvedCall.getDispatchReceiver();
return dispatchReceiver instanceof ExpressionReceiver &&
((ExpressionReceiver) dispatchReceiver).getExpression() instanceof JetSuperExpression;
ReceiverValue thisObject = resolvedCall.getThisObject();
return thisObject instanceof ExpressionReceiver &&
((ExpressionReceiver) thisObject).getExpression() instanceof JetSuperExpression;
}
}

View File

@@ -18,21 +18,18 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.psi.JetParenthesizedExpression;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
import static org.jetbrains.jet.codegen.AsmUtil.genIncrement;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.lang.resolve.BindingContext.EXPRESSION_TYPE;
public class Increment extends IntrinsicMethod {
private final int myDelta;
@@ -54,15 +51,15 @@ public class Increment extends IntrinsicMethod {
assert isPrimitive(returnType) : "Return type of Increment intrinsic should be of primitive type : " + returnType;
if (arguments.size() > 0) {
JetExpression operand = JetPsiUtil.deparenthesize(arguments.get(0));
JetExpression operand = arguments.get(0);
while (operand instanceof JetParenthesizedExpression) {
operand = ((JetParenthesizedExpression) operand).getExpression();
}
if (operand instanceof JetReferenceExpression && returnType == Type.INT_TYPE) {
int index = codegen.indexOfLocal((JetReferenceExpression) operand);
if (index >= 0) {
JetType operandType = codegen.getBindingContext().get(EXPRESSION_TYPE, operand);
if (operandType != null && KotlinBuiltIns.getInstance().isPrimitiveType(operandType)) {
StackValue.preIncrement(index, myDelta).put(returnType, v);
return returnType;
}
StackValue.preIncrement(index, myDelta).put(returnType, v);
return returnType;
}
}
StackValue value = codegen.genQualified(receiver, operand);

View File

@@ -106,7 +106,7 @@ class IntrinsicsMap {
@Nullable
private static FqNameUnsafe getReceiverParameterFqName(@NotNull CallableMemberDescriptor descriptor) {
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
if (receiverParameter == null) return null;
ClassifierDescriptor classifier = receiverParameter.getType().getConstructor().getDeclarationDescriptor();

View File

@@ -19,7 +19,6 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.AsmUtil;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression;
@@ -45,10 +44,6 @@ public class JavaClassProperty extends IntrinsicMethod {
) {
Type type = receiver.type;
if (isPrimitive(type)) {
if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) {
receiver.put(type, v);
AsmUtil.pop(v, type);
}
v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;");
}
else {

View File

@@ -144,13 +144,9 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
private static boolean isBoxing(@NotNull AbstractInsnNode insn) {
if (insn.getOpcode() != Opcodes.INVOKESTATIC) return false;
MethodInsnNode node = (MethodInsnNode) insn;
MethodInsnNode methodInsnNode = (MethodInsnNode) insn;
return isWrapperClassName(node.owner) && "valueOf".equals(node.name) &&
Type.getMethodDescriptor(
Type.getObjectType(node.owner),
AsmUtil.unboxType(Type.getObjectType(node.owner))
).equals(node.desc);
return isWrapperClassName(methodInsnNode.owner) && "valueOf".equals(methodInsnNode.name);
}
private static boolean isNextMethodCallOfProgressionIterator(

View File

@@ -21,6 +21,7 @@ import com.intellij.util.containers.MultiMap
import org.jetbrains.jet.codegen.ClassBuilderFactory
import org.jetbrains.jet.codegen.SignatureCollectingClassBuilderFactory
import org.jetbrains.jet.lang.descriptors.*
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.resolve.java.diagnostics.*
import java.util.*
@@ -30,12 +31,11 @@ import org.jetbrains.jet.utils.addIfNotNull
import org.jetbrains.jet.codegen.ClassBuilderMode
import org.jetbrains.jet.lang.resolve.java.descriptor.SamAdapterDescriptor
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
import org.jetbrains.jet.lang.diagnostics.DiagnosticSink
class BuilderFactoryForDuplicateSignatureDiagnostics(
builderFactory: ClassBuilderFactory,
bindingContext: BindingContext,
private val diagnostics: DiagnosticSink
private val diagnostics: DiagnosticHolder
) : SignatureCollectingClassBuilderFactory(builderFactory) {
// Avoid errors when some classes are not loaded for some reason

View File

@@ -26,7 +26,7 @@ import org.jetbrains.jet.codegen.optimization.OptimizationClassBuilderFactory;
import org.jetbrains.jet.codegen.when.MappingsClassesForWhenByEnum;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.diagnostics.DiagnosticSink;
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.reflect.ReflectionTypes;
@@ -120,7 +120,7 @@ public class GenerationState {
@NotNull List<JetFile> files
) {
this(project, builderFactory, Progress.DEAF, module, bindingContext, files, true, true, GenerateClassFilter.GENERATE_ALL,
false, false, null, null, DiagnosticSink.DO_NOTHING, null);
false, false, null, null, DiagnosticHolder.DO_NOTHING, null);
}
public GenerationState(
@@ -137,7 +137,7 @@ public class GenerationState {
boolean disableOptimization,
@Nullable Collection<FqName> packagesWithRemovedFiles,
@Nullable String moduleId,
@NotNull DiagnosticSink diagnostics,
@NotNull DiagnosticHolder diagnostics,
@Nullable File outDirectory
) {
this.project = project;

View File

@@ -159,9 +159,7 @@ public class JetTypeMapper {
private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable BothSignatureWriter sw) {
JetType returnType = descriptor.getReturnType();
assert returnType != null : "Function has no return type: " + descriptor;
if (returnType.equals(KotlinBuiltIns.getInstance().getUnitType())
&& !TypeUtils.isNullableType(returnType)
&& !(descriptor instanceof PropertyGetterDescriptor)) {
if (returnType.equals(KotlinBuiltIns.getInstance().getUnitType()) && !(descriptor instanceof PropertyGetterDescriptor)) {
if (sw != null) {
sw.writeAsmType(Type.VOID_TYPE);
}
@@ -222,7 +220,7 @@ public class JetTypeMapper {
if (descriptor instanceof ClassDescriptor) {
FqNameUnsafe className = DescriptorUtils.getFqName(descriptor);
if (className.isSafe()) {
known = KotlinToJavaTypesMap.getInstance().getJavaAnalog(className.toSafe(), TypeUtils.isNullableType(jetType));
known = KotlinToJavaTypesMap.getInstance().getJavaAnalog(className.toSafe(), jetType.isNullable());
}
}
@@ -526,7 +524,7 @@ public class JetTypeMapper {
Type calleeType = isLocalNamedFun(functionDescriptor) ? owner : null;
Type receiverParameterType;
ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getExtensionReceiverParameter();
ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getReceiverParameter();
if (receiverParameter != null) {
receiverParameterType = mapType(receiverParameter.getType());
}
@@ -626,7 +624,7 @@ public class JetTypeMapper {
sw.writeParametersStart();
writeThisIfNeeded(f, kind, sw);
ReceiverParameterDescriptor receiverParameter = f.getExtensionReceiverParameter();
ReceiverParameterDescriptor receiverParameter = f.getReceiverParameter();
if (receiverParameter != null) {
writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.getType());
}
@@ -666,7 +664,7 @@ public class JetTypeMapper {
public Method mapDefaultMethod(@NotNull FunctionDescriptor functionDescriptor, @NotNull OwnerKind kind, @NotNull CodegenContext<?> context) {
Method jvmSignature = mapSignature(functionDescriptor, kind).getAsmMethod();
Type ownerType = mapOwner(functionDescriptor, isCallInsideSameModuleAsDeclared(functionDescriptor, context, getOutDirectory()));
String descriptor = getDefaultDescriptor(jvmSignature, functionDescriptor.getExtensionReceiverParameter() != null);
String descriptor = getDefaultDescriptor(jvmSignature, functionDescriptor.getReceiverParameter() != null);
boolean isConstructor = "<init>".equals(jvmSignature.getName());
if (!isStaticMethod(kind, functionDescriptor) && !isConstructor) {
descriptor = descriptor.replace("(", "(" + ownerType.getDescriptor());
@@ -685,7 +683,7 @@ public class JetTypeMapper {
//noinspection ConstantConditions
if (!KotlinBuiltIns.getInstance().isPrimitiveType(descriptor.getReturnType())) return false;
for (FunctionDescriptor overridden : getAllOverriddenDescriptors(descriptor)) {
for (FunctionDescriptor overridden : OverrideResolver.getAllOverriddenDescriptors(descriptor)) {
//noinspection ConstantConditions
if (!KotlinBuiltIns.getInstance().isPrimitiveType(overridden.getOriginal().getReturnType())) return true;
}
@@ -715,7 +713,7 @@ public class JetTypeMapper {
if (kind == OwnerKind.TRAIT_IMPL) {
thisType = getTraitImplThisParameterClass((ClassDescriptor) descriptor.getContainingDeclaration());
}
else if (isAccessor(descriptor) && descriptor.getDispatchReceiverParameter() != null) {
else if (isAccessor(descriptor) && descriptor.getExpectedThisObject() != null) {
thisType = (ClassDescriptor) descriptor.getContainingDeclaration();
}
else return;
@@ -806,7 +804,7 @@ public class JetTypeMapper {
private void writeAdditionalConstructorParameters(@NotNull ConstructorDescriptor descriptor, @NotNull BothSignatureWriter sw) {
CalculatedClosure closure = bindingContext.get(CodegenBinding.CLOSURE, descriptor.getContainingDeclaration());
ClassDescriptor captureThis = getDispatchReceiverParameterForConstructorCall(descriptor, closure);
ClassDescriptor captureThis = getExpectedThisObjectForConstructorCall(descriptor, closure);
if (captureThis != null) {
writeParameter(sw, JvmMethodParameterKind.OUTER, captureThis.getDefaultType());
}
@@ -932,7 +930,7 @@ public class JetTypeMapper {
return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
}
else if (descriptor instanceof PropertyDescriptor || descriptor instanceof FunctionDescriptor) {
ReceiverParameterDescriptor receiverParameter = ((CallableDescriptor) descriptor).getExtensionReceiverParameter();
ReceiverParameterDescriptor receiverParameter = ((CallableDescriptor) descriptor).getReceiverParameter();
assert receiverParameter != null : "Callable should have a receiver parameter: " + descriptor;
return StackValue.sharedTypeForType(mapType(receiverParameter.getType()));
}

View File

@@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.NullValue;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
@@ -136,7 +135,7 @@ abstract public class SwitchCodegen {
assert subjectJetType != null : "subject type can't be null (i.e. void)";
if (TypeUtils.isNullableType(subjectJetType)) {
if (subjectJetType.isNullable()) {
int nullEntryIndex = findNullEntryIndex(expression);
Label nullLabel = nullEntryIndex == -1 ? defaultLabel : entryLabels.get(nullEntryIndex);
Label notNullLabel = new Label();

View File

@@ -23,6 +23,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
public abstract class CommonCompilerArguments {
public static final String PLUGIN_OPTION_FORMAT = "<pluginId>:<optionName>=<value>";
@Argument(value = "nowarn", description = "Generate no warnings")
public boolean suppressWarnings;
@@ -38,8 +40,13 @@ public abstract class CommonCompilerArguments {
@Argument(value = "X", description = "Print a synopsis of advanced options")
public boolean extraHelp;
@Argument(value = "Xno-inline", description = "Disable method inlining")
public boolean noInline;
@Argument(value = "Xplugin", description = "Load a plugin from the given classpath")
@ValueDescription("<path>")
public String[] pluginClasspaths;
@Argument(value = "P", description = "Pass an option to a plugin")
@ValueDescription(PLUGIN_OPTION_FORMAT)
public String[] pluginOptions;
public List<String> freeArgs = new SmartList<String>();

View File

@@ -63,6 +63,9 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
@Argument(value = "Xno-param-assertions", description = "Don't generate not-null assertions on parameters of methods accessible from Java")
public boolean noParamAssertions;
@Argument(value = "Xno-inline", description = "Disable method inlining")
public boolean noInline;
@Argument(value = "Xno-optimize", description = "Disable optimizations")
public boolean noOptimize;

View File

@@ -116,8 +116,14 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
errStream.print(messageRenderer.renderPreamble());
printVersionIfNeeded(errStream, arguments, messageRenderer);
MessageCollector collector = new PrintingMessageCollector(errStream, messageRenderer, arguments.verbose);
if (arguments.suppressWarnings) {
collector = new FilteringMessageCollector(collector, Predicates.equalTo(CompilerMessageSeverity.WARNING));
}
try {
return exec(collector, services, arguments);
}
@@ -128,12 +134,6 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
@NotNull
public ExitCode exec(@NotNull MessageCollector messageCollector, @NotNull Services services, @NotNull A arguments) {
printVersionIfNeeded(messageCollector, arguments);
if (arguments.suppressWarnings) {
messageCollector = new FilteringMessageCollector(messageCollector, Predicates.equalTo(CompilerMessageSeverity.WARNING));
}
GroupingMessageCollector groupingCollector = new GroupingMessageCollector(messageCollector);
try {
Disposable rootDisposable = Disposer.newDisposable();
@@ -164,12 +164,17 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
@NotNull Disposable rootDisposable
);
protected void printVersionIfNeeded(@NotNull MessageCollector messageCollector, @NotNull A arguments) {
if (!arguments.version) return;
messageCollector.report(CompilerMessageSeverity.INFO,
"Kotlin Compiler version " + KotlinVersion.VERSION,
CompilerMessageLocation.NO_LOCATION);
protected void printVersionIfNeeded(
@NotNull PrintStream errStream,
@NotNull A arguments,
@NotNull MessageRenderer messageRenderer
) {
if (arguments.version) {
String versionMessage = messageRenderer.render(CompilerMessageSeverity.INFO,
"Kotlin Compiler version " + KotlinVersion.VERSION,
CompilerMessageLocation.NO_LOCATION);
errStream.println(versionMessage);
}
}
/**

View File

@@ -23,7 +23,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import kotlin.Function0;
@@ -49,6 +48,7 @@ import org.jetbrains.jet.config.Services;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.k2js.analyze.TopDownAnalyzerFacadeForJS;
import org.jetbrains.k2js.config.*;
import org.jetbrains.k2js.facade.K2JSTranslator;
import org.jetbrains.k2js.facade.MainCallParameters;
import java.io.File;
@@ -58,7 +58,6 @@ import java.util.List;
import static org.jetbrains.jet.cli.common.ExitCode.COMPILATION_ERROR;
import static org.jetbrains.jet.cli.common.ExitCode.OK;
import static org.jetbrains.jet.cli.common.messages.CompilerMessageLocation.NO_LOCATION;
import static org.jetbrains.k2js.facade.K2JSTranslator.translateWithMainCallParameters;
public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
@@ -171,8 +170,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
@Nullable File outputPostfix
) {
try {
//noinspection unchecked
return translateWithMainCallParameters(mainCall, sourceFiles, outputFile, outputPrefix, outputPostfix, config, Consumer.EMPTY_CONSUMER);
return K2JSTranslator.translateWithMainCallParameters(mainCall, sourceFiles, outputFile, outputPrefix, outputPostfix, config);
}
catch (Exception e) {
throw new RuntimeException(e);
@@ -198,14 +196,12 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
}
EcmaVersion ecmaVersion = EcmaVersion.defaultVersion();
String moduleId = FileUtil.getNameWithoutExtension(new File(arguments.outputFile));
boolean inlineEnabled = !arguments.noInline;
if (arguments.libraryFiles != null) {
return new LibrarySourcesConfig(project, moduleId, Arrays.asList(arguments.libraryFiles), ecmaVersion, arguments.sourceMap, inlineEnabled);
return new LibrarySourcesConfig(project, moduleId, Arrays.asList(arguments.libraryFiles), ecmaVersion, arguments.sourceMap);
}
else {
// lets discover the JS library definitions on the classpath
return new ClassPathLibraryDefintionsConfig(project, moduleId, ecmaVersion, arguments.sourceMap, inlineEnabled);
return new ClassPathLibraryDefintionsConfig(project, moduleId, ecmaVersion, arguments.sourceMap);
}
}
@@ -217,4 +213,4 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
return MainCallParameters.mainWithoutArguments();
}
}
}
}

View File

@@ -40,6 +40,7 @@ import org.jetbrains.jet.lang.resolve.kotlin.incremental.cache.IncrementalCacheP
import org.jetbrains.jet.utils.KotlinPaths;
import org.jetbrains.jet.utils.KotlinPathsFromHomeDir;
import org.jetbrains.jet.utils.PathUtil;
import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException;
import java.io.File;
import java.util.Collections;
@@ -87,6 +88,15 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
return INTERNAL_ERROR;
}
try {
PluginCliParser.processPluginOptions(arguments, configuration);
}
catch (CliOptionProcessingException e) {
// TODO Print usage?
messageCollector.report(CompilerMessageSeverity.ERROR, e.getMessage(), CompilerMessageLocation.NO_LOCATION);
return INTERNAL_ERROR;
}
if (!arguments.script &&
arguments.module == null &&
arguments.freeArgs.isEmpty() &&
@@ -168,7 +178,7 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
}
}
private static void putAdvancedOptions(@NotNull CompilerConfiguration configuration, @NotNull K2JVMCompilerArguments arguments) {
public static void putAdvancedOptions(@NotNull CompilerConfiguration configuration, @NotNull K2JVMCompilerArguments arguments) {
configuration.put(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, arguments.noCallAssertions);
configuration.put(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, arguments.noParamAssertions);
configuration.put(JVMConfigurationKeys.DISABLE_INLINE, arguments.noInline);

View File

@@ -0,0 +1,109 @@
/*
* Copyright 2010-2014 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.jet.cli.jvm
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
import org.jetbrains.jet.cli.common.arguments.CommonCompilerArguments
import kotlin.platform.*
import java.util.jar.JarFile
import java.util.jar.Attributes
import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
import java.util.regex.Pattern
import org.jetbrains.jet.utils.valuesToMap
import org.jetbrains.jet.config.CompilerConfiguration
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.compiler.plugin.CliOption
public object PluginCliParser {
public val PLUGIN_ARGUMENT_PREFIX: String = "plugin:"
private fun getCommandLineProcessors(arguments: CommonCompilerArguments): Collection<CommandLineProcessor> {
return arguments.pluginClasspaths!!.map {
loadCommandLineProcessor(JarFile(it).getManifest()?.getAttributes("org.jetbrains.kotlin.compiler.plugin"))
}.filterNotNull()
}
private fun loadCommandLineProcessor(attributes: Attributes?): CommandLineProcessor? {
if (attributes == null) return null
val processorClassName = attributes.getValue("CommandLineProcessor")
if (processorClassName == null) return null
try {
val processorClass = Class.forName(processorClassName)
return processorClass.newInstance() as CommandLineProcessor
}
catch (e: Throwable) {
throw CliOptionProcessingException("Loading plugin component failed: $processorClassName", e)
}
}
[platformStatic]
fun processPluginOptions(arguments: CommonCompilerArguments, configuration: CompilerConfiguration) {
val optionValuesByPlugin = arguments.pluginOptions!!.map { parsePluginOption(it) }.groupBy {
if (it == null) throw CliOptionProcessingException("Wrong plugin option format: $it, should be ${CommonCompilerArguments.PLUGIN_OPTION_FORMAT}")
it.optionName
}
val processors = getCommandLineProcessors(arguments)
for (processor in processors) {
val declaredOptions = processor.pluginOptions.valuesToMap { it.name }
val optionsToValues = MultiMap<CliOption, PluginOptionValue>()
for (optionValue in optionValuesByPlugin[processor.pluginId].orEmpty()) {
val option = declaredOptions[optionValue!!.optionName]
if (option == null) {
throw CliOptionProcessingException("Unsupported plugin option: $optionValue")
}
optionsToValues.putValue(option, optionValue)
}
for (option in processor.pluginOptions) {
val values = optionsToValues[option]
if (option.required && values.isEmpty()) {
throw CliOptionProcessingException("Required plugin option not present: ${processor.pluginId}:${option.name}")
}
if (!option.allowMultipleOccurrences && values.size() > 1) {
throw CliOptionProcessingException("Multiple values not allowed for plugin option ${processor.pluginId}:${option.name}")
}
for (value in values) {
processor.processOption(option, value.value, configuration)
}
}
}
}
private class PluginOptionValue(
val pluginId: String,
val optionName: String,
val value: String
) {
override fun toString() = "$pluginId:$optionName=$value"
}
private fun parsePluginOption(argumentValue: String): PluginOptionValue? {
val pattern = Pattern.compile("""^([^:]*):([^=]*)=(.*)$""")
val matcher = pattern.matcher(argumentValue)
if (matcher.matches()) {
return PluginOptionValue(matcher.group(1)!!, matcher.group(2)!!, matcher.group(3)!!)
}
return null
}
}

View File

@@ -48,8 +48,10 @@ import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
import org.jetbrains.jet.cli.common.messages.MessageCollector;
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
import org.jetbrains.jet.codegen.extensions.ExpressionCodegenExtension;
import org.jetbrains.jet.config.CommonConfigurationKeys;
import org.jetbrains.jet.config.CompilerConfiguration;
import org.jetbrains.jet.extensions.ExternalDeclarationsProvider;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -59,6 +61,7 @@ import org.jetbrains.jet.lang.resolve.lazy.declarations.CliDeclarationProviderFa
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactoryService;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.utils.PathUtil;
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar;
import java.io.File;
import java.util.ArrayList;
@@ -208,6 +211,13 @@ public class JetCoreEnvironment {
configuration.getList(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY));
project.registerService(VirtualFileFinderFactory.class, new CliVirtualFileFinderFactory(classPath));
for (ComponentRegistrar registrar : configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) {
registrar.registerProjectComponents(project, configuration);
}
ExternalDeclarationsProvider.OBJECT$.registerExtensionPoint(project);
ExpressionCodegenExtension.OBJECT$.registerExtensionPoint(project);
}
// made public for Upsource

View File

@@ -7,9 +7,8 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="android-plugin" level="project" />
<orderEntry type="library" name="kotlin-runtime" level="project" />
<orderEntry type="library" name="idea-full" level="project" />
<orderEntry type="library" name="intellij-core" level="project" />
<orderEntry type="module" module-name="frontend" />
</component>
</module>

View File

@@ -47,7 +47,7 @@ import javax.annotation.PreDestroy;
/* This file is generated by org.jetbrains.jet.generators.injectors.InjectorsPackage. DO NOT EDIT! */
@SuppressWarnings("all")
public class InjectorForJavaDescriptorResolver {
private final Project project;
private final BindingTrace bindingTrace;
private final GlobalContextImpl globalContext;
@@ -73,7 +73,7 @@ public class InjectorForJavaDescriptorResolver {
private final AnnotationDescriptorLoader annotationDescriptorLoader;
private final DescriptorLoadersStorage descriptorLoadersStorage;
private final ConstantDescriptorLoader constantDescriptorLoader;
public InjectorForJavaDescriptorResolver(
@NotNull Project project,
@NotNull BindingTrace bindingTrace
@@ -138,25 +138,25 @@ public class InjectorForJavaDescriptorResolver {
javaClassFinder.initialize();
}
@PreDestroy
public void destroy() {
}
public GlobalContextImpl getGlobalContext() {
return this.globalContext;
}
public ModuleDescriptorImpl getModule() {
return this.module;
}
public JavaDescriptorResolver getJavaDescriptorResolver() {
return this.javaDescriptorResolver;
}
public JavaClassFinderImpl getJavaClassFinder() {
return this.javaClassFinder;
}
}

View File

@@ -36,7 +36,6 @@ import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedMethodSignatureCheck
import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedExternalAnnotationResolver;
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaPropertyInitializerEvaluatorImpl;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSourceElementFactoryImpl;
import org.jetbrains.jet.lang.resolve.java.JavaFlexibleTypeCapabilitiesProvider;
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
@@ -72,7 +71,7 @@ import javax.annotation.PreDestroy;
/* This file is generated by org.jetbrains.jet.generators.injectors.InjectorsPackage. DO NOT EDIT! */
@SuppressWarnings("all")
public class InjectorForLazyResolveWithJava {
private final Project project;
private final GlobalContext globalContext;
private final StorageManager storageManager;
@@ -93,7 +92,6 @@ public class InjectorForLazyResolveWithJava {
private final PsiBasedExternalAnnotationResolver psiBasedExternalAnnotationResolver;
private final JavaPropertyInitializerEvaluatorImpl javaPropertyInitializerEvaluator;
private final JavaSourceElementFactoryImpl javaSourceElementFactory;
private final JavaFlexibleTypeCapabilitiesProvider javaFlexibleTypeCapabilitiesProvider;
private final AdditionalCheckerProvider additionalCheckerProvider;
private final AnnotationResolver annotationResolver;
private final CallResolver callResolver;
@@ -123,7 +121,7 @@ public class InjectorForLazyResolveWithJava {
private final AnnotationDescriptorLoader annotationDescriptorLoader;
private final DescriptorLoadersStorage descriptorLoadersStorage;
private final ConstantDescriptorLoader constantDescriptorLoader;
public InjectorForLazyResolveWithJava(
@NotNull Project project,
@NotNull GlobalContext globalContext,
@@ -156,7 +154,6 @@ public class InjectorForLazyResolveWithJava {
this.globalJavaResolverContext = new GlobalJavaResolverContext(storageManager, javaClassFinder, virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, lazyResolveBasedCache, javaPropertyInitializerEvaluator, javaSourceElementFactory, moduleClassResolver);
this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, module);
this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, module);
this.javaFlexibleTypeCapabilitiesProvider = new JavaFlexibleTypeCapabilitiesProvider();
this.additionalCheckerProvider = org.jetbrains.jet.lang.resolve.kotlin.JavaDeclarationCheckerProvider.INSTANCE$;
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
@@ -253,7 +250,6 @@ public class InjectorForLazyResolveWithJava {
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver);
typeResolver.setFlexibleTypeCapabilitiesProvider(javaFlexibleTypeCapabilitiesProvider);
typeResolver.setModuleDescriptor(module);
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
@@ -281,17 +277,17 @@ public class InjectorForLazyResolveWithJava {
javaClassFinder.initialize();
}
@PreDestroy
public void destroy() {
}
public ResolveSession getResolveSession() {
return this.resolveSession;
}
public JavaDescriptorResolver getJavaDescriptorResolver() {
return this.javaDescriptorResolver;
}
}

View File

@@ -38,7 +38,6 @@ import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedExternalAnnotationRe
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaPropertyInitializerEvaluatorImpl;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSourceElementFactoryImpl;
import org.jetbrains.jet.lang.resolve.java.lazy.SingleModuleClassResolver;
import org.jetbrains.jet.lang.resolve.java.JavaFlexibleTypeCapabilitiesProvider;
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder;
import org.jetbrains.jet.lang.resolve.BodyResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
@@ -60,7 +59,6 @@ import org.jetbrains.jet.lang.resolve.calls.CallCompleter;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
import org.jetbrains.jet.lang.resolve.ControlFlowAnalyzer;
import org.jetbrains.jet.lang.resolve.DeclarationsChecker;
import org.jetbrains.jet.lang.resolve.ModifiersChecker;
import org.jetbrains.jet.lang.resolve.FunctionAnalyzerExtension;
import org.jetbrains.jet.lang.resolve.ScriptBodyResolver;
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
@@ -83,7 +81,7 @@ import javax.annotation.PreDestroy;
/* This file is generated by org.jetbrains.jet.generators.injectors.InjectorsPackage. DO NOT EDIT! */
@SuppressWarnings("all")
public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnalyzer {
private final Project project;
private final GlobalContext globalContext;
private final StorageManager storageManager;
@@ -106,7 +104,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private final JavaPropertyInitializerEvaluatorImpl javaPropertyInitializerEvaluator;
private final JavaSourceElementFactoryImpl javaSourceElementFactory;
private final SingleModuleClassResolver singleModuleClassResolver;
private final JavaFlexibleTypeCapabilitiesProvider javaFlexibleTypeCapabilitiesProvider;
private final VirtualFileFinder virtualFileFinder;
private final BodyResolver bodyResolver;
private final AnnotationResolver annotationResolver;
@@ -128,7 +125,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private final CandidateResolver candidateResolver;
private final ControlFlowAnalyzer controlFlowAnalyzer;
private final DeclarationsChecker declarationsChecker;
private final ModifiersChecker modifiersChecker;
private final FunctionAnalyzerExtension functionAnalyzerExtension;
private final ScriptBodyResolver scriptBodyResolver;
private final DeclarationResolver declarationResolver;
@@ -145,7 +141,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private final AnnotationDescriptorLoader annotationDescriptorLoader;
private final DescriptorLoadersStorage descriptorLoadersStorage;
private final ConstantDescriptorLoader constantDescriptorLoader;
public InjectorForTopDownAnalyzerForJvm(
@NotNull Project project,
@NotNull GlobalContext globalContext,
@@ -181,7 +177,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.deserializationGlobalContextForJava = new DeserializationGlobalContextForJava(storageManager, getModuleDescriptor(), javaClassDataFinder, annotationDescriptorLoader, constantDescriptorLoader, lazyJavaPackageFragmentProvider);
this.additionalCheckerProvider = org.jetbrains.jet.lang.resolve.kotlin.JavaDeclarationCheckerProvider.INSTANCE$;
this.globalSearchScope = com.intellij.psi.search.GlobalSearchScope.allScope(project);
this.javaFlexibleTypeCapabilitiesProvider = new JavaFlexibleTypeCapabilitiesProvider();
this.bodyResolver = new BodyResolver();
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
@@ -202,7 +197,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.callCompleter = new CallCompleter(argumentTypeResolver, candidateResolver);
this.controlFlowAnalyzer = new ControlFlowAnalyzer();
this.declarationsChecker = new DeclarationsChecker();
this.modifiersChecker = new ModifiersChecker(bindingTrace, additionalCheckerProvider);
this.functionAnalyzerExtension = new FunctionAnalyzerExtension();
this.scriptBodyResolver = new ScriptBodyResolver();
this.declarationResolver = new DeclarationResolver();
@@ -306,7 +300,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver);
typeResolver.setFlexibleTypeCapabilitiesProvider(javaFlexibleTypeCapabilitiesProvider);
typeResolver.setModuleDescriptor(moduleDescriptor);
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
@@ -314,8 +307,8 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
controlFlowAnalyzer.setTrace(bindingTrace);
declarationsChecker.setAdditionalCheckerProvider(additionalCheckerProvider);
declarationsChecker.setDescriptorResolver(descriptorResolver);
declarationsChecker.setModifiersChecker(modifiersChecker);
declarationsChecker.setTrace(bindingTrace);
functionAnalyzerExtension.setTrace(bindingTrace);
@@ -365,29 +358,29 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
javaClassFinder.initialize();
}
@PreDestroy
public void destroy() {
}
public ModuleDescriptor getModuleDescriptor() {
return this.moduleDescriptor;
}
public TopDownAnalyzer getTopDownAnalyzer() {
return this.topDownAnalyzer;
}
public LazyTopDownAnalyzer getLazyTopDownAnalyzer() {
return this.lazyTopDownAnalyzer;
}
public JavaDescriptorResolver getJavaDescriptorResolver() {
return this.javaDescriptorResolver;
}
public DeserializationGlobalContextForJava getDeserializationGlobalContextForJava() {
return this.deserializationGlobalContextForJava;
}
}

View File

@@ -1,25 +0,0 @@
/*
* Copyright 2010-2014 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.jet.lang.resolve.java
import org.jetbrains.jet.lang.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider
import org.jetbrains.jet.lang.types.FlexibleTypeCapabilities
import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaTypeResolver
public class JavaFlexibleTypeCapabilitiesProvider : FlexibleTypeCapabilitiesProvider() {
override fun getCapabilities(): FlexibleTypeCapabilities = LazyJavaTypeResolver.FlexibleJavaClassifierTypeCapabilities
}

View File

@@ -33,6 +33,10 @@ import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.jet.analyzer.ModuleInfo
import org.jetbrains.jet.analyzer.ModuleContent
import org.jetbrains.jet.di.InjectorForLazyResolveWithJava
import org.jetbrains.jet.lang.psi.JetFile
import java.util.ArrayList
import org.jetbrains.jet.extensions.ExternalDeclarationsProvider
import kotlin.platform.platformStatic
public class JvmResolverForModule(
override val lazyResolveSession: ResolveSession,
@@ -54,8 +58,9 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmResolverForModule, JvmPlatfo
resolverForProject: ResolverForProject<M, JvmResolverForModule>
): JvmResolverForModule {
val (syntheticFiles, moduleContentScope) = moduleContent
val filesToAnalyze = getAllFilesToAnalyze(project, syntheticFiles)
val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory(
project, globalContext.storageManager, syntheticFiles, moduleContentScope
project, globalContext.storageManager, filesToAnalyze, moduleContentScope
)
val moduleClassResolver = ModuleClassResolverImpl { javaClass ->
@@ -76,4 +81,12 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmResolverForModule, JvmPlatfo
override val defaultImports = TopDownAnalyzerFacadeForJVM.DEFAULT_IMPORTS
override val platformToKotlinClassMap = JavaToKotlinClassMap.getInstance()
public platformStatic fun getAllFilesToAnalyze(project: Project, baseFiles: Collection<JetFile>): List<JetFile> {
val allFiles = ArrayList(baseFiles)
for (externalDeclarationsProvider in ExternalDeclarationsProvider.getInstances(project)) {
allFiles.addAll(externalDeclarationsProvider.getExternalDeclarations())
}
return allFiles
}
}

View File

@@ -75,6 +75,8 @@ public enum TopDownAnalyzerFacadeForJVM {
false
);
List<JetFile> allFiles = JvmAnalyzerFacade.getAllFilesToAnalyze(project, files);
InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(project, topDownAnalysisParameters, trace, module);
try {
List<PackageFragmentProvider> additionalProviders = new ArrayList<PackageFragmentProvider>();
@@ -85,7 +87,7 @@ public enum TopDownAnalyzerFacadeForJVM {
additionalProviders.add(
new IncrementalPackageFragmentProvider(
files, module, globalContext.getStorageManager(), injector.getDeserializationGlobalContextForJava(),
allFiles, module, globalContext.getStorageManager(), injector.getDeserializationGlobalContextForJava(),
incrementalCache, moduleId, injector.getJavaDescriptorResolver()
)
);
@@ -93,7 +95,7 @@ public enum TopDownAnalyzerFacadeForJVM {
}
additionalProviders.add(injector.getJavaDescriptorResolver().getPackageFragmentProvider());
injector.getTopDownAnalyzer().analyzeFiles(topDownAnalysisParameters, files, additionalProviders);
injector.getTopDownAnalyzer().analyzeFiles(topDownAnalysisParameters, allFiles, additionalProviders);
return AnalyzeExhaust.success(trace.getBindingContext(), module);
}
finally {

View File

@@ -53,7 +53,7 @@ public class AlternativeFieldSignatureData extends ElementAlternativeSignatureDa
try {
checkForSyntaxErrors(altPropertyDeclaration);
checkFieldAnnotation(altPropertyDeclaration, field, isVar);
altReturnType = computeReturnType(originalReturnType, altPropertyDeclaration.getTypeReference(),
altReturnType = computeReturnType(originalReturnType, altPropertyDeclaration.getTypeRef(),
new HashMap<TypeParameterDescriptor, TypeParameterDescriptorImpl>());
}
catch (AlternativeSignatureMismatchException e) {
@@ -73,7 +73,7 @@ public class AlternativeFieldSignatureData extends ElementAlternativeSignatureDa
field.getName().asString(), altProperty.getName());
}
if (altProperty.getTypeReference() == null) {
if (altProperty.getTypeRef() == null) {
throw new AlternativeSignatureMismatchException("Field annotation for shouldn't have type reference");
}

View File

@@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.java.JavaPackage;
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.resolver.ExternalAnnotationResolver;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMember;
@@ -90,7 +89,7 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
computeValueParameters(valueParameters);
if (originalReturnType != null) {
altReturnType = computeReturnType(originalReturnType, altFunDeclaration.getTypeReference(), originalToAltTypeParameters);
altReturnType = computeReturnType(originalReturnType, altFunDeclaration.getReturnTypeRef(), originalToAltTypeParameters);
}
if (hasSuperMethods) {
@@ -102,25 +101,11 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD
}
}
public static List<ValueParameterDescriptor> updateNames(
List<ValueParameterDescriptor> originalValueParameters,
List<ValueParameterDescriptor> altValueParameters
) {
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(originalValueParameters.size());
for (int i = 0; i < originalValueParameters.size(); i++) {
ValueParameterDescriptor originalValueParameter = originalValueParameters.get(i);
ValueParameterDescriptor altValueParameter = altValueParameters.get(i);
result.add(originalValueParameter.copy(originalValueParameter.getContainingDeclaration(), altValueParameter.getName()));
}
return result;
}
private void checkParameterAndReturnTypesForOverridingMethods(
@NotNull List<ValueParameterDescriptor> valueParameters,
@NotNull List<TypeParameterDescriptor> methodTypeParameters,
@Nullable JetType returnType
) {
if (JavaPackage.getPLATFORM_TYPES()) return;
TypeSubstitutor substitutor = DescriptorResolverUtils.createSubstitutorForTypeParameters(originalToAltTypeParameters);
for (ValueParameterDescriptor parameter : valueParameters) {

View File

@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMapBuilder;
public class CollectionClassMapping extends JavaToKotlinClassMapBuilder {
/* package */ class CollectionClassMapping extends JavaToKotlinClassMapBuilder {
private static CollectionClassMapping instance = null;
@NotNull

View File

@@ -0,0 +1,131 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.kotlinSignature;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
import org.jetbrains.jet.lang.resolve.java.structure.JavaSignatureFormatter;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import java.util.*;
public class JavaToKotlinMethodMap {
public static final JavaToKotlinMethodMap INSTANCE = new JavaToKotlinMethodMap();
private final JavaToKotlinMethodMapGenerated mapContainer = new JavaToKotlinMethodMapGenerated();
private JavaToKotlinMethodMap() {
}
@NotNull
public List<FunctionDescriptor> getFunctions(
@NotNull JavaMethod javaMethod,
@NotNull FqName classFqName,
@NotNull ClassDescriptor containingClass
) {
ImmutableCollection<ClassData> classDatas = mapContainer.map.get(classFqName.asString());
List<FunctionDescriptor> result = Lists.newArrayList();
Set<ClassDescriptor> allSuperClasses = new HashSet<ClassDescriptor>(DescriptorUtils.getSuperclassDescriptors(containingClass));
String serializedMethod = JavaSignatureFormatter.getInstance().formatMethod(javaMethod);
for (ClassData classData : classDatas) {
String expectedSerializedFunction = classData.method2Function.get(serializedMethod);
if (expectedSerializedFunction == null) continue;
ClassDescriptor kotlinClass = classData.kotlinClass;
if (!allSuperClasses.contains(kotlinClass)) continue;
Collection<FunctionDescriptor> functions = kotlinClass.getDefaultType().getMemberScope().getFunctions(javaMethod.getName());
for (FunctionDescriptor function : functions) {
if (expectedSerializedFunction.equals(serializeFunction(function))) {
result.add(function);
}
}
}
return result;
}
@NotNull
public static String serializeFunction(@NotNull FunctionDescriptor fun) {
return DescriptorRenderer.COMPACT.render(fun);
}
// used in generated code
static Pair<String, String> pair(String a, String b) {
return Pair.create(a, b);
}
// used in generated code
static void put(
ImmutableMultimap.Builder<String, ClassData> builder,
String javaFqName,
String kotlinQualifiedName,
Pair<String, String>... methods2Functions
) {
ImmutableMap<String, String> methods2FunctionsMap = pairs2Map(methods2Functions);
ClassDescriptor kotlinClass;
if (kotlinQualifiedName.contains(".")) { // Map.Entry and MutableMap.MutableEntry
String[] kotlinNames = kotlinQualifiedName.split("\\.");
assert kotlinNames.length == 2 : "unexpected qualified name " + kotlinQualifiedName;
ClassDescriptor outerClass = KotlinBuiltIns.getInstance().getBuiltInClassByName(Name.identifier(kotlinNames[0]));
kotlinClass = DescriptorUtils.getInnerClassByName(outerClass, kotlinNames[1]);
assert kotlinClass != null : "Class not found: " + kotlinQualifiedName;
}
else {
kotlinClass = KotlinBuiltIns.getInstance().getBuiltInClassByName(Name.identifier(kotlinQualifiedName));
}
builder.put(javaFqName, new ClassData(kotlinClass, methods2FunctionsMap));
}
private static ImmutableMap<String, String> pairs2Map(Pair<String, String>[] pairs) {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
for (Pair<String, String> pair : pairs) {
builder.put(pair.first, pair.second);
}
return builder.build();
}
static class ClassData {
@NotNull
public final ClassDescriptor kotlinClass;
@NotNull
public Map<String, String> method2Function;
public ClassData(@NotNull ClassDescriptor kotlinClass, @NotNull Map<String, String> method2Function) {
this.kotlinClass = kotlinClass;
this.method2Function = method2Function;
}
}
}

View File

@@ -0,0 +1,254 @@
/*
* Copyright 2010-2014 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.jet.lang.resolve.java.kotlinSignature;
import com.google.common.collect.ImmutableMultimap;
import static org.jetbrains.jet.lang.resolve.java.kotlinSignature.JavaToKotlinMethodMap.*;
/* This file is generated by org.jetbrains.jet.generators.jvm.GenerateJavaToKotlinMethodMap. DO NOT EDIT! */
@SuppressWarnings("unchecked")
class JavaToKotlinMethodMapGenerated {
final ImmutableMultimap<String, JavaToKotlinMethodMap.ClassData> map;
JavaToKotlinMethodMapGenerated() {
ImmutableMultimap.Builder<String, JavaToKotlinMethodMap.ClassData> b = ImmutableMultimap.builder();
put(b, "java.lang.Object", "Any",
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("toString()", "fun toString(): kotlin.String")
);
put(b, "java.lang.String", "String",
pair("compareTo(java.lang.String)", "fun compareTo(other: kotlin.String): kotlin.Int"),
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("toString()", "fun toString(): kotlin.String")
);
put(b, "java.lang.CharSequence", "CharSequence",
pair("toString()", "fun toString(): kotlin.String")
);
put(b, "java.lang.Throwable", "Throwable",
pair("getCause()", "fun getCause(): kotlin.Throwable?"),
pair("getMessage()", "fun getMessage(): kotlin.String?"),
pair("printStackTrace()", "fun printStackTrace(): kotlin.Unit"),
pair("toString()", "fun toString(): kotlin.String")
);
put(b, "java.lang.Comparable", "Comparable",
pair("compareTo(T)", "fun compareTo(other: T): kotlin.Int")
);
put(b, "java.lang.Enum", "Enum",
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("name()", "fun name(): kotlin.String"),
pair("ordinal()", "fun ordinal(): kotlin.Int"),
pair("toString()", "fun toString(): kotlin.String")
);
put(b, "java.lang.annotation.Annotation", "Annotation",
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("toString()", "fun toString(): kotlin.String")
);
put(b, "java.lang.Iterable", "Iterable",
pair("iterator()", "fun iterator(): kotlin.Iterator<T>")
);
put(b, "java.lang.Iterable", "MutableIterable",
pair("iterator()", "fun iterator(): kotlin.MutableIterator<T>")
);
put(b, "java.util.Iterator", "Iterator",
pair("hasNext()", "fun hasNext(): kotlin.Boolean"),
pair("next()", "fun next(): T")
);
put(b, "java.util.Iterator", "MutableIterator",
pair("hasNext()", "fun hasNext(): kotlin.Boolean"),
pair("next()", "fun next(): T"),
pair("remove()", "fun remove(): kotlin.Unit")
);
put(b, "java.util.Collection", "Collection",
pair("contains(java.lang.Object)", "fun contains(o: kotlin.Any?): kotlin.Boolean"),
pair("containsAll(java.util.Collection<?>)", "fun containsAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("isEmpty()", "fun isEmpty(): kotlin.Boolean"),
pair("iterator()", "fun iterator(): kotlin.Iterator<E>"),
pair("size()", "fun size(): kotlin.Int")
);
put(b, "java.util.Collection", "MutableCollection",
pair("add(E)", "fun add(e: E): kotlin.Boolean"),
pair("addAll(java.util.Collection<? extends E>)", "fun addAll(c: kotlin.Collection<E>): kotlin.Boolean"),
pair("clear()", "fun clear(): kotlin.Unit"),
pair("contains(java.lang.Object)", "fun contains(o: kotlin.Any?): kotlin.Boolean"),
pair("containsAll(java.util.Collection<?>)", "fun containsAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("isEmpty()", "fun isEmpty(): kotlin.Boolean"),
pair("iterator()", "fun iterator(): kotlin.MutableIterator<E>"),
pair("remove(java.lang.Object)", "fun remove(o: kotlin.Any?): kotlin.Boolean"),
pair("removeAll(java.util.Collection<?>)", "fun removeAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("retainAll(java.util.Collection<?>)", "fun retainAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("size()", "fun size(): kotlin.Int")
);
put(b, "java.util.List", "List",
pair("contains(java.lang.Object)", "fun contains(o: kotlin.Any?): kotlin.Boolean"),
pair("containsAll(java.util.Collection<?>)", "fun containsAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("get(int)", "fun get(index: kotlin.Int): E"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("indexOf(java.lang.Object)", "fun indexOf(o: kotlin.Any?): kotlin.Int"),
pair("isEmpty()", "fun isEmpty(): kotlin.Boolean"),
pair("iterator()", "fun iterator(): kotlin.Iterator<E>"),
pair("lastIndexOf(java.lang.Object)", "fun lastIndexOf(o: kotlin.Any?): kotlin.Int"),
pair("listIterator()", "fun listIterator(): kotlin.ListIterator<E>"),
pair("listIterator(int)", "fun listIterator(index: kotlin.Int): kotlin.ListIterator<E>"),
pair("size()", "fun size(): kotlin.Int"),
pair("subList(int, int)", "fun subList(fromIndex: kotlin.Int, toIndex: kotlin.Int): kotlin.List<E>")
);
put(b, "java.util.List", "MutableList",
pair("add(E)", "fun add(e: E): kotlin.Boolean"),
pair("add(int, E)", "fun add(index: kotlin.Int, element: E): kotlin.Unit"),
pair("addAll(int, java.util.Collection<? extends E>)", "fun addAll(index: kotlin.Int, c: kotlin.Collection<E>): kotlin.Boolean"),
pair("addAll(java.util.Collection<? extends E>)", "fun addAll(c: kotlin.Collection<E>): kotlin.Boolean"),
pair("clear()", "fun clear(): kotlin.Unit"),
pair("contains(java.lang.Object)", "fun contains(o: kotlin.Any?): kotlin.Boolean"),
pair("containsAll(java.util.Collection<?>)", "fun containsAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("get(int)", "fun get(index: kotlin.Int): E"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("indexOf(java.lang.Object)", "fun indexOf(o: kotlin.Any?): kotlin.Int"),
pair("isEmpty()", "fun isEmpty(): kotlin.Boolean"),
pair("iterator()", "fun iterator(): kotlin.MutableIterator<E>"),
pair("lastIndexOf(java.lang.Object)", "fun lastIndexOf(o: kotlin.Any?): kotlin.Int"),
pair("listIterator()", "fun listIterator(): kotlin.MutableListIterator<E>"),
pair("listIterator(int)", "fun listIterator(index: kotlin.Int): kotlin.MutableListIterator<E>"),
pair("remove(int)", "fun remove(index: kotlin.Int): E"),
pair("remove(java.lang.Object)", "fun remove(o: kotlin.Any?): kotlin.Boolean"),
pair("removeAll(java.util.Collection<?>)", "fun removeAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("retainAll(java.util.Collection<?>)", "fun retainAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("set(int, E)", "fun set(index: kotlin.Int, element: E): E"),
pair("size()", "fun size(): kotlin.Int"),
pair("subList(int, int)", "fun subList(fromIndex: kotlin.Int, toIndex: kotlin.Int): kotlin.MutableList<E>")
);
put(b, "java.util.Set", "Set",
pair("contains(java.lang.Object)", "fun contains(o: kotlin.Any?): kotlin.Boolean"),
pair("containsAll(java.util.Collection<?>)", "fun containsAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("isEmpty()", "fun isEmpty(): kotlin.Boolean"),
pair("iterator()", "fun iterator(): kotlin.Iterator<E>"),
pair("size()", "fun size(): kotlin.Int")
);
put(b, "java.util.Set", "MutableSet",
pair("add(E)", "fun add(e: E): kotlin.Boolean"),
pair("addAll(java.util.Collection<? extends E>)", "fun addAll(c: kotlin.Collection<E>): kotlin.Boolean"),
pair("clear()", "fun clear(): kotlin.Unit"),
pair("contains(java.lang.Object)", "fun contains(o: kotlin.Any?): kotlin.Boolean"),
pair("containsAll(java.util.Collection<?>)", "fun containsAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("isEmpty()", "fun isEmpty(): kotlin.Boolean"),
pair("iterator()", "fun iterator(): kotlin.MutableIterator<E>"),
pair("remove(java.lang.Object)", "fun remove(o: kotlin.Any?): kotlin.Boolean"),
pair("removeAll(java.util.Collection<?>)", "fun removeAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("retainAll(java.util.Collection<?>)", "fun retainAll(c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean"),
pair("size()", "fun size(): kotlin.Int")
);
put(b, "java.util.Map", "Map",
pair("containsKey(java.lang.Object)", "fun containsKey(key: kotlin.Any?): kotlin.Boolean"),
pair("containsValue(java.lang.Object)", "fun containsValue(value: kotlin.Any?): kotlin.Boolean"),
pair("entrySet()", "fun entrySet(): kotlin.Set<kotlin.Map.Entry<K, V>>"),
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("get(java.lang.Object)", "fun get(key: kotlin.Any?): V?"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("isEmpty()", "fun isEmpty(): kotlin.Boolean"),
pair("keySet()", "fun keySet(): kotlin.Set<K>"),
pair("size()", "fun size(): kotlin.Int"),
pair("values()", "fun values(): kotlin.Collection<V>")
);
put(b, "java.util.Map", "MutableMap",
pair("clear()", "fun clear(): kotlin.Unit"),
pair("containsKey(java.lang.Object)", "fun containsKey(key: kotlin.Any?): kotlin.Boolean"),
pair("containsValue(java.lang.Object)", "fun containsValue(value: kotlin.Any?): kotlin.Boolean"),
pair("entrySet()", "fun entrySet(): kotlin.MutableSet<kotlin.MutableMap.MutableEntry<K, V>>"),
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("get(java.lang.Object)", "fun get(key: kotlin.Any?): V?"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("isEmpty()", "fun isEmpty(): kotlin.Boolean"),
pair("keySet()", "fun keySet(): kotlin.MutableSet<K>"),
pair("put(K, V)", "fun put(key: K, value: V): V?"),
pair("putAll(java.util.Map<? extends K,? extends V>)", "fun putAll(m: kotlin.Map<out K, V>): kotlin.Unit"),
pair("remove(java.lang.Object)", "fun remove(key: kotlin.Any?): V?"),
pair("size()", "fun size(): kotlin.Int"),
pair("values()", "fun values(): kotlin.MutableCollection<V>")
);
put(b, "java.util.Map.Entry", "Map.Entry",
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("getKey()", "fun getKey(): K"),
pair("getValue()", "fun getValue(): V"),
pair("hashCode()", "fun hashCode(): kotlin.Int")
);
put(b, "java.util.Map.Entry", "MutableMap.MutableEntry",
pair("equals(java.lang.Object)", "fun equals(other: kotlin.Any?): kotlin.Boolean"),
pair("getKey()", "fun getKey(): K"),
pair("getValue()", "fun getValue(): V"),
pair("hashCode()", "fun hashCode(): kotlin.Int"),
pair("setValue(V)", "fun setValue(value: V): V")
);
put(b, "java.util.ListIterator", "ListIterator",
pair("hasNext()", "fun hasNext(): kotlin.Boolean"),
pair("hasPrevious()", "fun hasPrevious(): kotlin.Boolean"),
pair("next()", "fun next(): T"),
pair("nextIndex()", "fun nextIndex(): kotlin.Int"),
pair("previous()", "fun previous(): T"),
pair("previousIndex()", "fun previousIndex(): kotlin.Int")
);
put(b, "java.util.ListIterator", "MutableListIterator",
pair("add(E)", "fun add(e: T): kotlin.Unit"),
pair("hasNext()", "fun hasNext(): kotlin.Boolean"),
pair("hasPrevious()", "fun hasPrevious(): kotlin.Boolean"),
pair("next()", "fun next(): T"),
pair("nextIndex()", "fun nextIndex(): kotlin.Int"),
pair("previous()", "fun previous(): T"),
pair("previousIndex()", "fun previousIndex(): kotlin.Int"),
pair("remove()", "fun remove(): kotlin.Unit"),
pair("set(E)", "fun set(e: T): kotlin.Unit")
);
map = b.build();
}
}

View File

@@ -30,7 +30,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JavaPackage;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaMethodDescriptor;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmSignaturePackage;
@@ -58,12 +57,10 @@ public class SignaturesPropagationData {
KotlinToJvmSignatureMapper.class.getClassLoader()
).iterator().next();
private final JavaMethodDescriptor autoMethodDescriptor;
private final List<TypeParameterDescriptor> modifiedTypeParameters;
private final ValueParameters modifiedValueParameters;
private final JetType modifiedReturnType;
private final List<String> signatureErrors = Lists.newArrayList();
private final List<FunctionDescriptor> superFunctions;
private final Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> autoTypeParameterToModified;
@@ -79,7 +76,7 @@ public class SignaturesPropagationData {
) {
this.containingClass = containingClass;
autoMethodDescriptor =
JavaMethodDescriptor autoMethodDescriptor =
createAutoMethodDescriptor(containingClass, method, autoReturnType, receiverType, autoValueParameters, autoTypeParameters);
superFunctions = getSuperFunctionsForMethod(method, autoMethodDescriptor, containingClass);
@@ -153,8 +150,6 @@ public class SignaturesPropagationData {
private JetType modifyReturnTypeAccordingToSuperMethods(
@NotNull JetType autoType // type built by JavaTypeTransformer
) {
if (JavaPackage.getPLATFORM_TYPES()) return autoType;
List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map(superFunctions,
new Function<FunctionDescriptor, TypeAndVariance>() {
@Override
@@ -167,8 +162,6 @@ public class SignaturesPropagationData {
}
private List<TypeParameterDescriptor> modifyTypeParametersAccordingToSuperMethods(List<TypeParameterDescriptor> autoTypeParameters) {
if (JavaPackage.getPLATFORM_TYPES()) return autoTypeParameters;
List<TypeParameterDescriptor> result = Lists.newArrayList();
for (TypeParameterDescriptor autoParameter : autoTypeParameters) {
@@ -222,7 +215,7 @@ public class SignaturesPropagationData {
new Function<FunctionDescriptor, TypeAndName>() {
@Override
public TypeAndName fun(FunctionDescriptor superFunction) {
ReceiverParameterDescriptor receiver = superFunction.getExtensionReceiverParameter();
ReceiverParameterDescriptor receiver = superFunction.getReceiverParameter();
int index = receiver != null ? originalIndex - 1 : originalIndex;
if (index == -1) {
assert receiver != null : "can't happen: index is -1, while function is not extension";
@@ -325,7 +318,7 @@ public class SignaturesPropagationData {
boolean someSupersNotExtension = false;
for (FunctionDescriptor superFunction : superFunctions) {
if (superFunction.getExtensionReceiverParameter() != null) {
if (superFunction.getReceiverParameter() != null) {
someSupersExtension = true;
}
else {
@@ -350,7 +343,7 @@ public class SignaturesPropagationData {
boolean someSupersNotVararg = false;
for (FunctionDescriptor superFunction : superFunctions) {
int originalIndex = originalParam.getIndex();
int index = superFunction.getExtensionReceiverParameter() != null ? originalIndex - 1 : originalIndex;
int index = superFunction.getReceiverParameter() != null ? originalIndex - 1 : originalIndex;
if (index != -1 && superFunction.getValueParameters().get(index).getVarargElementType() != null) {
someSupersVararg = true;
}
@@ -406,9 +399,9 @@ public class SignaturesPropagationData {
@NotNull List<TypeAndVariance> typesFromSuper,
@NotNull TypeUsage howThisTypeIsUsed
) {
if (autoType.isError()) return autoType;
if (JavaPackage.getPLATFORM_TYPES()) return autoType;
if (autoType.isError()) {
return autoType;
}
boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, howThisTypeIsUsed);
ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper);
@@ -437,14 +430,11 @@ public class SignaturesPropagationData {
@NotNull ClassifierDescriptor classifier,
@NotNull List<TypeAndVariance> typesFromSuper
) {
if (typesFromSuper.isEmpty()) return autoType.getArguments();
List<TypeProjection> autoArguments = autoType.getArguments();
if (!(classifier instanceof ClassDescriptor)) {
assert autoArguments.isEmpty() :
"Unexpected type arguments when type constructor is not ClassDescriptor, type = " + autoType +
", classifier = " + classifier + ", classifier class = " + classifier.getClass();
"Unexpected type arguments when type constructor is not ClassDescriptor, type = " + autoType;
return autoArguments;
}
@@ -472,8 +462,6 @@ public class SignaturesPropagationData {
@NotNull TypeProjection argument,
@NotNull List<TypeProjectionAndVariance> projectionsFromSuper
) {
if (projectionsFromSuper.isEmpty()) return argument.getProjectionKind();
Set<Variance> projectionKindsInSuper = Sets.newLinkedHashSet();
for (TypeProjectionAndVariance projectionAndVariance : projectionsFromSuper) {
projectionKindsInSuper.add(projectionAndVariance.typeProjection.getProjectionKind());
@@ -587,7 +575,7 @@ public class SignaturesPropagationData {
boolean someSupersCovariantNullable = false;
boolean someSupersNotNull = false;
for (TypeAndVariance typeFromSuper : typesFromSuper) {
if (!TypeUtils.isNullableType(typeFromSuper.type)) {
if (!typeFromSuper.type.isNullable()) {
someSupersNotNull = true;
}
else {
@@ -602,23 +590,23 @@ public class SignaturesPropagationData {
if (someSupersNotNull && someSupersNotCovariantNullable) {
reportError("Incompatible types in superclasses: " + typesFromSuper);
return TypeUtils.isNullableType(autoType);
return autoType.isNullable();
}
else if (someSupersNotNull) {
return false;
}
else if (someSupersNotCovariantNullable || someSupersCovariantNullable) {
boolean annotatedAsNotNull = howThisTypeIsUsed != TYPE_ARGUMENT && !TypeUtils.isNullableType(autoType);
boolean annotatedAsNotNull = howThisTypeIsUsed != TYPE_ARGUMENT && !autoType.isNullable();
if (annotatedAsNotNull && someSupersNotCovariantNullable) {
DescriptorRenderer renderer = DescriptorRenderer.SHORT_NAMES_IN_TYPES;
DescriptorRenderer renderer = DescriptorRenderer.SOURCE_CODE_SHORT_NAMES_IN_TYPES;
reportError("In superclass type is nullable: " + typesFromSuper + ", in subclass it is not: " + renderer.renderType(autoType));
return true;
}
return !annotatedAsNotNull;
}
return TypeUtils.isNullableType(autoType);
return autoType.isNullable();
}
@NotNull
@@ -628,7 +616,7 @@ public class SignaturesPropagationData {
) {
ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor();
if (!(classifier instanceof ClassDescriptor)) {
assert classifier != null : "no declaration descriptor for type " + autoType + ", auto method descriptor: " + autoMethodDescriptor;
assert classifier != null : "no declaration descriptor for type " + autoType;
if (classifier instanceof TypeParameterDescriptor && autoTypeParameterToModified.containsKey(classifier)) {
return autoTypeParameterToModified.get(classifier);

View File

@@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.java.JavaPackage;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap;
import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage;
@@ -73,7 +72,7 @@ public class TypeTransformingVisitor extends JetVisitor<JetType, Void> {
@Override
public JetType visitNullableType(@NotNull JetNullableType nullableType, Void aVoid) {
if (!TypeUtils.isNullableType(originalType) && typeUsage != TYPE_ARGUMENT) {
if (!originalType.isNullable() && typeUsage != TYPE_ARGUMENT) {
throw new AlternativeSignatureMismatchException("Auto type '%s' is not-null, while type in alternative signature is nullable: '%s'",
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(originalType), nullableType.getText());
}
@@ -84,7 +83,7 @@ public class TypeTransformingVisitor extends JetVisitor<JetType, Void> {
@Override
public JetType visitFunctionType(@NotNull JetFunctionType type, Void data) {
return visitCommonType(type.getReceiverTypeReference() == null
return visitCommonType(type.getReceiverTypeRef() == null
? KotlinBuiltIns.getInstance().getFunction(type.getParameters().size())
: KotlinBuiltIns.getInstance().getExtensionFunction(type.getParameters().size()), type);
}
@@ -134,8 +133,6 @@ public class TypeTransformingVisitor extends JetVisitor<JetType, Void> {
List<TypeProjection> arguments = originalType.getArguments();
if (arguments.size() != type.getTypeArgumentsAsTypes().size()) {
if (JavaPackage.getPLATFORM_TYPES()) return originalType;
throw new AlternativeSignatureMismatchException("'%s' type in method signature has %d type arguments, while '%s' in alternative signature has %d of them",
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(originalType), arguments.size(), type.getText(),
type.getTypeArgumentsAsTypes().size());
@@ -188,7 +185,7 @@ public class TypeTransformingVisitor extends JetVisitor<JetType, Void> {
if (type instanceof JetUserType) {
JetTypeProjection typeProjection = ((JetUserType) type).getTypeArguments().get(i);
altProjectionKind = TypeResolver.resolveProjectionKind(typeProjection.getProjectionKind());
if (altProjectionKind != projectionKind && projectionKind != Variance.INVARIANT && !JavaPackage.getPLATFORM_TYPES()) {
if (altProjectionKind != projectionKind && projectionKind != Variance.INVARIANT) {
throw new AlternativeSignatureMismatchException("Projection kind mismatch, actual: %s, in alternative signature: %s",
projectionKind, altProjectionKind);
}

View File

@@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.java.JavaBindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaPackage;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeFieldSignatureData;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesPropagationData;
@@ -95,12 +94,6 @@ public class TraceBasedExternalSignatureResolver implements ExternalSignatureRes
returnType, typeParameters, hasSuperMethods);
if (data.isAnnotated() && !data.hasErrors()) {
if (JavaPackage.getPLATFORM_TYPES()) {
// We only take parameter names from the @KotlinSignature
return new AlternativeMethodSignature(returnType, receiverType,
AlternativeMethodSignatureData.updateNames(valueParameters, data.getValueParameters()),
typeParameters, Collections.<String>emptyList(), true);
}
return new AlternativeMethodSignature(data.getReturnType(), receiverType, data.getValueParameters(), data.getTypeParameters(),
Collections.<String>emptyList(), true);
}
@@ -120,9 +113,6 @@ public class TraceBasedExternalSignatureResolver implements ExternalSignatureRes
new AlternativeFieldSignatureData(externalAnnotationResolver, field, returnType, project, isVar);
if (data.isAnnotated() && !data.hasErrors()) {
if (JavaPackage.getPLATFORM_TYPES()) {
return new AlternativeFieldSignature(returnType, null);
}
return new AlternativeFieldSignature(data.getReturnType(), null);
}

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