Compare commits

..

23 Commits

Author SHA1 Message Date
Ilya Matveev
2f0e20b1c7 WIP: Basic support for Kotlin/Native
* Target presets
 * Compilation into a klib
 * Compilation into native binraies: framework and executable
 * Basic dependencies between projects
2018-07-19 19:19:04 +07:00
Ilya Matveev
f924de871f Add dependency on KN shared in gradle-plugin 2018-07-19 19:18:45 +07:00
Alexander Podkhalyuzin
f953726f64 Kotlin/Native support in IntelliJ IDEA 2018-07-16 12:31:29 +07:00
Sergey Igushkin
d32afbf28c Fix non-MPP builds failing due to an invalid type cast 2018-07-12 17:54:53 +03:00
Sergey Igushkin
2f567f0fdb Fix Android, clashes due to the naming conventions; refactor 2018-07-12 14:37:11 +03:00
Sergey Igushkin
c94386cff7 Fix old use cases and tests 2018-07-09 18:53:45 +03:00
Sergey Igushkin
2cb379c7da (incomplete) new MPP design implementation 2018-07-06 17:21:09 +03:00
Sergey Igushkin
eeb9281b25 ~ Partial implementation 2018-07-02 12:26:02 +03:00
Sergey Igushkin
698d69070c (incomplete) new MPP design implementation 2018-06-29 14:00:49 +03:00
Sergey Igushkin
59cc320abc ~ Fix build after rebase on master 2018-06-26 15:33:40 +03:00
Sergey Igushkin
6bd1675a8b ~ Fix Android in experimental MPP (source sets were not detected) 2018-06-25 18:40:46 +03:00
Sergey Igushkin
d8d69fca98 Partial implementation of Android support in experimental MPP 2018-06-25 18:40:45 +03:00
Sergey Igushkin
504a9ec48f Publishing with variants 2018-06-25 18:39:34 +03:00
Sergey Igushkin
712a108c7f (minor) Make allSource include kotlin and resources. 2018-06-25 18:39:34 +03:00
Sergey Igushkin
ab9536b64a Add jvmWithJava platform. 2018-06-25 18:39:33 +03:00
Sergey Igushkin
0072b62d76 Variants, expectedBy relation for single platform 2018-06-25 18:38:51 +03:00
Sergey Igushkin
83d9e9363e Support JVM platform 2018-06-25 18:38:49 +03:00
Sergey Igushkin
150f8f34c7 Preparations for JVM platform in the experimental MPP plugin. 2018-06-25 18:36:32 +03:00
Sergey Igushkin
3bb1afb05a Implement common and js platforms in the multiplatform plugin 2018-06-25 18:32:54 +03:00
Sergey Igushkin
0aaf084ff6 Add experimental multiplatform plugin 2018-06-25 18:32:54 +03:00
Sergey Igushkin
415006e7b2 Factor out some abstractions for Kotlin platforms, which should allow
implementing a MPP plugin that just calls those abstractions.
2018-06-25 18:32:51 +03:00
Sergey Igushkin
6631d539ad Кefactor KotlinSourceSet & base plugin, support Android & MPP 2018-06-25 18:28:43 +03:00
Sergey Igushkin
204c36fea2 Add Kotlin source sets that are Java-agnostic, use them instead of the
Java source sets.
2018-06-25 17:52:02 +03:00
55326 changed files with 586897 additions and 2097552 deletions

14
.bunch
View File

@@ -1,8 +1,6 @@
201
202
203_202
193
192_193
as36_192_193
as40_193
as41
181
173
172_173
as31_173
as32
182

4
.gitattributes vendored
View File

@@ -1,8 +1,4 @@
**/testData/** linguist-vendored
*Generated.java linguist-generated=true
* text=auto
* eol=lf
*.png binary
*.jar binary
compiler/cli/bin/* eol=lf
compiler/cli/bin/*.bat eol=crlf

14
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,14 @@
Many thanks for your contribution, we genuinely appreciate it.
Make sure that you can say "YES" to each point in this short checklist:
- You do not have merge commits in PR
- You made a few changes
- You provided the link to related issue from YouTrack
- You can describe changes made in PR
- You made changes related to only one issue
- You are ready to defend your changes on code review
- You didn't touch what you don't understand
- You ran the build locally, and verified new functionality
- You ran related tests locally, and it passed
Thank you for your contribution!

35
.gitignore vendored
View File

@@ -1,9 +1,8 @@
.DS_Store
.idea/shelf
/confluence/target
/dependencies/repo
/android.tests.dependencies
/dependencies/android.tests.dependencies
/confluence/target
/dependencies
/dist
/local
/gh-pages
@@ -16,9 +15,12 @@ workspace.xml
*.versionsBackup
/idea/testData/debugger/tinyApp/classes*
/jps-plugin/testData/kannotator
/ultimate/dependencies
/ultimate/ideaSDK
/ultimate/out
/ultimate/tmp
/js/js.translator/testData/out/
/js/js.translator/testData/out-min/
/js/js.translator/testData/out-pir/
.gradle/
build/
!**/src/**/build
@@ -27,35 +29,12 @@ build/
!**/testData/**/*.iml
.idea/libraries/Gradle*.xml
.idea/libraries/Maven*.xml
.idea/artifacts/PILL_*.xml
.idea/artifacts/KotlinPlugin.xml
.idea/artifacts
.idea/modules
.idea/runConfigurations/JPS_*.xml
.idea/runConfigurations/PILL_*.xml
.idea/libraries
.idea/modules.xml
.idea/gradle.xml
.idea/compiler.xml
.idea/inspectionProfiles/profiles_settings.xml
.idea/.name
.idea/artifacts/dist_auto_*
.idea/artifacts/dist.xml
.idea/artifacts/ideaPlugin.xml
.idea/artifacts/kotlinc.xml
.idea/artifacts/kotlin_compiler_jar.xml
.idea/artifacts/kotlin_plugin_jar.xml
.idea/artifacts/kotlin_jps_plugin_jar.xml
.idea/artifacts/kotlin_daemon_client_jar.xml
.idea/artifacts/kotlin_imports_dumper_compiler_plugin_jar.xml
.idea/artifacts/kotlin_main_kts_jar.xml
.idea/artifacts/kotlin_compiler_client_embeddable_jar.xml
.idea/artifacts/kotlin_reflect_jar.xml
.idea/artifacts/kotlin_stdlib_js_ir_*
.idea/artifacts/kotlin_test_js_ir_*
.idea/artifacts/kotlin_stdlib_wasm_*
.idea/jarRepositories.xml
kotlin-ultimate/
node_modules/
.rpt2_cache/
libraries/tools/kotlin-test-js-runner/lib/
local.properties

8
.idea/ant.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AntConfiguration">
<buildFile url="file://$PROJECT_DIR$/libraries/build-docs.xml">
<maximumHeapSize value="1024" />
</buildFile>
</component>
</project>

View File

@@ -1,8 +0,0 @@
<component name="ArtifactManager">
<artifact build-on-make="true" name="dist_root">
<output-path>$PROJECT_DIR$/dist</output-path>
<root id="root">
<element id="artifact" artifact-name="dist" />
</root>
</artifact>
</component>

289
.idea/codeStyleSettings.xml generated Normal file
View File

@@ -0,0 +1,289 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</value>
</option>
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="PREFER_LONGER_NAMES" value="false" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value>
<package name="java.awt" withSubpackages="false" static="false" />
<package name="javax.tools" withSubpackages="true" static="false" />
<package name="javax.swing" withSubpackages="false" static="false" />
</value>
</option>
<option name="STATIC_METHODS_ORDER_WEIGHT" value="5" />
<option name="METHODS_ORDER_WEIGHT" value="4" />
<option name="RIGHT_MARGIN" value="140" />
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="5" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="CFML">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="CoffeeScript">
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="ECMA Script Level 4">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="GSP">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Groovy">
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="5" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="HTML">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="5" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
<indentOptions>
<option name="TAB_SIZE" value="8" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="Scala">
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
</project>

View File

@@ -1,7 +1,50 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
</value>
</option>
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="RIGHT_MARGIN" value="140" />
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="5" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<GroovyCodeStyleSettings>
<option name="STATIC_METHODS_ORDER_WEIGHT" value="5" />
<option name="METHODS_ORDER_WEIGHT" value="4" />
</GroovyCodeStyleSettings>
<JavaCodeStyleSettings>
<option name="PREFER_LONGER_NAMES" value="false" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
@@ -18,10 +61,90 @@
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="CFML">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ASSIGNMENT_WRAP" value="1" />
</codeStyleSettings>
<codeStyleSettings language="CoffeeScript">
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
</codeStyleSettings>
<codeStyleSettings language="ECMA Script Level 4">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
</codeStyleSettings>
<codeStyleSettings language="GSP">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Groovy">
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="5" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
</codeStyleSettings>
<codeStyleSettings language="HTML">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JAVA">
@@ -62,6 +185,9 @@
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<indentOptions>
<option name="TAB_SIZE" value="8" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="ELSE_ON_NEW_LINE" value="true" />
@@ -88,12 +214,59 @@
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Scala">
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="kotlin">

View File

@@ -1,7 +1,7 @@
<component name="CopyrightManager">
<copyright>
<option name="allowReplaceRegexp" value="JetBrains" />
<option name="notice" value="Copyright 2010-&amp;#36;today.year JetBrains s.r.o. and Kotlin Programming Language contributors.&#10;Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file." />
<option name="notice" value="Copyright 2010-&amp;#36;today.year JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license &#10;that can be found in the license/LICENSE.txt file." />
<option name="myName" value="apache" />
</copyright>
</component>

View File

@@ -1,18 +1,8 @@
<component name="ProjectDictionaryState">
<dictionary name="4u7">
<words>
<w>bintray</w>
<w>cacheability</w>
<w>cacheable</w>
<w>cidr</w>
<w>foldable</w>
<w>instrumentator</w>
<w>jdks</w>
<w>protobuf</w>
<w>redirector</w>
<w>remapper</w>
<w>sonatype</w>
<w>unpresent</w>
</words>
</dictionary>
</component>

View File

@@ -7,10 +7,9 @@
<w>fqname</w>
<w>goto</w>
<w>gradle</w>
<w>infos</w>
<w>intrinsics</w>
<w>kdoc</w>
<w>lateinit</w>
<w>kompiler</w>
<w>memoize</w>
<w>memoized</w>
<w>multiline</w>
@@ -19,15 +18,11 @@
<w>preloader</w>
<w>preloading</w>
<w>preprocess</w>
<w>proximities</w>
<w>redeclarations</w>
<w>reparsed</w>
<w>smap</w>
<w>subclassed</w>
<w>subgraph</w>
<w>substep</w>
<w>tailrec</w>
<w>typealias</w>
</words>
</dictionary>
</component>

View File

@@ -1,19 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="dmitriy.dolovov">
<words>
<w>cinterop</w>
<w>commonizable</w>
<w>commonization</w>
<w>commonize</w>
<w>commonized</w>
<w>commonizer</w>
<w>commonizers</w>
<w>commonizes</w>
<w>commonizing</w>
<w>jetbrains</w>
<w>konan</w>
<w>kotlinx</w>
<w>macos</w>
</words>
</dictionary>
</component>

View File

@@ -7,7 +7,6 @@
<w>experimentality</w>
<w>insn</w>
<w>liveness</w>
<w>parameterless</w>
</words>
</dictionary>
</component>
</component>

View File

@@ -1,7 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="sergey.igushkin">
<words>
<w>klib</w>
</words>
</dictionary>
</component>

View File

@@ -1,9 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="skuzmich">
<words>
<w>anyref</w>
<w>ushr</w>
<w>wasm</w>
</words>
</dictionary>
</component>

View File

@@ -1,22 +1,12 @@
<component name="ProjectDictionaryState">
<dictionary name="yan">
<words>
<w>debuggee</w>
<w>deserializes</w>
<w>destructured</w>
<w>hacky</w>
<w>impls</w>
<w>inlined</w>
<w>kapt</w>
<w>kotlinc</w>
<w>mutators</w>
<w>parceler</w>
<w>repl</w>
<w>testdata</w>
<w>uast</w>
<w>unbox</w>
<w>unboxed</w>
<w>unmute</w>
</words>
</dictionary>
</component>

3
.idea/encodings.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false">
<file url="file://$PROJECT_DIR$/libraries" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libraries/examples/browser-example" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libraries/examples/browser-example-with-library" charset="UTF-8" />
@@ -14,7 +14,6 @@
<file url="file://$PROJECT_DIR$/libraries/tools/kotlin-maven-plugin" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libraries/tools/kotlin-maven-plugin-test" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libraries/tools/kotlin-maven-sam-with-receiver" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libraries/tools/kotlin-maven-serialization" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libraries/tools/kotlin-osgi-bundle" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libraries/tools/maven-archetypes" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/libraries/tools/maven-archetypes/kotlin-archetype-js" charset="UTF-8" />

BIN
.idea/icon.png generated

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -21,6 +21,7 @@
</inspection_tool>
<inspection_tool class="BooleanMethodIsAlwaysInverted" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BusyWait" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CStyleArrayDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CastConflictsWithInstanceof" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CastToIncompatibleInterface" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ChainedEquality" enabled="false" level="WARNING" enabled_by_default="true" />
@@ -54,6 +55,9 @@
<inspection_tool class="DoubleCheckedLocking" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreOnVolatileVariables" value="true" />
</inspection_tool>
<inspection_tool class="DuplicateCondition" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreSideEffectConditions" value="true" />
</inspection_tool>
<inspection_tool class="EmptyStatementBody" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_reportEmptyBlocks" value="false" />
</inspection_tool>
@@ -75,7 +79,6 @@
<option name="m_ignoreLoopsWithoutConditions" value="false" />
</inspection_tool>
<inspection_tool class="ForLoopThatDoesntUseLoopVariable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GrPackage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myValues">
<value>
@@ -98,9 +101,21 @@
<inspection_tool class="IncompatibleAPI" enabled="true" level="ERROR" enabled_by_default="true">
<option name="problems">
<list>
<Problem reference="com.intellij.util.JdomKt#element" reason="Removed in 191" />
<Problem reference="org.jetbrains.kotlin.idea.reporter.ITNReporterCompat#submit" reason="parentComponent is nullable in AS" />
<Problem reference="com.intellij.diagnostic.ITNReporter#submit" reason="parentComponent is nullable in AS" />
<Problem reference="org.jetbrains.plugins.gradle.util.GradleConstants#KOTLIN_DSL_SCRIPT_EXTENSION" reason="Absent in 172. Please inline." />
<Problem reference="com.intellij.psi.impl.compiled.ClsClassImpl#getQualifiedName" reason="Nullable in 173, platform in 172. Use qualifiedNameEx instead." />
<Problem reference="com.intellij.internal.statistic.utils.StatisticsUtilKt#getEnumUsage" reason="Absent in 172. Use org.jetbrains.kotlin.idea.util.compat.statistic.StatisticKt.getEnumUsage instead." />
<Problem reference="com.intellij.internal.statistic.utils.StatisticsUtilKt#getBooleanUsage" reason="Absent in 172 Use org.jetbrains.kotlin.idea.util.compat.statistic.StatisticKt.getBooleanUsage instead." />
<Problem reference="com.intellij.internal.statistic.AbstractProjectsUsagesCollector" reason="Absent in 172. Use org.jetbrains.kotlin.idea.util.compat.statistic.AbstractProjectsUsagesCollector instead." />
<Problem reference="com.intellij.openapi.progress.ProgressManager#getProgressIndicator" reason="Not null starting from 181. Use getProgressIndicatorNullable instead." />
<Problem reference="com.intellij.testFramework.PlatformTestCase#createModuleAt" reason="Not static anymore in 181 after 7dacf096c47d2125e17031c71a037b63ab00ec53" />
<Problem reference="com.intellij.testFramework.PlatformTestCase#doCreateRealModuleIn" reason="Not static anymore in 181 after 7dacf096c47d2125e17031c71a037b63ab00ec53" />
<Problem reference="com.intellij.openapi.progress.ProgressManager#getProgressIndicator" reason="Nullable in 181. Temporary use progressIndicatorNullable instead." />
<Problem reference="com.intellij.testFramework.fixtures.CodeInsightTestFixture#getProjectDisposable" reason="Method was introduced in 173 and absent in 172. Use getProjectDisposableEx instead. (95eaf81e0ea497f8c69263c11fd3202d28a7a1b2)" />
<Problem reference="org.jetbrains.org.objectweb.asm.Opcodes#V9" reason="Absent in 172 branch. Use V1_9 while 172 is supported." />
<Problem reference="com.intellij.psi.codeStyle.CommonCodeStyleSettings#getSoftMargins" reason="Absent in 172." />
<Problem reference="com.intellij.util.xmlb.XmlSerializer#serializeInto(java.lang.Object, org.jdom.Element)" reason="Absent in 172." />
<Problem reference="org.jetbrains.java.decompiler.main.decompiler.BaseDecompiler#addSpace" reason="Method was replaced with outher methods in 182. Use addSpaceEx instead." />
<Problem reference="com.intellij.psi.util.PsiUtil#canBeOverridden" reason="Absent in 172. Use org.jetbrains.kotlin.idea.core.util.compat.psi.canBeOverridden() instead." />
</list>
</option>
</inspection_tool>
@@ -253,10 +268,6 @@
<option name="ignoreObjectMethods" value="true" />
<option name="ignoreAnonymousClassMethods" value="false" />
</inspection_tool>
<inspection_tool class="MissingRecentApi" enabled="true" level="ERROR" enabled_by_default="true">
<option name="sinceBuildString" value="183.3284" />
<option name="untilBuildString" value="192.SNAPSHOT" />
</inspection_tool>
<inspection_tool class="MisspelledCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisspelledEquals" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisspelledHashcode" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -285,8 +296,15 @@
<inspection_tool class="PackageDirectoryMismatch" enabled="true" level="WARNING" enabled_by_default="false">
<scope name="all except testData" level="WARNING" enabled="true" />
</inspection_tool>
<inspection_tool class="PackageName" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="namePattern" value="[a-z_][a-z\d_]*(\.[a-z_][a-zA-Z\d_]*)*" />
<inspection_tool class="ProblematicAPIUsage" enabled="true" level="ERROR" enabled_by_default="true">
<option name="problems">
<list>
<Problem reference="com.intellij.testFramework.PlatformTestCase#createModuleAt" reason="Not static anymore in 181 after 7dacf096c47d2125e17031c71a037b63ab00ec53" />
<Problem reference="com.intellij.testFramework.PlatformTestCase#doCreateRealModuleIn" reason="Not static anymore in 181 after 7dacf096c47d2125e17031c71a037b63ab00ec53" />
<Problem reference="com.intellij.openapi.progress.ProgressManager#getProgressIndicator" reason="Nullable in 181. Temporary use progressIndicatorNullable instead." />
<Problem reference="com.intellij.testFramework.fixtures.CodeInsightTestFixture#getProjectDisposable" reason="Method was introduced in 173 and absent in 172. Use getProjectDisposableEx instead. (95eaf81e0ea497f8c69263c11fd3202d28a7a1b2)" />
</list>
</option>
</inspection_tool>
<inspection_tool class="ProtectedMemberInFinalClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PublicFieldAccessedInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -294,20 +312,23 @@
<option name="fromVersion" value="2.4" />
<option name="toVersion" value="3.1" />
</inspection_tool>
<inspection_tool class="Reformat" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="processChangedFilesOnly" value="true" />
</inspection_tool>
<inspection_tool class="Reformat" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="ReplaceAssignmentWithOperatorAssignment" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreLazyOperators" value="true" />
<option name="ignoreObscureOperators" value="true" />
</inspection_tool>
<inspection_tool class="SSBasedInspection" enabled="true" level="WARNING" enabled_by_default="true">
<searchConfiguration name="SwingUtilities.invokeLater" text="SwingUtilities.invokeLater($runnable$)" recursive="false" caseInsensitive="false" type="JAVA">
<constraint name="Instance" regexp="SwingUtilities" minCount="0" target="true" within="" contains="" />
<constraint name="MethodCall" within="" contains="" />
<constraint name="Parameter" minCount="0" maxCount="2147483647" within="" contains="" />
<constraint name="__context__" within="" contains="" />
<constraint name="runnable" within="" contains="" />
</searchConfiguration>
<replaceConfiguration name="DirectCallOfDispose" text="$Instance$.dispose()" recursive="false" caseInsensitive="false" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" replacement="Disposer.dispose($Instance$)">
<constraint name="Instance" regexp="super" nameOfExprType="Disposable" withinHierarchy="true" exprTypeWithinHierarchy="true" minCount="0" negateName="true" within="" contains="" />
<constraint name="MethodCall" target="true" within="" contains="" />
<constraint name="Parameter" minCount="0" maxCount="2147483647" within="" contains="" />
<constraint name="__context__" within="" contains="" />
</replaceConfiguration>
<replaceConfiguration name="new Object[0]" text="new Object[0]" recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.intellij.util.ArrayUtil.EMPTY_OBJECT_ARRAY" />
@@ -371,7 +392,6 @@
</inspection_tool>
<inspection_tool class="StringEquality" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringEqualsEmptyString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringOperationCanBeSimplifiedMerged" />
<inspection_tool class="SwitchStatementWithConfusingDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SynchronizeOnThis" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SystemOutErr" enabled="true" level="WARNING" enabled_by_default="true">
@@ -423,21 +443,6 @@
<inspection_tool class="UnnecessaryLabelOnContinueStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryQualifierForThis" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryUnboxing" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnstableApiUsage" enabled="true" level="WARNING" enabled_by_default="true">
<option name="unstableApiAnnotations">
<set>
<option value="com.google.common.annotations.Beta" />
<option value="io.reactivex.annotations.Beta" />
<option value="io.reactivex.annotations.Experimental" />
<option value="org.apache.http.annotation.Beta" />
<option value="org.jetbrains.annotations.ApiStatus.Experimental" />
<option value="org.jetbrains.annotations.ApiStatus.Internal" />
<option value="org.jetbrains.annotations.ApiStatus.ScheduledForRemoval" />
<option value="rx.annotations.Beta" />
<option value="rx.annotations.Experimental" />
</set>
</option>
</inspection_tool>
<inspection_tool class="UseOfPropertiesAsHashtable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UtilityClassWithPublicConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="VolatileLongOrDoubleField" enabled="true" level="WARNING" enabled_by_default="true" />

View File

@@ -1,6 +1,7 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="idea.default" />
<option name="USE_PROJECT_PROFILE" value="true" />
<version value="1.0" />
</settings>
</component>

59
.idea/misc.xml generated
View File

@@ -6,25 +6,48 @@
</properties>
</component>
<component name="EntryPointsManager">
<list size="3">
<list size="1">
<item index="0" class="java.lang.String" itemvalue="javax.inject.Inject" />
<item index="1" class="java.lang.String" itemvalue="org.gradle.api.tasks.TaskAction" />
<item index="2" class="java.lang.String" itemvalue="org.gradle.api.tasks.options.Option" />
</list>
</component>
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
<component name="FacetAutodetectingManager">
<autodetection-disabled>
<facet-type id="Python">
<modules>
<module name="Jet" />
</modules>
</facet-type>
</autodetection-disabled>
</component>
<component name="IdProvider" IDEtalkID="71A301FF1940049D6D82F12C40F1E1D5" />
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" />
<option name="OPTION_SCOPE" value="protected" />
<option name="OPTION_HIERARCHY" value="true" />
<option name="OPTION_NAVIGATOR" value="true" />
<option name="OPTION_INDEX" value="true" />
<option name="OPTION_SEPARATE_INDEX" value="true" />
<option name="OPTION_DOCUMENT_TAG_USE" value="false" />
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
<option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
<option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
<option name="OPTION_DEPRECATED_LIST" value="true" />
<option name="OTHER_OPTIONS" value="" />
<option name="HEAP_SIZE" />
<option name="LOCALE" />
<option name="OPEN_IN_BROWSER" value="true" />
</component>
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/libraries/pom.xml" />
</list>
</option>
</component>
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="org.jetbrains.annotations.Nullable" />
<option name="myDefaultNotNull" value="org.jetbrains.annotations.NotNull" />
<option name="myNullables">
<value>
<list size="14">
<list size="9">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
@@ -34,17 +57,12 @@
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
<item index="9" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
<item index="10" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
<item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.Nullable" />
<item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.Nullable" />
<item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="14">
<list size="9">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="javax.validation.constraints.NotNull" />
@@ -54,11 +72,6 @@
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
<item index="9" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
<item index="10" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
<item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.NonNull" />
<item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.NonNull" />
<item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.NonNull" />
</list>
</value>
</option>
@@ -66,12 +79,9 @@
<component name="ProjectResources">
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="PsiViewerSettings">
<option name="splitDividerLocation" value="35" />
</component>
<component name="SuppressABINotification">
<option name="modulesWithSuppressedNotConfigured">
<set>
@@ -88,7 +98,4 @@
<option name="autoscroll" value="false" />
<option name="showOnlyWarnings" value="false" />
</component>
<component name="intellij-api-watcher-check-current-project">
<option name="shouldCheckCurrentProject" value="true" />
</component>
</project>

171
.idea/projectCodeStyle.xml generated Normal file
View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="1" />
<ADDITIONAL_INDENT_OPTIONS fileType="css">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="groovy">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="gsp">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="haml">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="js">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="jsp">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="php">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="py">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="sass">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="scala">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="sql">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="xml">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="yml">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
<option name="USE_RELATIVE_INDENTS" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<codeStyleSettings language="JAVA">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
<indentOptions />
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="PHP">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
</project>

View File

@@ -12,7 +12,6 @@
<list>
<option value=":compiler:generateTests" />
<option value=":compiler:tests-java8:generateTests" />
<option value=":compiler:tests-against-klib:generateTests" />
<option value=":js:js.tests:generateTests" />
<option value=":core:descriptors.runtime:generateTests" />
</list>

View File

@@ -15,6 +15,6 @@
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
<method v="2" />
</configuration>
</component>

View File

@@ -1,19 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA (Not Internal)" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-Pidea.is.internal=false" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
</configuration>
</component>

View File

@@ -1,20 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test: KMM" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="kmmTest" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method v="2" />
</configuration>
</component>

View File

@@ -1,22 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test: stdlib-js public kotlin api test, overwrite results" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="--tests &quot;org.jetbrains.kotlin.js.test.ApiTest&quot; -Poverwrite.output=true --parallel" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value=":js:js.tests:cleanTest" />
<option value=":js:js.tests:test" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<GradleScriptDebugEnabled>false</GradleScriptDebugEnabled>
<method v="2" />
</configuration>
</component>

View File

@@ -1,13 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run IR test in node.js" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/js/js.translator/testData/package.json" />
<command value="run" />
<scripts>
<script value="runIrTestInNode" />
</scripts>
<arguments value="$FilePath$" />
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@@ -1,3 +1,3 @@
<component name="DependencyValidationManager">
<scope name="Apply copyright" pattern="!file[*]:*//testData//*&amp;&amp;!file[*]:testData//*&amp;&amp;!file[*]:*.gradle.kts&amp;&amp;!file[*]:*.gradle&amp;&amp;!file[group:kotlin-ultimate]:*/&amp;&amp;!file[kotlin.libraries]:stdlib/api//*" />
<scope name="Apply copyright" pattern="!file[*]:*//testData//*&amp;&amp;!file[*]:testData//*&amp;&amp;!file[*]:*.gradle.kts&amp;&amp;!file[*]:*.gradle" />
</component>

6
.idea/upsource.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UpsourceSharedProjectSettings">
<option name="upsourceUrl" value="https://upsource.jetbrains.com/" />
</component>
</project>

11
.idea/vcs.xml generated
View File

@@ -1,13 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CommitMessageInspectionProfile">
<profile version="1.0">
<inspection_tool class="BodyLimit" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GrazieCommit" enabled="true" level="TYPO" enabled_by_default="true" />
<inspection_tool class="SubjectBodySeparation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SubjectLimit" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
<component name="IssueNavigationConfiguration">
<option name="links">
<list>
@@ -33,4 +25,5 @@
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
</project>

View File

@@ -1,4 +0,0 @@
## Code of Conduct
This project and the corresponding community is governed by the [JetBrains Open Source and Community Code of Conduct](https://confluence.jetbrains.com/display/ALL/JetBrains+Open+Source+and+Community+Code+of+Conduct). Please make sure you read it.

File diff suppressed because it is too large Load Diff

106
ReadMe.md
View File

@@ -1,7 +1,8 @@
[![official project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![TeamCity (simple build status)](https://img.shields.io/teamcity/http/teamcity.jetbrains.com/s/Kotlin_KotlinPublic_Compiler.svg)](https://teamcity.jetbrains.com/buildConfiguration/Kotlin_KotlinPublic_Compiler?branch=%3Cdefault%3E&buildTypeTab=overview&mode=builds)
[![Maven Central](https://img.shields.io/maven-central/v/org.jetbrains.kotlin/kotlin-maven-plugin.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.jetbrains.kotlin%22)
[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0)
[![official project](http://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
<a href="http://slack.kotlinlang.org/"><img src="http://slack.kotlinlang.org/badge.svg" height="20"></a>
[![TeamCity (simple build status)](https://img.shields.io/teamcity/http/teamcity.jetbrains.com/s/Kotlin_dev_Compiler.svg)](https://teamcity.jetbrains.com/viewType.html?buildTypeId=Kotlin_dev_Compiler&branch_Kotlin_dev=%3Cdefault%3E&tab=buildTypeStatusDiv)
[![Maven Central](https://img.shields.io/maven-central/v/org.jetbrains.kotlin/kotlin-maven-plugin.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.jetbrains.kotlin%22)
[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0)
# Kotlin Programming Language
@@ -9,13 +10,13 @@ Welcome to [Kotlin](https://kotlinlang.org/)! Some handy links:
* [Kotlin Site](https://kotlinlang.org/)
* [Getting Started Guide](https://kotlinlang.org/docs/tutorials/getting-started.html)
* [Try Kotlin](https://play.kotlinlang.org/)
* [Try Kotlin](https://try.kotlinlang.org/)
* [Kotlin Standard Library](https://kotlinlang.org/api/latest/jvm/stdlib/index.html)
* [Issue Tracker](https://youtrack.jetbrains.com/issues/KT)
* [Forum](https://discuss.kotlinlang.org/)
* [Kotlin Blog](https://blog.jetbrains.com/kotlin/)
* [Follow Kotlin on Twitter](https://twitter.com/kotlin)
* [Public Slack channel](https://slack.kotlinlang.org/)
* [Public Slack channel](http://slack.kotlinlang.org/)
* [TeamCity CI build](https://teamcity.jetbrains.com/project.html?tab=projectOverview&projectId=Kotlin)
## Editing Kotlin
@@ -37,20 +38,11 @@ In order to build Kotlin distribution you need to have:
JDK_18="path to JDK 1.8"
JDK_9="path to JDK 9"
For local development, if you're not working on bytecode generation or the standard library, it's OK to have only JDK 1.8 and JDK 9 installed, and to point `JDK_16` and `JDK_17` environment variables to your JDK 1.8 installation.
For local development, if you're not working on bytecode generation or the standard library, it's OK to have only JDK 1.8 and JDK 9 installed, and to point JDK_16 and JDK_17 environment variables to your JDK 1.8 installation.
You also can use [Gradle properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties) to setup `JDK_*` variables.
You also can use [Gradle properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_properties_and_system_properties) to setup JDK_* variables.
Note: The JDK 6 for MacOS is not available on Oracle's site. You can install it by
```bash
$ brew tap caskroom/versions
$ brew cask install java6
```
On Windows you might need to add long paths setting to the repo:
git config core.longpaths true
> Note: The JDK 6 for MacOS is not available on Oracle's site. You can [download it here](https://support.apple.com/kb/DL1572).
## Building
@@ -78,7 +70,7 @@ command line parameters on the first run:
- `clean` - clean build results
- `dist` - assembles the compiler distribution into `dist/kotlinc/` folder
- `ideaPlugin` - assembles the Kotlin IDEA plugin distribution into `dist/artifacts/ideaPlugin/Kotlin/` folder
- `ideaPlugin` - assembles the Kotlin IDEA plugin distribution into `dist/artifacts/Kotlin` folder
- `install` - build and install all public artifacts into local maven repository
- `runIde` - build IDEA plugin and run IDEA with it
- `coreLibsTest` - build and run stdlib, reflect and kotlin-test tests
@@ -86,15 +78,13 @@ command line parameters on the first run:
- `compilerTest` - build and run all compiler tests
- `ideaPluginTest` - build and run all IDEA plugin tests
To reproduce TeamCity build use `-Pteamcity=true` flag. Local builds don't run proguard and have jar compression disabled by default.
**OPTIONAL:** Some artifacts, mainly Maven plugin ones, are built separately with Maven.
Refer to [libraries/ReadMe.md](libraries/ReadMe.md) for details.
### Building for different versions of IntelliJ IDEA and Android Studio
Kotlin plugin is intended to work with several recent versions of IntelliJ IDEA and Android Studio. Each platform is allowed to have a different set of features and might provide a slightly different API. Instead of using several parallel Git branches, project stores everything in a single branch, but files may have counterparts with version extensions (\*.as32, \*.172, \*.181). The primary file is expected to be replaced with its counterpart when targeting non-default platform.
Kotlin plugin is indented to work with several recent versions of IntelliJ IDEA and Android Studio. Each platform is allowed to have a different set of features and might provide a slightly different API. Instead of using several parallel Git branches, project stores everything in a single branch, but files may have counterparts with version extensions (\*.as32, \*.172, \*.181). The primary file is expected to be replaced with its counterpart when targeting non-default platform.
More detailed description of this scheme can be found at https://github.com/JetBrains/bunches/blob/master/ReadMe.md.
@@ -105,47 +95,36 @@ Development for some particular platform is possible after 'switching' that can
```sh
cd kotlin-project-dir
# switching to IntelliJ Idea 2019.1
bunch switch 191
# switching to IntelliJ Idea 2018.2
bunch switch . 182
```
## <a name="working-in-idea"></a> Working with the project in IntelliJ IDEA
Working with the Kotlin project requires at least IntelliJ IDEA 2019.1. You can download IntelliJ IDEA 2019.1 [here](https://www.jetbrains.com/idea/download).
Working with the Kotlin project requires IntelliJ IDEA 2017.3. You can download IntelliJ IDEA 2017.3 [here](https://www.jetbrains.com/idea/download).
After cloning the project, to import the project in IntelliJ choose the project directory in the Open project dialog. Then, after project opened, select
`File` -> `New` -> `Module from Existing Sources...` in the menu, and select `build.gradle.kts` file in the project's root folder.
To import the project in Intellij choose project directory in Open project dialog. Then, after project opened, Select
`File` -> `New...` -> `Module from Existing Sources` in the menu, and select `build.gradle.kts` file in the project's root folder.
In the import dialog, select `use default gradle wrapper`.
To be able to run tests from IntelliJ easily, check `Delegate IDE build/run actions to Gradle` and choose `Gradle Test Runner` in the Gradle runner settings after importing the project.
To be able to run tests from IntelliJ easily, check `Delegate IDE build/run actions to Gradle` and choose `Gradle Test Runner` in the Gradle runner settings.
At this time, you can use the latest released `1.3.x` version of the Kotlin plugin for working with the code. To make sure you have the latest version installed, use `Tools` -> `Kotlin` -> `Configure Kotlin Plugin Updates`.
At this time, you can use the latest released 1.2.x version of the Kotlin plugin for working with the code. To make sure you have the latest version installed, use Tools | Kotlin | Configure Kotlin Plugin Updates and press "Check for updates now".
### Compiling and running
From this root project there are Run/Debug Configurations for running `IDEA` or the `Generate Compiler Tests` for example; so if you want to try out the latest and greatest IDEA plugin
From this root project there are Run/Debug Configurations for running IDEA or the Compiler Tests for example; so if you want to try out the latest and greatest IDEA plugin
* `VCS` -> `Git` -> `Pull`
* Run the `IDEA` run configuration in the project
* A child IntelliJ IDEA with the Kotlin plugin will then startup
* VCS -> Git -> Pull
* Run the "IDEA" run configuration in the project
* a child IntelliJ IDEA with the Kotlin plugin will then startup
### Including into composite build
To include kotlin compiler into [composite build](https://docs.gradle.org/current/userguide/composite_builds.html) you need to define `dependencySubstitution` for `kotlin-compiler` module in `settings.gradle.kts`
To include kotlin compiler into [composite build](https://docs.gradle.org/current/userguide/composite_builds.html) you need to define `dependencySubstitution` for `kotlin-compiler` module in `settings.gradle`
```Kotlin
includeBuild("/path/to/kotlin") {
dependencySubstitution {
substitute(module("org.jetbrains.kotlin:kotlin-compiler"))
.with(project(":include:kotlin-compiler"))
}
}
```
or in `settings.gradle`
```Groovy
includeBuild('/path/to/kotlin') {
dependencySubstitution {
substitute module('org.jetbrains.kotlin:kotlin-compiler') with project(':include:kotlin-compiler')
@@ -153,9 +132,38 @@ includeBuild('/path/to/kotlin') {
}
```
# License
Kotlin is distributed under the terms of the Apache License (Version 2.0). See [license folder](license/README.md) for details.
# Contributing
Please be sure to review Kotlin's [contributing guidelines](docs/contributing.md) to learn how to help the project.
We love contributions! There's [lots to do on Kotlin](https://youtrack.jetbrains.com/issues/KT) and on the
[standard library](https://youtrack.jetbrains.com/issues/KT?q=%23Kotlin%20%23Unresolved%20and%20(links:%20KT-2554,%20KT-4089%20or%20%23Libraries)) so why not chat with us
about what you're interested in doing? Please join the #kontributors channel in [our Slack chat](http://slack.kotlinlang.org/)
and let us know about your plans.
If you want to find some issues to start off with, try [this query](https://youtrack.jetbrains.com/issues/KT?q=tag:%20%7BUp%20For%20Grabs%7D%20%23Unresolved) which should find all Kotlin 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.
A nice gentle way to contribute would be to review the [standard library docs](https://kotlinlang.org/api/latest/jvm/stdlib/index.html)
and find classes or functions which are not documented very well and submit a patch.
In particular it'd be great if all functions included a nice example of how to use it such as for the
[`hashMapOf()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/hash-map-of.html) function.
This is implemented using the [`@sample`](https://github.com/JetBrains/kotlin/blob/1.1.0/libraries/stdlib/src/kotlin/collections/Maps.kt#L91)
macro to include code from a test function. The benefits of this approach are twofold; First, the API's documentation is improved via beneficial examples that help new users and second, the code coverage is increased.
Also the [JavaScript translation](https://github.com/JetBrains/kotlin/blob/master/js/ReadMe.md) could really use your help. See the [JavaScript contribution section](https://github.com/JetBrains/kotlin/blob/master/js/ReadMe.md) for more details.
Some of the code in the standard library is created by generating code from templates. See the [README](libraries/stdlib/ReadMe.md) in the stdlib section for how to run the code generator. The existing templates can be used as examples for creating new ones.
## Submitting patches
The best way to submit a patch is to [fork the project on github](https://help.github.com/articles/fork-a-repo/) then send us a
[pull request](https://help.github.com/articles/creating-a-pull-request/) via [github](https://github.com).
If you create your own fork, it might help to enable rebase by default
when you pull by executing
``` bash
git config --global pull.rebase true
```
This will avoid your local repo having too many merge commits
which will help keep your pull request simple and easy to apply.

View File

@@ -8,7 +8,7 @@ plugins {
dependencies {
compile(commonDep("org.apache.ant", "ant"))
compile(project(":kotlin-preloader"))
compile(kotlinStdlib())
compile(projectDist(":kotlin-stdlib"))
}
sourceSets {
@@ -17,5 +17,9 @@ sourceSets {
}
runtimeJar {
manifest.attributes["Class-Path"] = "$compilerManifestClassPath kotlin-preloader.jar"
from("$projectDir/src") { include("**/*.xml") }
manifest.attributes.put("Class-Path", "kotlin-stdlib.jar kotlin-reflect.jar kotlin-script-runtime.jar kotlin-preloader.jar")
}
dist()

View File

@@ -38,7 +38,7 @@ internal object KotlinAntTaskUtil {
}
val compilerJar: File by jar("kotlin-compiler.jar")
val runtimeJar: File by jar("kotlin-stdlib.jar")
val runtimeJar: File by jar("kotlin-runtime.jar")
val reflectJar: File by jar("kotlin-reflect.jar")
private fun jar(name: String) = lazy {

View File

@@ -129,7 +129,7 @@ class KotlinCompilerAdapter : Javac13() {
}
companion object {
private val KOTLIN_EXTENSIONS = listOf("kt", "kts")
private val KOTLIN_EXTENSIONS = Arrays.asList("kt", "kts")
private fun filterOutKotlinSources(files: Array<File>): Array<File> {
return files.filterNot {

View File

@@ -1,148 +0,0 @@
import kotlinx.benchmark.gradle.benchmark
val benchmarks_version = "0.2.0-dev-7"
buildscript {
val benchmarks_version = "0.2.0-dev-7"
repositories {
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
if (cacheRedirectorEnabled) {
maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlinx")
maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev")
} else {
maven("https://dl.bintray.com/kotlin/kotlinx")
maven("https://dl.bintray.com/kotlin/kotlin-dev")
}
}
dependencies {
classpath("org.jetbrains.kotlinx:kotlinx.benchmark.gradle:$benchmarks_version")
}
}
apply(plugin = "kotlinx.benchmark")
plugins {
java
kotlin("jvm")
}
repositories {
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
if (cacheRedirectorEnabled) {
maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlinx")
maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev")
} else {
maven("https://dl.bintray.com/kotlin/kotlinx")
maven("https://dl.bintray.com/kotlin/kotlin-dev")
}
}
dependencies {
compile(kotlinStdlib())
compile(project(":compiler:frontend"))
compile(projectTests(":compiler:tests-common"))
compile(project(":compiler:cli"))
compile(intellijCoreDep()) { includeJars("intellij-core") }
compile(jpsStandalone()) { includeJars("jps-model") }
Platform[192].orHigher {
compile(intellijPluginDep("java"))
}
compile(intellijDep()) { includeIntellijCoreJarDependencies(project) }
compile("org.jetbrains.kotlinx:kotlinx.benchmark.runtime-jvm:$benchmarks_version")
}
sourceSets {
"main" { projectDefault() }
}
benchmark {
configurations {
named("main") {
warmups = 10
iterations = 10
iterationTime = 1
iterationTimeUnit = "sec"
param("size", 1000)
}
register("fir") {
warmups = 10
iterations = 10
iterationTime = 1
iterationTimeUnit = "sec"
param("isIR", true)
param("size", 1000)
include("CommonCallsBenchmark")
include("ControlFlowAnalysisBenchmark")
//include("InferenceBaselineCallsBenchmark")
}
register("ni") {
warmups = 10
iterations = 10
iterationTime = 1
iterationTimeUnit = "sec"
param("useNI", true)
param("isIR", false)
param("size", 1000)
include("InferenceBaselineCallsBenchmark")
include("InferenceExplicitArgumentsCallsBenchmark")
include("InferenceForInApplicableCandidate")
include("InferenceFromArgumentCallsBenchmark")
include("InferenceFromReturnTypeCallsBenchmark")
}
}
targets {
register("main")
}
}
tasks.named("classes") {
doLast {
tasks.named("mainBenchmarkJar", Zip::class.java) {
isZip64 = true
archiveName = "benchmarks.jar"
}
listOf("mainBenchmark", "mainFirBenchmark", "mainNiBenchmark").forEach {
tasks.named(it, JavaExec::class.java) {
systemProperty("idea.home.path", intellijRootDir().canonicalPath)
}
}
}
}
tasks.register<JavaExec>("runBenchmark") {
// jmhArgs example: -PjmhArgs='CommonCalls -p size=500 -p isIR=true -p useNI=true -f 1'
val jmhArgs = if (project.hasProperty("jmhArgs")) project.property("jmhArgs").toString() else ""
val resultFilePath = "$buildDir/benchmarks/jmh-result.json"
val ideaHome = intellijRootDir().canonicalPath
val benchmarkJarPath = "$buildDir/benchmarks/main/jars/benchmarks.jar"
args = mutableListOf("-Didea.home.path=$ideaHome", benchmarkJarPath, "-rf", "json", "-rff", resultFilePath) + jmhArgs.split("\\s".toRegex())
main = "-jar"
doLast {
if (project.kotlinBuildProperties.isTeamcityBuild) {
val jsonArray = com.google.gson.JsonParser.parseString(File(resultFilePath).readText()).asJsonArray
jsonArray.forEach {
val benchmark = it.asJsonObject
// remove unnecessary name parts from string like this "org.jetbrains.kotlin.benchmarks.CommonCallsBenchmark.benchmark"
val name = benchmark["benchmark"].asString.removeSuffix(".benchmark").let {
val indexOfLastDot = it.indexOfLast { it == '.' }
it.removeRange(0..indexOfLastDot)
}
val params = benchmark["params"].asJsonObject
val isIR = if (params.has("isIR")) params["isIR"].asString else "false"
val useNI = if (params.has("useNI")) params["useNI"].asString else "false"
val size = params["size"].asString
val score = "%.3f".format(benchmark["primaryMetric"].asJsonObject["score"].asString.toFloat())
val irPostfix = if (isIR.toBoolean()) " isIR=true" else ""
val niPostfix = if (useNI.toBoolean() && !isIR.toBoolean()) " isNI=true" else ""
println("""##teamcity[buildStatisticValue key='$name size=$size${irPostfix}$niPostfix' value='$score']""")
}
}
}
}

View File

@@ -1,19 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.Param
import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State
@State(Scope.Benchmark)
abstract class AbstractInferenceBenchmark : AbstractSimpleFileBenchmark() {
@Param("true", "false")
private var useNI: Boolean = false
override val useNewInference: Boolean
get() = useNI
}

View File

@@ -1,172 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import com.intellij.openapi.Disposable
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.impl.PsiFileFactoryImpl
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.testFramework.LightVirtualFile
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.jvm.compiler.*
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.context.SimpleGlobalContext
import org.jetbrains.kotlin.context.withModule
import org.jetbrains.kotlin.context.withProject
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.createSession
import org.jetbrains.kotlin.fir.java.FirJavaElementFinder
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveProcessor
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.storage.ExceptionTracker
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.io.File
private fun createFile(shortName: String, text: String, project: Project): KtFile {
val virtualFile = object : LightVirtualFile(shortName, KotlinLanguage.INSTANCE, text) {
override fun getPath(): String {
//TODO: patch LightVirtualFile
return "/" + name
}
}
virtualFile.charset = CharsetToolkit.UTF8_CHARSET
val factory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl
return factory.trySetupPsiForFile(virtualFile, KotlinLanguage.INSTANCE, true, false) as KtFile
}
private val JDK_PATH = File("${System.getProperty("java.home")!!}/lib/rt.jar")
private val RUNTIME_JAR = File(System.getProperty("kotlin.runtime.path") ?: "dist/kotlinc/lib/kotlin-runtime.jar")
private val LANGUAGE_FEATURE_SETTINGS =
LanguageVersionSettingsImpl(
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
specificFeatures = mapOf(LanguageFeature.NewInference to LanguageFeature.State.ENABLED)
)
private fun newConfiguration(useNewInference: Boolean): CompilerConfiguration {
val configuration = CompilerConfiguration()
configuration.put(CommonConfigurationKeys.MODULE_NAME, "benchmark")
configuration.put(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, "../compiler/cli/cli-common/resources")
configuration.addJvmClasspathRoot(JDK_PATH)
configuration.addJvmClasspathRoot(RUNTIME_JAR)
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
val newInferenceState = if (useNewInference) LanguageFeature.State.ENABLED else LanguageFeature.State.DISABLED
configuration.languageVersionSettings = LanguageVersionSettingsImpl(
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
specificFeatures = mapOf(
LanguageFeature.NewInference to newInferenceState
)
)
return configuration
}
@State(Scope.Benchmark)
abstract class AbstractSimpleFileBenchmark {
private var myDisposable: Disposable = Disposable { }
private lateinit var env: KotlinCoreEnvironment
private lateinit var file: KtFile
@Param("true", "false")
protected var isIR: Boolean = false
protected open val useNewInference get() = isIR
@Setup(Level.Trial)
fun setUp() {
if (isIR && !useNewInference) error("Invalid configuration")
env = KotlinCoreEnvironment.createForTests(
myDisposable,
newConfiguration(useNewInference),
EnvironmentConfigFiles.JVM_CONFIG_FILES
)
if (isIR) {
Extensions.getArea(env.project)
.getExtensionPoint(PsiElementFinder.EP_NAME)
.unregisterExtension(JavaElementFinder::class.java)
}
file = createFile(
"test.kt",
buildText(),
env.project
)
}
protected fun analyzeGreenFile(bh: Blackhole) {
if (isIR) {
analyzeGreenFileIr(bh)
} else {
analyzeGreenFileFrontend(bh)
}
}
private fun analyzeGreenFileFrontend(bh: Blackhole) {
val tracker = ExceptionTracker()
val storageManager: StorageManager =
LockBasedStorageManager.createWithExceptionHandling("benchmarks", tracker)
val context = SimpleGlobalContext(storageManager, tracker)
val module =
ModuleDescriptorImpl(
Name.special("<benchmark>"), storageManager,
JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FROM_DEPENDENCIES)
)
val moduleContext = context.withProject(env.project).withModule(module)
val result = TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
moduleContext.project,
listOf(file),
NoScopeRecordCliBindingTrace(),
env.configuration,
{ scope -> JvmPackagePartProvider(LANGUAGE_FEATURE_SETTINGS, scope) }
)
assert(result.bindingContext.diagnostics.none { it.severity == Severity.ERROR })
bh.consume(result.shouldGenerateCode)
}
private fun analyzeGreenFileIr(bh: Blackhole) {
val scope = GlobalSearchScope.filesScope(env.project, listOf(file.virtualFile))
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
val session = createSession(env, scope)
val firProvider = session.firProvider as FirProviderImpl
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
val totalTransformer = FirTotalResolveProcessor(session)
val firFile = builder.buildFirFile(file).also(firProvider::recordFile)
totalTransformer.process(listOf(firFile))
bh.consume(firFile.hashCode())
Extensions.getArea(env.project)
.getExtensionPoint(PsiElementFinder.EP_NAME)
.unregisterExtension(FirJavaElementFinder::class.java)
}
protected abstract fun buildText(): String
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class CommonCallsBenchmark : AbstractSimpleFileBenchmark(){
@Param("1", "10", "100", "1000", "3000", "5000", "7000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun foo(): Int = 1
|
|fun bar() {
|${(1..size).joinToString("\n") { " foo()" }}
|}
""".trimMargin()
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class ComplexDataFlowBenchmark : AbstractSimpleFileBenchmark(){
@Param("1", "100", "1000", "3000", "5000", "7000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|
|fun bar(x: Any?) {
| var y = x
|${(1..size).joinToString("\n") {
"""
|if (x is String) {
| y = x
|}
|y = 1
""".trimMargin()
}}
|}
""".trimMargin()
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class ControlFlowAnalysisBenchmark : AbstractSimpleFileBenchmark() {
@Param("1000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
buildString {
appendLine("fun test() {")
for (i in 0 until size) {
appendLine("for (i$i in 0..10) { ")
}
for (i in 0 until size) {
appendLine("}")
}
appendLine("}")
}
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class ControlFlowOperators : AbstractSimpleFileBenchmark(){
@Param("1", "100", "1000", "3000", "5000", "7000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|var isTrue = true
|var s = ""
|fun bar() {
|${(1..size).joinToString("\n") {
"""
|var x$it: String
|
|when (s) {
| "A" -> { x$it = "1" }
| "B" -> { x$it = "2" }
| else -> { x$it = "3" }
|}
|
|while (isTrue) {
| x$it.hashCode()
|}
""".trimMargin()
}}
|}
""".trimMargin()
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class InferenceBaselineCallsBenchmark : AbstractSimpleFileBenchmark() {
@Param("1", "10", "100", "1000", "5000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun foo(x: Int): Int = 1
|fun expectsInt(x: Int) {}
|fun bar(v: Int) {
|${(1..size).map { " expectsInt(foo(v))" }.joinToString("\n")}
|}
""".trimMargin()
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class InferenceExplicitArgumentsCallsBenchmark : AbstractInferenceBenchmark() {
@Param("1", "10", "100", "1000", "5000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun <T> foo(x: T): Int = 1
|fun expectsInt(x: Int) {}
|fun bar(v: Int) {
|${(1..size).map { " expectsInt(foo<Int>(v))" }.joinToString("\n")}
|}
""".trimMargin()
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class InferenceForInApplicableCandidate : AbstractInferenceBenchmark() {
@Param("1", "10", "100", "1000", "5000", "10000")
private var size: Int = 1
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun <T : Comparable<T>> foo(x: MutableList<T>) {}
|fun <T> foo(x: MutableList<T>, y: (T, T) -> Int) {}
|fun bar(x: MutableList<Any>) {
|${(1..size).joinToString("\n") { " foo(x) { a, b -> 1 }" }}
|}
""".trimMargin()
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class InferenceFromArgumentCallsBenchmark : AbstractInferenceBenchmark() {
@Param("1", "10", "100", "1000", "5000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun <T> foo(x: T): Int = 1
|fun expectsInt(x: Int) {}
|fun bar(v: Int) {
|${(1..size).map { " expectsInt(foo(v))" }.joinToString("\n")}
|}
""".trimMargin()
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class InferenceFromReturnTypeCallsBenchmark : AbstractInferenceBenchmark() {
@Param("1", "10", "100", "1000", "5000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun <T> foo(x: Int): T = null!!
|fun expectsInt(x: Int) {}
|fun bar(v: Int) {
|${(1..size).map { " expectsInt(foo(v))" }.joinToString("\n")}
|}
""".trimMargin()
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class IntArrayPlusBenchmark : AbstractSimpleFileBenchmark() {
@Param("1", "10", "100", "1000", "3000", "5000", "7000", "10000")
private var size: Int = 0
@Benchmark
//@Fork(jvmArgsAppend = ["-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"])
fun benchmark(bh: Blackhole) {
if (!isIR) error("Doesn't make sense to run it on old frontend on buildserver")
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun bar(x: IntArray, y: IntArray) {
|${(1..size).joinToString("\n") { " x + y" }}
|}
""".trimMargin()
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class ManyImplicitReceiversBenchmark : AbstractSimpleFileBenchmark() {
@Param("1", "10", "50")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText(): String {
return buildString {
appendLine("inline fun <T, R> with(receiver: T, block: T.() -> R): R = block()")
for (i in 1..size) {
appendLine("interface A$i {")
appendLine(" fun foo$i()")
appendLine("}")
appendLine()
}
appendLine()
append("fun test(")
append((1..size).joinToString(", ") { "a$it: A$it" })
appendLine(" {")
for (i in 1..size) {
appendLine("with(a$i) {")
}
for (i in 1..size) {
appendLine("foo$i()")
}
for (i in 1..size) {
appendLine("}")
}
appendLine("}")
}
}
}

View File

@@ -1,31 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class ManyValsBenchmark : AbstractSimpleFileBenchmark(){
@Param("1", "100", "1000", "3000", "5000", "7000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun bar() {
|${(1..size).joinToString("\n") { " val x$it: Int = 1" }}
|}
""".trimMargin()
}

View File

@@ -1,31 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class ManyVarsBenchmark : AbstractSimpleFileBenchmark(){
@Param("1", "100", "1000", "3000", "5000", "7000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun bar() {
|${(1..size).joinToString("\n") { " var x$it: Int = 1" }}
|}
""".trimMargin()
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class PlusAssignOperatorDesugaringBenchmark : AbstractInferenceBenchmark() {
@Param("9", "10", "11", "12", "13", "14")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText(): String = buildString {
appendLine(
"""
class A {
operator fun <T : Number> plus(other: (Int) -> T): A = this
operator fun <T : CharSequence> plusAssign(other: (String) -> T) {}
}
""".trimIndent()
)
appendLine("fun test() {")
appendLine("var a = A()")
for (i in 1..size) {
appendLine("a += {")
}
for (i in 1..size) {
appendLine(
"""
it.inc()
1
}
""".trimIndent()
)
}
appendLine()
}
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class SimpleDataFlowBenchmark : AbstractSimpleFileBenchmark(){
@Param("1", "100", "1000", "3000", "5000", "7000", "10000")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText() =
"""
|fun foo(x: Int): Int = 1
|var x = 1
|fun bar(v: Int) {
|${(1..size).joinToString("\n") { " x = foo(v)" }}
|}
""".trimMargin()
}

View File

@@ -1,3 +1,4 @@
description = "Kotlin Build Common"
plugins {
@@ -11,21 +12,19 @@ dependencies {
compileOnly(project(":compiler:cli-common"))
compileOnly(project(":compiler:frontend.java"))
compileOnly(project(":js:js.serializer"))
compileOnly(project(":js:js.config"))
compileOnly(project(":kotlin-util-klib-metadata"))
compileOnly(project(":js:js.frontend"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeJars("asm-all", "trove4j", "util", rootProject = rootProject) }
compileOnly(intellijDep()) { includeJars("annotations", "asm-all", "trove4j", "util") }
compileOnly(project(":kotlin-reflect-api"))
testCompileOnly(project(":compiler:cli-common"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(commonDep("junit:junit"))
testCompile(protobufFull())
testCompile(kotlinStdlib())
Platform[193].orLower {
testCompileOnly(intellijDep()) { includeJars("openapi", rootProject = rootProject) }
}
testRuntime(project(":kotlin-reflect"))
testCompile(projectDist(":kotlin-stdlib"))
testCompileOnly(intellijDep()) { includeJars("openapi") }
testRuntime(projectDist(":kotlin-reflect"))
}
sourceSets {
@@ -33,12 +32,12 @@ sourceSets {
"test" { projectDefault() }
}
publish()
runtimeJar()
sourcesJar()
javadocJar()
testsJar()
projectTest(parallel = true)
projectTest()
publish()

View File

@@ -1,6 +1,6 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.build
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.isPreRelease
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import kotlin.reflect.KClass
interface BuildMetaInfo {
@@ -41,8 +40,7 @@ abstract class BuildMetaInfoFactory<T : BuildMetaInfo>(private val metaInfoClass
multiplatformEnable: Boolean,
ownVersion: Int,
coroutinesVersion: Int,
multiplatformVersion: Int,
metadataVersionArray: IntArray?
multiplatformVersion: Int
): T
fun create(args: CommonCompilerArguments): T {
@@ -59,14 +57,10 @@ abstract class BuildMetaInfoFactory<T : BuildMetaInfo>(private val metaInfoClass
multiplatformEnable = args.multiPlatform,
ownVersion = OWN_VERSION,
coroutinesVersion = COROUTINES_VERSION,
multiplatformVersion = MULTIPLATFORM_VERSION,
metadataVersionArray = args.metadataVersion?.let((BinaryVersion)::parseVersionArray)
multiplatformVersion = MULTIPLATFORM_VERSION
)
}
fun serializeToString(args: CommonCompilerArguments): String =
serializeToString(create(args))
fun serializeToString(info: T): String =
serializeToPlainText(info, metaInfoClass)
@@ -78,4 +72,4 @@ abstract class BuildMetaInfoFactory<T : BuildMetaInfo>(private val metaInfoClass
const val COROUTINES_VERSION: Int = 0
const val MULTIPLATFORM_VERSION: Int = 0
}
}
}

View File

@@ -1,11 +1,12 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.build
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import org.jetbrains.kotlin.utils.JsMetadataVersion
/**
* If you want to add a new field, check its type is supported by [serializeToPlainText], [deserializeFromPlainText]
@@ -38,26 +39,22 @@ data class CommonBuildMetaInfo(
multiplatformEnable: Boolean,
ownVersion: Int,
coroutinesVersion: Int,
multiplatformVersion: Int,
metadataVersionArray: IntArray?
): CommonBuildMetaInfo {
val metadataVersion = metadataVersionArray?.let(::JvmMetadataVersion) ?: JvmMetadataVersion.INSTANCE
return CommonBuildMetaInfo(
isEAP = isEAP,
compilerBuildVersion = compilerBuildVersion,
languageVersionString = languageVersionString,
apiVersionString = apiVersionString,
coroutinesEnable = coroutinesEnable,
coroutinesWarn = coroutinesWarn,
coroutinesError = coroutinesError,
multiplatformEnable = multiplatformEnable,
metadataVersionMajor = metadataVersion.major,
metadataVersionMinor = metadataVersion.minor,
metadataVersionPatch = metadataVersion.patch,
ownVersion = ownVersion,
coroutinesVersion = coroutinesVersion,
multiplatformVersion = multiplatformVersion
)
}
multiplatformVersion: Int
) = CommonBuildMetaInfo(
isEAP = isEAP,
compilerBuildVersion = compilerBuildVersion,
languageVersionString = languageVersionString,
apiVersionString = apiVersionString,
coroutinesEnable = coroutinesEnable,
coroutinesWarn = coroutinesWarn,
coroutinesError = coroutinesError,
multiplatformEnable = multiplatformEnable,
metadataVersionMajor = JvmMetadataVersion.INSTANCE.major,
metadataVersionMinor = JvmMetadataVersion.INSTANCE.minor,
metadataVersionPatch = JvmMetadataVersion.INSTANCE.patch,
ownVersion = ownVersion,
coroutinesVersion = coroutinesVersion,
multiplatformVersion = multiplatformVersion
)
}
}
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.build
@@ -38,26 +38,22 @@ data class JsBuildMetaInfo(
multiplatformEnable: Boolean,
ownVersion: Int,
coroutinesVersion: Int,
multiplatformVersion: Int,
metadataVersionArray: IntArray?
): JsBuildMetaInfo {
val metadataVersion = metadataVersionArray?.let(::JsMetadataVersion) ?: JsMetadataVersion.INSTANCE
return JsBuildMetaInfo(
isEAP = isEAP,
compilerBuildVersion = compilerBuildVersion,
languageVersionString = languageVersionString,
apiVersionString = apiVersionString,
coroutinesEnable = coroutinesEnable,
coroutinesWarn = coroutinesWarn,
coroutinesError = coroutinesError,
multiplatformEnable = multiplatformEnable,
metadataVersionMajor = metadataVersion.major,
metadataVersionMinor = metadataVersion.minor,
metadataVersionPatch = metadataVersion.patch,
ownVersion = ownVersion,
coroutinesVersion = coroutinesVersion,
multiplatformVersion = multiplatformVersion
)
}
multiplatformVersion: Int
) = JsBuildMetaInfo(
isEAP = isEAP,
compilerBuildVersion = compilerBuildVersion,
languageVersionString = languageVersionString,
apiVersionString = apiVersionString,
coroutinesEnable = coroutinesEnable,
coroutinesWarn = coroutinesWarn,
coroutinesError = coroutinesError,
multiplatformEnable = multiplatformEnable,
metadataVersionMajor = JsMetadataVersion.INSTANCE.major,
metadataVersionMinor = JsMetadataVersion.INSTANCE.minor,
metadataVersionPatch = JsMetadataVersion.INSTANCE.patch,
ownVersion = ownVersion,
coroutinesVersion = coroutinesVersion,
multiplatformVersion = multiplatformVersion
)
}
}
}

View File

@@ -53,29 +53,25 @@ data class JvmBuildMetaInfo(
multiplatformEnable: Boolean,
ownVersion: Int,
coroutinesVersion: Int,
multiplatformVersion: Int,
metadataVersionArray: IntArray?
): JvmBuildMetaInfo {
val metadataVersion = metadataVersionArray?.let(::JvmMetadataVersion) ?: JvmMetadataVersion.INSTANCE
return JvmBuildMetaInfo(
isEAP = isEAP,
compilerBuildVersion = compilerBuildVersion,
languageVersionString = languageVersionString,
apiVersionString = apiVersionString,
coroutinesEnable = coroutinesEnable,
coroutinesWarn = coroutinesWarn,
coroutinesError = coroutinesError,
multiplatformEnable = multiplatformEnable,
metadataVersionMajor = metadataVersion.major,
metadataVersionMinor = metadataVersion.minor,
metadataVersionPatch = metadataVersion.patch,
bytecodeVersionMajor = JvmBytecodeBinaryVersion.INSTANCE.major,
bytecodeVersionMinor = JvmBytecodeBinaryVersion.INSTANCE.minor,
bytecodeVersionPatch = JvmBytecodeBinaryVersion.INSTANCE.patch,
ownVersion = ownVersion,
coroutinesVersion = coroutinesVersion,
multiplatformVersion = multiplatformVersion
)
}
multiplatformVersion: Int
) = JvmBuildMetaInfo(
isEAP = isEAP,
compilerBuildVersion = compilerBuildVersion,
languageVersionString = languageVersionString,
apiVersionString = apiVersionString,
coroutinesEnable = coroutinesEnable,
coroutinesWarn = coroutinesWarn,
coroutinesError = coroutinesError,
multiplatformEnable = multiplatformEnable,
metadataVersionMajor = JvmMetadataVersion.INSTANCE.major,
metadataVersionMinor = JvmMetadataVersion.INSTANCE.minor,
metadataVersionPatch = JvmMetadataVersion.INSTANCE.patch,
bytecodeVersionMajor = JvmBytecodeBinaryVersion.INSTANCE.major,
bytecodeVersionMinor = JvmBytecodeBinaryVersion.INSTANCE.minor,
bytecodeVersionPatch = JvmBytecodeBinaryVersion.INSTANCE.patch,
ownVersion = ownVersion,
coroutinesVersion = coroutinesVersion,
multiplatformVersion = multiplatformVersion
)
}
}

View File

@@ -22,11 +22,9 @@ import org.jetbrains.kotlin.utils.sure
import java.io.File
open class GeneratedFile(
sourceFiles: Collection<File>,
val sourceFiles: Collection<File>,
val outputFile: File
) {
val sourceFiles = sourceFiles.sortedBy { it.path }
}
)
class GeneratedJvmClass (
sourceFiles: Collection<File>,

View File

@@ -1,9 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.build
val DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS = listOf("kt", "kts")

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.compilerRunner;
import kotlin.collections.CollectionsKt;
import com.intellij.util.containers.ContainerUtil;
import kotlin.jvm.JvmClassMappingKt;
import kotlin.reflect.KClass;
import kotlin.reflect.KProperty1;
@@ -24,10 +24,8 @@ import kotlin.reflect.KVisibility;
import kotlin.reflect.full.KClasses;
import kotlin.reflect.jvm.ReflectJvmMapping;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cli.common.arguments.Argument;
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments;
import org.jetbrains.kotlin.cli.common.arguments.InternalArgument;
import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt;
import org.jetbrains.kotlin.utils.StringsKt;
@@ -48,7 +46,7 @@ public class ArgumentUtils {
Class<? extends CommonToolArguments> argumentsClass = arguments.getClass();
convertArgumentsToStringList(arguments, argumentsClass.newInstance(), JvmClassMappingKt.getKotlinClass(argumentsClass), result);
result.addAll(arguments.getFreeArgs());
result.addAll(CollectionsKt.map(arguments.getInternalArguments(), InternalArgument::getStringRepresentation));
result.addAll(arguments.getInternalArguments());
return result;
}
@@ -60,7 +58,7 @@ public class ArgumentUtils {
@NotNull List<String> result
) throws IllegalAccessException, InstantiationException, InvocationTargetException {
for (KProperty1 property : KClasses.getMemberProperties(clazz)) {
Argument argument = findInstance(property.getAnnotations(), Argument.class);
Argument argument = ContainerUtil.findInstance(property.getAnnotations(), Argument.class);
if (argument == null) continue;
if (property.getVisibility() != KVisibility.PUBLIC) continue;
@@ -90,14 +88,4 @@ public class ArgumentUtils {
}
}
}
@Nullable
private static <T> T findInstance(Iterable<? super T> iterable, Class<T> clazz) {
for (Object item : iterable) {
if (clazz.isInstance(item)) {
return clazz.cast(item);
}
}
return null;
}
}

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.compilerRunner
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
@@ -25,7 +25,7 @@ class MessageCollectorToOutputItemsCollectorAdapter(
private val delegate: MessageCollector,
private val outputCollector: OutputItemsCollector
) : MessageCollector by delegate {
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) {
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
// TODO: consider adding some other way of passing input -> output mapping from compiler, e.g. dedicated service
OutputMessageUtil.parseOutputMessage(message)?.let {
outputCollector.add(it.sourceFiles, it.outputFile)

View File

@@ -16,15 +16,15 @@
package org.jetbrains.kotlin.compilerRunner;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class OutputItemsCollectorImpl implements OutputItemsCollector {
private final List<SimpleOutputItem> outputs = new ArrayList<>();
private final List<SimpleOutputItem> outputs = ContainerUtil.newArrayList();
@Override
public void add(Collection<File> sourceFiles, File outputFile) {

View File

@@ -37,34 +37,28 @@ interface IncrementalCacheCommon {
fun getSourceFileIfClass(fqName: FqName): File?
fun markDirty(removedAndCompiledSources: Collection<File>)
fun clearCacheForRemovedClasses(changesCollector: ChangesCollector)
fun getComplementaryFilesRecursive(dirtyFiles: Collection<File>): Collection<File>
fun updateComplementaryFiles(dirtyFiles: Collection<File>, expectActualTracker: ExpectActualTrackerImpl)
fun clearComplementaryFilesMapping(dirtyFiles: Collection<File>): Collection<File>
fun registerComplementaryFiles(expectActualTracker: ExpectActualTrackerImpl)
fun dump(): String
}
/**
* Incremental cache common for JVM and JS for specifit ClassName type
*/
abstract class AbstractIncrementalCache<ClassName>(
workingDir: File,
protected val pathConverter: FileToPathConverter
) : BasicMapsOwner(workingDir), IncrementalCacheCommon {
abstract class AbstractIncrementalCache<ClassName>(workingDir: File) : BasicMapsOwner(workingDir), IncrementalCacheCommon {
companion object {
private val SUBTYPES = "subtypes"
private val SUPERTYPES = "supertypes"
private val CLASS_FQ_NAME_TO_SOURCE = "class-fq-name-to-source"
private val COMPLEMENTARY_FILES = "complementary-files"
@JvmStatic
protected val SOURCE_TO_CLASSES = "source-to-classes"
@JvmStatic
protected val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
@JvmStatic protected val SOURCE_TO_CLASSES = "source-to-classes"
@JvmStatic protected val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
}
private val dependents = arrayListOf<AbstractIncrementalCache<ClassName>>()
fun addDependentCache(cache: AbstractIncrementalCache<ClassName>) {
dependents.add(cache)
}
override val thisWithDependentCaches: Iterable<AbstractIncrementalCache<ClassName>> by lazy {
val result = arrayListOf(this)
result.addAll(dependents)
@@ -73,25 +67,26 @@ abstract class AbstractIncrementalCache<ClassName>(
private val subtypesMap = registerMap(SubtypesMap(SUBTYPES.storageFile))
private val supertypesMap = registerMap(SupertypesMap(SUPERTYPES.storageFile))
protected val classFqNameToSourceMap = registerMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile, pathConverter))
protected val classFqNameToSourceMap = registerMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile))
internal abstract val sourceToClassesMap: AbstractSourceToOutputMap<ClassName>
internal abstract val dirtyOutputClassesMap: AbstractDirtyClassesMap<ClassName>
/**
* A file X is a complementary to a file Y if they contain corresponding expect/actual declarations.
* Complementary files should be compiled together during IC so the compiler does not complain
* about missing parts.
* TODO: provide a better solution (maintain an index of expect/actual declarations akin to IncrementalPackagePartProvider)
*/
private val complementaryFilesMap = registerMap(ComplementarySourceFilesMap(COMPLEMENTARY_FILES.storageFile, pathConverter))
private val complementaryFilesMap = registerMap(FilesMap(COMPLEMENTARY_FILES.storageFile))
override fun classesFqNamesBySources(files: Iterable<File>): Collection<FqName> =
files.flatMapTo(HashSet()) { sourceToClassesMap.getFqNames(it) }
override fun getSubtypesOf(className: FqName): Sequence<FqName> =
subtypesMap[className].asSequence()
subtypesMap[className].asSequence()
override fun getSourceFileIfClass(fqName: FqName): File? =
classFqNameToSourceMap[fqName]
classFqNameToSourceMap[fqName]
override fun markDirty(removedAndCompiledSources: Collection<File>) {
for (sourceFile in removedAndCompiledSources) {
@@ -107,8 +102,8 @@ abstract class AbstractIncrementalCache<ClassName>(
protected fun addToClassStorage(proto: ProtoBuf.Class, nameResolver: NameResolver, srcFile: File) {
val supertypes = proto.supertypes(TypeTable(proto.typeTable))
val parents = supertypes.map { nameResolver.getClassId(it.className).asSingleFqName() }
.filter { it.asString() != "kotlin.Any" }
.toSet()
.filter { it.asString() != "kotlin.Any" }
.toSet()
val child = nameResolver.getClassId(proto.fqName).asSingleFqName()
parents.forEach { subtypesMap.add(it, child) }
@@ -155,17 +150,13 @@ abstract class AbstractIncrementalCache<ClassName>(
removedFqNames.forEach { classFqNameToSourceMap.remove(it) }
}
protected class ClassFqNameToSourceMap(
storageFile: File,
private val pathConverter: FileToPathConverter
) :
BasicStringMap<String>(storageFile, EnumeratorStringDescriptor(), PathStringDescriptor) {
protected class ClassFqNameToSourceMap(storageFile: File) : BasicStringMap<String>(storageFile, EnumeratorStringDescriptor(), PathStringDescriptor) {
operator fun set(fqName: FqName, sourceFile: File) {
storage[fqName.asString()] = pathConverter.toPath(sourceFile)
storage[fqName.asString()] = sourceFile.canonicalPath
}
operator fun get(fqName: FqName): File? =
storage[fqName.asString()]?.let(pathConverter::toFile)
storage[fqName.asString()]?.let(::File)
fun remove(fqName: FqName) {
storage.remove(fqName.asString())
@@ -174,24 +165,18 @@ abstract class AbstractIncrementalCache<ClassName>(
override fun dumpValue(value: String) = value
}
override fun getComplementaryFilesRecursive(dirtyFiles: Collection<File>): Collection<File> {
override fun clearComplementaryFilesMapping(dirtyFiles: Collection<File>): Collection<File> {
val complementaryFiles = HashSet<File>()
val filesQueue = ArrayDeque(dirtyFiles)
while (filesQueue.isNotEmpty()) {
val file = filesQueue.pollFirst()
complementaryFilesMap[file].forEach {
if (complementaryFiles.add(it)) filesQueue.add(it)
}
complementaryFilesMap.remove(file).filterTo(filesQueue) { complementaryFiles.add(it) }
}
complementaryFiles.removeAll(dirtyFiles)
return complementaryFiles
}
override fun updateComplementaryFiles(dirtyFiles: Collection<File>, expectActualTracker: ExpectActualTrackerImpl) {
dirtyFiles.forEach {
complementaryFilesMap.remove(it)
}
override fun registerComplementaryFiles(expectActualTracker: ExpectActualTrackerImpl) {
val actualToExpect = hashMapOf<File, MutableSet<File>>()
for ((expect, actuals) in expectActualTracker.expectToActualMap) {
for (actual in actuals) {

View File

@@ -0,0 +1,112 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import java.io.File
import java.io.IOException
private val NORMAL_VERSION = 9
private val DATA_CONTAINER_VERSION = 3
private val NORMAL_VERSION_FILE_NAME = "format-version.txt"
private val DATA_CONTAINER_VERSION_FILE_NAME = "data-container-format-version.txt"
class CacheVersion(
private val ownVersion: Int,
private val versionFile: File,
private val whenVersionChanged: CacheVersion.Action,
private val whenTurnedOn: CacheVersion.Action,
private val whenTurnedOff: CacheVersion.Action,
isEnabled: ()->Boolean
) {
private val isEnabled by lazy(isEnabled)
private val actualVersion: Int?
get() = try {
versionFile.readText().toInt()
}
catch (e: NumberFormatException) {
null
}
catch (e: IOException) {
null
}
private val expectedVersion: Int
get() {
val metadata = JvmMetadataVersion.INSTANCE
val bytecode = JvmBytecodeBinaryVersion.INSTANCE
return ownVersion * 1000000 +
bytecode.major * 10000 + bytecode.minor * 100 +
metadata.major * 1000 + metadata.minor
}
fun checkVersion(): Action =
when (versionFile.exists() to isEnabled) {
true to true -> if (actualVersion != expectedVersion) whenVersionChanged else Action.DO_NOTHING
false to true -> whenTurnedOn
true to false -> whenTurnedOff
else -> Action.DO_NOTHING
}
fun saveIfNeeded() {
if (!isEnabled) return
if (!versionFile.parentFile.exists()) {
versionFile.parentFile.mkdirs()
}
versionFile.writeText(expectedVersion.toString())
}
fun clean() {
versionFile.delete()
}
@get:TestOnly
val formatVersionFile: File
get() = versionFile
// Order of entries is important, because actions are sorted in KotlinBuilder::checkVersions
enum class Action {
REBUILD_ALL_KOTLIN,
REBUILD_CHUNK,
CLEAN_NORMAL_CACHES,
CLEAN_DATA_CONTAINER,
DO_NOTHING
}
}
fun normalCacheVersion(dataRoot: File, enabled: Boolean? = null): CacheVersion =
CacheVersion(ownVersion = NORMAL_VERSION,
versionFile = File(dataRoot, NORMAL_VERSION_FILE_NAME),
whenVersionChanged = CacheVersion.Action.REBUILD_CHUNK,
whenTurnedOn = CacheVersion.Action.REBUILD_CHUNK,
whenTurnedOff = CacheVersion.Action.CLEAN_NORMAL_CACHES,
isEnabled = { enabled ?: IncrementalCompilation.isEnabled() })
fun dataContainerCacheVersion(dataRoot: File, enabled: Boolean? = null): CacheVersion =
CacheVersion(ownVersion = DATA_CONTAINER_VERSION,
versionFile = File(dataRoot, DATA_CONTAINER_VERSION_FILE_NAME),
whenVersionChanged = CacheVersion.Action.REBUILD_ALL_KOTLIN,
whenTurnedOn = CacheVersion.Action.REBUILD_ALL_KOTLIN,
whenTurnedOff = CacheVersion.Action.CLEAN_DATA_CONTAINER,
isEnabled = { enabled ?: IncrementalCompilation.isEnabled() })

View File

@@ -1,6 +1,6 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental

View File

@@ -1,6 +1,17 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental
@@ -10,10 +21,14 @@ import java.io.File
interface ICReporter {
fun report(message: () -> String)
fun reportVerbose(message: () -> String)
fun reportCompileIteration(incremental: Boolean, sourceFiles: Collection<File>, exitCode: ExitCode)
fun reportMarkDirtyClass(affectedFiles: Iterable<File>, classFqName: String)
fun reportMarkDirtyMember(affectedFiles: Iterable<File>, scope: String, name: String)
fun reportMarkDirty(affectedFiles: Iterable<File>, reason: String)
}
// used in Gradle plugin
@Suppress("unused")
fun reportCompileIteration(sourceFiles: Collection<File>, exitCode: ExitCode) {}
fun pathsAsString(files: Iterable<File>): String =
files.joinToString { it.canonicalPath }
fun pathsAsString(vararg files: File): String =
pathsAsString(files.toList())
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental
import java.io.File
abstract class ICReporterBase(private val pathsBase: File? = null) : ICReporter {
override fun reportMarkDirtyClass(affectedFiles: Iterable<File>, classFqName: String) {
reportMarkDirty(affectedFiles, "dirty class $classFqName")
}
override fun reportMarkDirtyMember(affectedFiles: Iterable<File>, scope: String, name: String) {
reportMarkDirty(affectedFiles, "dirty member $scope#$name")
}
override fun reportMarkDirty(affectedFiles: Iterable<File>, reason: String) {
affectedFiles.forEach { file ->
reportVerbose { "${pathsAsString(file)} is marked dirty: $reason" }
}
}
protected fun relativizeIfPossible(files: Iterable<File>): List<File> =
files.map { it.relativeOrCanonical() }
protected fun pathsAsString(files: Iterable<File>): String =
relativizeIfPossible(files).map { it.path }.sorted().joinToString()
protected fun pathsAsString(vararg files: File): String =
pathsAsString(files.toList())
protected fun File.relativeOrCanonical(): File =
pathsBase?.let { relativeToOrNull(it) } ?: canonicalFile
}

View File

@@ -18,9 +18,11 @@ package org.jetbrains.kotlin.incremental
import com.intellij.util.io.DataExternalizer
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
import org.jetbrains.kotlin.incremental.js.IrTranslationResultValue
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
import org.jetbrains.kotlin.incremental.storage.*
import org.jetbrains.kotlin.incremental.storage.BasicStringMap
import org.jetbrains.kotlin.incremental.storage.DirtyClassesFqNameMap
import org.jetbrains.kotlin.incremental.storage.SourceToFqNameMap
import org.jetbrains.kotlin.incremental.storage.StringToLongMapExternalizer
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
@@ -28,37 +30,25 @@ import org.jetbrains.kotlin.metadata.js.JsProtoBuf
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.parentOrNull
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
import java.io.DataInput
import java.io.DataOutput
import java.io.File
open class IncrementalJsCache(
cachesDir: File,
pathConverter: FileToPathConverter,
serializerProtocol: SerializerExtensionProtocol
) : AbstractIncrementalCache<FqName>(cachesDir, pathConverter) {
open class IncrementalJsCache(cachesDir: File) : AbstractIncrementalCache<FqName>(cachesDir) {
companion object {
private const val TRANSLATION_RESULT_MAP = "translation-result"
private const val IR_TRANSLATION_RESULT_MAP = "ir-translation-result"
private const val INLINE_FUNCTIONS = "inline-functions"
private const val HEADER_FILE_NAME = "header.meta"
private const val PACKAGE_META_FILE = "packages-meta"
private val TRANSLATION_RESULT_MAP = "translation-result"
private val INLINE_FUNCTIONS = "inline-functions"
private val HEADER_FILE_NAME = "header.meta"
fun hasHeaderFile(cachesDir: File) = File(cachesDir, HEADER_FILE_NAME).exists()
}
private val protoData = ProtoDataProvider(serializerProtocol)
override val sourceToClassesMap = registerMap(SourceToFqNameMap(SOURCE_TO_CLASSES.storageFile, pathConverter))
override val sourceToClassesMap = registerMap(SourceToFqNameMap(SOURCE_TO_CLASSES.storageFile))
override val dirtyOutputClassesMap = registerMap(DirtyClassesFqNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile, pathConverter, protoData))
private val irTranslationResults = registerMap(IrTranslationResultMap(IR_TRANSLATION_RESULT_MAP.storageFile, pathConverter))
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile, pathConverter))
private val packageMetadata = registerMap(PackageMetadataMap(PACKAGE_META_FILE.storageFile))
private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile))
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
private val dirtySources = hashSetOf<File>()
@@ -73,36 +63,19 @@ open class IncrementalJsCache(
}
override fun markDirty(removedAndCompiledSources: Collection<File>) {
removedAndCompiledSources.forEach { sourceFile ->
// The common prefix of all FQN parents has to be the file package
sourceToClassesMap[sourceFile].map { it.parentOrNull()?.asString() ?: "" }.minBy { it.length }?.let {
packageMetadata.remove(it)
}
}
super.markDirty(removedAndCompiledSources)
dirtySources.addAll(removedAndCompiledSources)
}
fun compare(translatedFiles: Map<File, TranslationResultValue>, changesCollector: ChangesCollector) {
for ((srcFile, data) in translatedFiles) {
val oldProtoMap = translationResults[srcFile]?.metadata?.let { protoData(srcFile, it) } ?: emptyMap()
val newProtoMap = protoData(srcFile, data.metadata)
for (classId in oldProtoMap.keys + newProtoMap.keys) {
changesCollector.collectProtoChanges(oldProtoMap[classId], newProtoMap[classId])
}
}
}
fun compareAndUpdate(incrementalResults: IncrementalResultsConsumerImpl, changesCollector: ChangesCollector) {
val translatedFiles = incrementalResults.packageParts
for ((srcFile, data) in translatedFiles) {
dirtySources.remove(srcFile)
val (binaryMetadata, binaryAst, inlineData) = data
val (binaryMetadata, binaryAst) = data
val oldProtoMap = translationResults[srcFile]?.metadata?.let { protoData(srcFile, it) } ?: emptyMap()
val newProtoMap = protoData(srcFile, binaryMetadata)
val oldProtoMap = translationResults[srcFile]?.metadata?.let { getProtoData(srcFile, it) } ?: emptyMap()
val newProtoMap = getProtoData(srcFile, binaryMetadata)
for ((classId, protoData) in newProtoMap) {
registerOutputForFile(srcFile, classId.asSingleFqName())
@@ -116,21 +89,12 @@ open class IncrementalJsCache(
changesCollector.collectProtoChanges(oldProtoMap[classId], newProtoMap[classId])
}
translationResults.put(srcFile, binaryMetadata, binaryAst, inlineData)
translationResults.put(srcFile, binaryMetadata, binaryAst)
}
for ((srcFile, inlineDeclarations) in incrementalResults.inlineFunctions) {
inlineFunctions.process(srcFile, inlineDeclarations, changesCollector)
}
for ((packageName, metadata) in incrementalResults.packageMetadata) {
packageMetadata.put(packageName, metadata)
}
for ((srcFile, irData) in incrementalResults.irFileData) {
val (fileData, types, signatures, strings, declarations, bodies, fqn) = irData
irTranslationResults.put(srcFile, fileData, types, signatures, strings, declarations, bodies, fqn)
}
}
private fun registerOutputForFile(srcFile: File, name: FqName) {
@@ -141,7 +105,6 @@ open class IncrementalJsCache(
override fun clearCacheForRemovedClasses(changesCollector: ChangesCollector) {
dirtySources.forEach {
translationResults.remove(it, changesCollector)
irTranslationResults.remove(it)
inlineFunctions.remove(it)
}
removeAllFromClassStorage(dirtyOutputClassesMap.getDirtyOutputClasses(), changesCollector)
@@ -150,30 +113,14 @@ open class IncrementalJsCache(
}
fun nonDirtyPackageParts(): Map<File, TranslationResultValue> =
hashMapOf<File, TranslationResultValue>().apply {
for (file in translationResults.keys()) {
if (file !in dirtySources) {
put(file, translationResults[file]!!)
hashMapOf<File, TranslationResultValue>().apply {
for (path in translationResults.keys()) {
val file = File(path)
if (file !in dirtySources) {
put(file, translationResults[path]!!)
}
}
}
}
fun packageMetadata(): Map<String, ByteArray> = hashMapOf<String, ByteArray>().apply {
for (fqNameString in packageMetadata.keys()) {
put(fqNameString, packageMetadata[fqNameString]!!)
}
}
fun nonDirtyIrParts(): Map<File, IrTranslationResultValue> =
hashMapOf<File, IrTranslationResultValue>().apply {
for (file in irTranslationResults.keys()) {
if (file !in dirtySources) {
put(file, irTranslationResults[file]!!)
}
}
}
}
private object TranslationResultValueExternalizer : DataExternalizer<TranslationResultValue> {
@@ -183,9 +130,6 @@ private object TranslationResultValueExternalizer : DataExternalizer<Translation
output.writeInt(value.binaryAst.size)
output.write(value.binaryAst)
output.writeInt(value.inlineData.size)
output.write(value.inlineData)
}
override fun read(input: DataInput): TranslationResultValue {
@@ -197,145 +141,39 @@ private object TranslationResultValueExternalizer : DataExternalizer<Translation
val binaryAst = ByteArray(binaryAstSize)
input.readFully(binaryAst)
val inlineDataSize = input.readInt()
val inlineData = ByteArray(inlineDataSize)
input.readFully(inlineData)
return TranslationResultValue(metadata = metadata, binaryAst = binaryAst, inlineData = inlineData)
return TranslationResultValue(metadata = metadata, binaryAst = binaryAst)
}
}
private class TranslationResultMap(
storageFile: File,
private val pathConverter: FileToPathConverter,
private val protoData: ProtoDataProvider
) :
BasicStringMap<TranslationResultValue>(storageFile, TranslationResultValueExternalizer) {
private class TranslationResultMap(storageFile: File) : BasicStringMap<TranslationResultValue>(storageFile, TranslationResultValueExternalizer) {
override fun dumpValue(value: TranslationResultValue): String =
"Metadata: ${value.metadata.md5()}, Binary AST: ${value.binaryAst.md5()}, InlineData: ${value.inlineData.md5()}"
"Metadata: ${value.metadata.md5()}, Binary AST: ${value.binaryAst.md5()}"
fun put(sourceFile: File, newMetadata: ByteArray, newBinaryAst: ByteArray, newInlineData: ByteArray) {
storage[pathConverter.toPath(sourceFile)] =
TranslationResultValue(metadata = newMetadata, binaryAst = newBinaryAst, inlineData = newInlineData)
fun put(file: File, newMetadata: ByteArray, newBinaryAst: ByteArray) {
storage[file.canonicalPath] = TranslationResultValue(metadata = newMetadata, binaryAst = newBinaryAst)
}
operator fun get(sourceFile: File): TranslationResultValue? =
storage[pathConverter.toPath(sourceFile)]
operator fun get(file: File): TranslationResultValue? =
storage[file.canonicalPath]
fun keys(): Collection<File> =
storage.keys.map { pathConverter.toFile(it) }
operator fun get(key: String): TranslationResultValue? =
storage[key]
fun remove(sourceFile: File, changesCollector: ChangesCollector) {
val path = pathConverter.toPath(sourceFile)
val protoBytes = storage[path]!!.metadata
val protoMap = protoData(sourceFile, protoBytes)
fun keys(): Collection<String> =
storage.keys
fun remove(file: File, changesCollector: ChangesCollector) {
val protoBytes = storage[file.canonicalPath]!!.metadata
val protoMap = getProtoData(file, protoBytes)
for ((_, protoData) in protoMap) {
changesCollector.collectProtoChanges(oldData = protoData, newData = null)
}
storage.remove(path)
storage.remove(file.canonicalPath)
}
}
private object IrTranslationResultValueExternalizer : DataExternalizer<IrTranslationResultValue> {
override fun save(output: DataOutput, value: IrTranslationResultValue) {
output.writeArray(value.fileData)
output.writeArray(value.types)
output.writeArray(value.signatures)
output.writeArray(value.strings)
output.writeArray(value.declarations)
output.writeArray(value.bodies)
output.writeArray(value.fqn)
}
private fun DataOutput.writeArray(array: ByteArray) {
writeInt(array.size)
write(array)
}
private fun DataInput.readArray(): ByteArray {
val dataSize = readInt()
val filedata = ByteArray(dataSize)
readFully(filedata)
return filedata
}
override fun read(input: DataInput): IrTranslationResultValue {
val fileData = input.readArray()
val types = input.readArray()
val signatures = input.readArray()
val strings = input.readArray()
val declarations = input.readArray()
val bodies = input.readArray()
val fqn = input.readArray()
return IrTranslationResultValue(fileData, types, signatures, strings, declarations, bodies, fqn)
}
}
private class IrTranslationResultMap(
storageFile: File,
private val pathConverter: FileToPathConverter
) :
BasicStringMap<IrTranslationResultValue>(storageFile, IrTranslationResultValueExternalizer) {
override fun dumpValue(value: IrTranslationResultValue): String =
"Filedata: ${value.fileData.md5()}, " +
"Types: ${value.types.md5()}, " +
"Signatures: ${value.signatures.md5()}, " +
"Strings: ${value.strings.md5()}, " +
"Declarations: ${value.declarations.md5()}, " +
"Bodies: ${value.bodies.md5()}"
fun put(
sourceFile: File,
newFiledata: ByteArray,
newTypes: ByteArray,
newSignatures: ByteArray,
newStrings: ByteArray,
newDeclarations: ByteArray,
newBodies: ByteArray,
fqn: ByteArray
) {
storage[pathConverter.toPath(sourceFile)] =
IrTranslationResultValue(newFiledata, newTypes, newSignatures, newStrings, newDeclarations, newBodies, fqn)
}
operator fun get(sourceFile: File): IrTranslationResultValue? =
storage[pathConverter.toPath(sourceFile)]
fun keys(): Collection<File> =
storage.keys.map { pathConverter.toFile(it) }
fun remove(sourceFile: File) {
val path = pathConverter.toPath(sourceFile)
storage.remove(path)
}
}
private class ProtoDataProvider(private val serializerProtocol: SerializerExtensionProtocol) {
operator fun invoke(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData> {
val classes = hashMapOf<ClassId, ProtoData>()
val proto = ProtoBuf.PackageFragment.parseFrom(metadata, serializerProtocol.extensionRegistry)
val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames)
proto.class_List.forEach {
val classId = nameResolver.getClassId(it.fqName)
classes[classId] = ClassProtoData(it, nameResolver)
}
proto.`package`.apply {
val packageNameId = getExtensionOrNull(serializerProtocol.packageFqName)
val packageFqName = packageNameId?.let { FqName(nameResolver.getPackageFqName(it)) } ?: FqName.ROOT
val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt"))
classes[packagePartClassId] = PackagePartProtoData(this, nameResolver, packageFqName)
}
return classes
}
}
// TODO: remove this method once AbstractJsProtoComparisonTest is fixed
fun getProtoData(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData> {
fun getProtoData(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData> {
val classes = hashMapOf<ClassId, ProtoData>()
val proto = ProtoBuf.PackageFragment.parseFrom(metadata, JsSerializerProtocol.extensionRegistry)
val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames)
@@ -354,17 +192,15 @@ fun getProtoData(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData>
return classes
}
private class InlineFunctionsMap(
storageFile: File,
private val pathConverter: FileToPathConverter
) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
private class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
fun process(srcFile: File, newMap: Map<String, Long>, changesCollector: ChangesCollector) {
val key = pathConverter.toPath(srcFile)
val key = srcFile.canonicalPath
val oldMap = storage[key] ?: emptyMap()
if (newMap.isNotEmpty()) {
storage[key] = newMap
} else {
}
else {
storage.remove(key)
}
@@ -376,40 +212,9 @@ private class InlineFunctionsMap(
}
fun remove(sourceFile: File) {
storage.remove(pathConverter.toPath(sourceFile))
storage.remove(sourceFile.canonicalPath)
}
override fun dumpValue(value: Map<String, Long>): String =
value.dumpMap { java.lang.Long.toHexString(it) }
}
private object ByteArrayExternalizer : DataExternalizer<ByteArray> {
override fun save(output: DataOutput, value: ByteArray) {
output.writeInt(value.size)
output.write(value)
}
override fun read(input: DataInput): ByteArray {
val size = input.readInt()
val array = ByteArray(size)
input.readFully(array)
return array
}
}
private class PackageMetadataMap(storageFile: File) : BasicStringMap<ByteArray>(storageFile, ByteArrayExternalizer) {
fun put(packageName: String, newMetadata: ByteArray) {
storage[packageName] = newMetadata
}
fun remove(packageName: String) {
storage.remove(packageName)
}
fun keys() = storage.keys
operator fun get(packageName: String) = storage[packageName]
override fun dumpValue(value: ByteArray): String = "Package metadata: ${value.md5()}"
value.dumpMap { java.lang.Long.toHexString(it) }
}

View File

@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.*
import java.io.File
@@ -43,13 +42,9 @@ import java.util.*
val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
open class IncrementalJvmCache(
private val targetDataRoot: File,
targetOutputDir: File?,
pathConverter: FileToPathConverter
) : AbstractIncrementalCache<JvmClassName>(
workingDir = File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME),
pathConverter = pathConverter
), IncrementalCache {
private val targetDataRoot: File,
targetOutputDir: File?
) : AbstractIncrementalCache<JvmClassName>(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
companion object {
private val PROTO_MAP = "proto"
private val CONSTANTS_MAP = "constants"
@@ -63,7 +58,7 @@ open class IncrementalJvmCache(
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
}
override val sourceToClassesMap = registerMap(SourceToJvmNameMap(SOURCE_TO_CLASSES.storageFile, pathConverter))
override val sourceToClassesMap = registerMap(SourceToJvmNameMap(SOURCE_TO_CLASSES.storageFile))
override val dirtyOutputClassesMap = registerMap(DirtyClassesJvmNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
@@ -73,8 +68,7 @@ open class IncrementalJvmCache(
private val partToMultifileFacade = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
// todo: try to use internal names only?
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile, pathConverter))
// gradle only
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile))
private val javaSourcesProtoMap = registerMap(JavaSourcesProtoMap(JAVA_SOURCES_PROTO_MAP.storageFile))
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory" } }
@@ -86,16 +80,16 @@ open class IncrementalJvmCache(
// used in gradle
@Suppress("unused")
fun classesBySources(sources: Iterable<File>): Iterable<JvmClassName> =
sources.flatMap { sourceToClassesMap[it] }
sources.flatMap { sourceToClassesMap[it] }
fun sourceInCache(file: File): Boolean =
sourceToClassesMap.contains(file)
fun sourcesByInternalName(internalName: String): Collection<File> =
internalNameToSource[internalName]
internalNameToSource[internalName]
fun isMultifileFacade(className: JvmClassName): Boolean =
className in multifileFacadeToParts
className in multifileFacadeToParts
override fun getClassFilePath(internalClassName: String): String {
return toSystemIndependentName(File(outputDir, "$internalClassName.class").canonicalPath)
@@ -134,7 +128,7 @@ open class IncrementalJvmCache(
}
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
val partNames = kotlinClass.classHeader.data?.toList()
?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
multifileFacadeToParts[className] = partNames
// When a class is replaced with a facade with the same name,
// the class' proto wouldn't ever be deleted,
@@ -182,15 +176,15 @@ open class IncrementalJvmCache(
}
fun getObsoleteJavaClasses(): Collection<ClassId> =
dirtyOutputClassesMap.getDirtyOutputClasses()
.mapNotNull {
javaSourcesProtoMap[it]?.classId
}
dirtyOutputClassesMap.getDirtyOutputClasses()
.mapNotNull {
javaSourcesProtoMap[it]?.classId
}
fun isJavaClassToTrack(classId: ClassId): Boolean {
val jvmClassName = JvmClassName.byClassId(classId)
return dirtyOutputClassesMap.isDirty(jvmClassName) ||
jvmClassName !in javaSourcesProtoMap
jvmClassName !in javaSourcesProtoMap
}
fun isJavaClassAlreadyInCache(classId: ClassId): Boolean {
@@ -215,7 +209,8 @@ open class IncrementalJvmCache(
if (notRemovedParts.isEmpty()) {
multifileFacadeToParts.remove(facade)
} else {
}
else {
multifileFacadeToParts[facade] = notRemovedParts
}
}
@@ -267,6 +262,11 @@ open class IncrementalJvmCache(
return protoMap[JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME)]?.bytes
}
override fun clean() {
super.clean()
normalCacheVersion(targetDataRoot).clean()
}
private inner class ProtoMap(storageFile: File) : BasicStringMap<ProtoMapValue>(storageFile, ProtoMapValueExternalizer) {
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
@@ -289,11 +289,9 @@ open class IncrementalJvmCache(
val key = kotlinClass.className.internalName
val oldData = storage[key]
val newData = ProtoMapValue(
header.kind != KotlinClassHeader.Kind.CLASS,
BitEncoding.decodeBytes(header.data!!),
header.strings!!
)
val newData = ProtoMapValue(header.kind != KotlinClassHeader.Kind.CLASS,
BitEncoding.decodeBytes(header.data!!),
header.strings!!)
storage[key] = newData
val packageFqName = kotlinClass.className.packageFqName
@@ -301,10 +299,10 @@ open class IncrementalJvmCache(
}
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
className.internalName in storage
operator fun get(className: JvmClassName): ProtoMapValue? =
storage[className.internalName]
storage[className.internalName]
fun remove(className: JvmClassName, changesCollector: ChangesCollector) {
val key = className.internalName
@@ -320,16 +318,15 @@ open class IncrementalJvmCache(
}
}
private inner class JavaSourcesProtoMap(storageFile: File) :
BasicStringMap<SerializedJavaClass>(storageFile, JavaClassProtoMapValueExternalizer) {
private inner class JavaSourcesProtoMap(storageFile: File) : BasicStringMap<SerializedJavaClass>(storageFile, JavaClassProtoMapValueExternalizer) {
fun process(jvmClassName: JvmClassName, newData: SerializedJavaClass, changesCollector: ChangesCollector) {
val key = jvmClassName.internalName
val oldData = storage[key]
storage[key] = newData
changesCollector.collectProtoChanges(
oldData?.toProtoData(), newData.toProtoData(),
collectAllMembersForNewClass = true
oldData?.toProtoData(), newData.toProtoData(),
collectAllMembersForNewClass = true
)
}
@@ -342,13 +339,13 @@ open class IncrementalJvmCache(
}
operator fun get(className: JvmClassName): SerializedJavaClass? =
storage[className.internalName]
storage[className.internalName]
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
className.internalName in storage
override fun dumpValue(value: SerializedJavaClass): String =
java.lang.Long.toHexString(value.proto.toByteArray().md5())
java.lang.Long.toHexString(value.proto.toByteArray().md5())
}
// todo: reuse code with InlineFunctionsMap?
@@ -356,7 +353,7 @@ open class IncrementalJvmCache(
private fun getConstantsMap(bytes: ByteArray): Map<String, Any> {
val result = HashMap<String, Any>()
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.ASM5) {
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
val staticFinal = Opcodes.ACC_STATIC or Opcodes.ACC_FINAL or Opcodes.ACC_PRIVATE
if (value != null && access and staticFinal == Opcodes.ACC_STATIC or Opcodes.ACC_FINAL) {
@@ -370,7 +367,7 @@ open class IncrementalJvmCache(
}
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
className.internalName in storage
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val key = kotlinClass.className.internalName
@@ -379,7 +376,8 @@ open class IncrementalJvmCache(
val newMap = getConstantsMap(kotlinClass.fileContents)
if (newMap.isNotEmpty()) {
storage[key] = newMap
} else {
}
else {
storage.remove(key)
}
@@ -393,7 +391,7 @@ open class IncrementalJvmCache(
}
override fun dumpValue(value: Map<String, Any>): String =
value.dumpMap(Any::toString)
value.dumpMap(Any::toString)
}
private inner class PackagePartMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
@@ -406,22 +404,21 @@ open class IncrementalJvmCache(
}
fun isPackagePart(className: JvmClassName): Boolean =
className.internalName in storage
className.internalName in storage
override fun dumpValue(value: Boolean) = ""
}
private inner class MultifileClassFacadeMap(storageFile: File) :
BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
operator fun set(className: JvmClassName, partNames: Collection<String>) {
storage[className.internalName] = partNames
}
operator fun get(className: JvmClassName): Collection<String>? =
storage[className.internalName]
storage[className.internalName]
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
className.internalName in storage
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
@@ -430,14 +427,13 @@ open class IncrementalJvmCache(
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
}
private inner class MultifileClassPartMap(storageFile: File) :
BasicStringMap<String>(storageFile, EnumeratorStringDescriptor.INSTANCE) {
private inner class MultifileClassPartMap(storageFile: File) : BasicStringMap<String>(storageFile, EnumeratorStringDescriptor.INSTANCE) {
fun set(partName: String, facadeName: String) {
storage[partName] = facadeName
}
fun get(partName: JvmClassName): String? =
storage[partName.internalName]
storage[partName.internalName]
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
@@ -446,23 +442,20 @@ open class IncrementalJvmCache(
override fun dumpValue(value: String): String = value
}
inner class InternalNameToSourcesMap(
storageFile: File,
private val pathConverter: FileToPathConverter
) : BasicStringMap<Collection<String>>(storageFile, EnumeratorStringDescriptor(), PathCollectionExternalizer) {
operator fun set(internalName: String, sourceFiles: Collection<File>) {
storage[internalName] = pathConverter.toPaths(sourceFiles)
inner class InternalNameToSourcesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, EnumeratorStringDescriptor(), PathCollectionExternalizer) {
operator fun set(internalName: String, sourceFiles: Iterable<File>) {
storage[internalName] = sourceFiles.map { it.canonicalPath }
}
operator fun get(internalName: String): Collection<File> =
pathConverter.toFiles(storage[internalName] ?: emptyList())
(storage[internalName] ?: emptyList()).map(::File)
fun remove(internalName: String) {
storage.remove(internalName)
}
override fun dumpValue(value: Collection<String>): String =
value.dumpCollection()
value.dumpCollection()
}
private fun addToClassStorage(kotlinClass: LocalFileKotlinClass, srcFile: File) {
@@ -470,45 +463,23 @@ open class IncrementalJvmCache(
addToClassStorage(proto, nameResolver, srcFile)
}
private inner class InlineFunctionsMap(storageFile: File) :
BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
private inner class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray): Map<String, Long> {
val inlineFunctions = inlineFunctionsJvmNames(header)
if (inlineFunctions.isEmpty()) return emptyMap()
val result = HashMap<String, Long>()
var dummyVersion: Int = -1
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visit(
version: Int,
access: Int,
name: String?,
signature: String?,
superName: String?,
interfaces: Array<out String>?
) {
super.visit(version, access, name, signature, superName, interfaces)
dummyVersion = version
}
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.ASM5) {
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
val dummyClassWriter = ClassWriter(Opcodes.ASM5)
override fun visitMethod(
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<out String>?
): MethodVisitor? {
val dummyClassWriter = ClassWriter(0)
dummyClassWriter.visit(dummyVersion, 0, "dummy", null, AsmTypes.OBJECT_TYPE.internalName, null)
return object : MethodVisitor(Opcodes.API_VERSION, dummyClassWriter.visitMethod(0, name, desc, null, exceptions)) {
return object : MethodVisitor(Opcodes.ASM5, dummyClassWriter.visitMethod(0, name, desc, null, exceptions)) {
override fun visitEnd() {
val jvmName = name + desc
if (jvmName !in inlineFunctions) return
val dummyBytes = dummyClassWriter.toByteArray()!!
val hash = dummyBytes.md5()
result[jvmName] = hash
}
@@ -527,35 +498,30 @@ open class IncrementalJvmCache(
val newMap = getInlineFunctionsMap(kotlinClass.classHeader, kotlinClass.fileContents)
if (newMap.isNotEmpty()) {
storage[key] = newMap
} else {
}
else {
storage.remove(key)
}
for (fn in oldMap.keys + newMap.keys) {
changesCollector.collectMemberIfValueWasChanged(
kotlinClass.scopeFqName(),
functionNameBySignature(fn),
oldMap[fn],
newMap[fn]
)
changesCollector.collectMemberIfValueWasChanged(kotlinClass.scopeFqName(), functionNameBySignature(fn), oldMap[fn], newMap[fn])
}
}
// TODO get name in better way instead of using substringBefore
private fun functionNameBySignature(signature: String): String =
signature.substringBefore("(")
signature.substringBefore("(")
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
}
override fun dumpValue(value: Map<String, Long>): String =
value.dumpMap { java.lang.Long.toHexString(it) }
value.dumpMap { java.lang.Long.toHexString(it) }
}
}
private object PathCollectionExternalizer :
CollectionExternalizer<String>(PathStringDescriptor, { THashSet(FileUtil.PATH_HASHING_STRATEGY) })
private object PathCollectionExternalizer : CollectionExternalizer<String>(PathStringDescriptor, { THashSet(FileUtil.PATH_HASHING_STRATEGY) })
sealed class ChangeInfo(val fqName: FqName) {
open class MembersChanged(fqName: FqName, val names: Collection<String>) : ChangeInfo(fqName) {
@@ -575,10 +541,10 @@ sealed class ChangeInfo(val fqName: FqName) {
}
private fun LocalFileKotlinClass.scopeFqName() =
when (classHeader.kind) {
KotlinClassHeader.Kind.CLASS -> className.fqNameForClassNameWithoutDollars
else -> className.packageFqName
}
when (classHeader.kind) {
KotlinClassHeader.Kind.CLASS -> className.fqNameForClassNameWithoutDollars
else -> className.packageFqName
}
fun ByteArray.md5(): Long {
val d = MessageDigest.getInstance("MD5").digest(this)!!
@@ -590,24 +556,23 @@ fun ByteArray.md5(): Long {
or ((d[5].toLong() and 0xFFL) shl 40)
or ((d[6].toLong() and 0xFFL) shl 48)
or ((d[7].toLong() and 0xFFL) shl 56)
)
)
}
@TestOnly
fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V) -> String): String =
buildString {
append("{")
for (key in keys.sorted()) {
if (length != 1) {
append(", ")
fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): String =
buildString {
append("{")
for (key in keys.sorted()) {
if (length != 1) {
append(", ")
}
val value = get(key)?.let(dumpValue) ?: "null"
append("$key -> $value")
}
val value = get(key)?.let(dumpValue) ?: "null"
append("$key -> $value")
append("}")
}
append("}")
}
@TestOnly
fun <T : Comparable<T>> Collection<T>.dumpCollection(): String =
"[${sorted().joinToString(", ", transform = Any::toString)}]"
@TestOnly fun <T : Comparable<T>> Collection<T>.dumpCollection(): String =
"[${sorted().joinToString(", ", transform = Any::toString)}]"

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental
import java.io.File
import java.io.Serializable
data class IncrementalModuleEntry(
private val projectPath: String,
val name: String,
val buildDir: File,
val buildHistoryFile: File
) : Serializable {
companion object {
private const val serialVersionUID = 0L
}
}
class IncrementalModuleInfo(
val projectRoot: File,
val dirToModule: Map<File, IncrementalModuleEntry>,
val nameToModules: Map<String, Set<IncrementalModuleEntry>>,
val jarToClassListFile: Map<File, File>,
// only for js and mpp
val jarToModule: Map<File, IncrementalModuleEntry>
) : Serializable {
companion object {
private const val serialVersionUID = 0L
}
}

View File

@@ -16,52 +16,34 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.java.JavaClassProtoBuf
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
// It uses BuiltInSerializerProtocol for annotations serialization
class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
override val metadataVersion: BinaryVersion
get() = JvmMetadataVersion.INVALID_VERSION
override fun serializeClass(
descriptor: ClassDescriptor,
proto: ProtoBuf.Class.Builder,
versionRequirementTable: MutableVersionRequirementTable,
childSerializer: DescriptorSerializer
) {
super.serializeClass(descriptor, proto, versionRequirementTable, childSerializer)
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
super.serializeClass(descriptor, proto)
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
proto.setExtension(JavaClassProtoBuf.isPackagePrivateClass, true)
}
}
override fun serializeConstructor(descriptor: ConstructorDescriptor,
proto: ProtoBuf.Constructor.Builder,
childSerializer: DescriptorSerializer) {
super.serializeConstructor(descriptor, proto, childSerializer)
override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder) {
super.serializeConstructor(descriptor, proto)
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
proto.setExtension(JavaClassProtoBuf.isPackagePrivateConstructor, true)
}
}
override fun serializeFunction(
descriptor: FunctionDescriptor,
proto: ProtoBuf.Function.Builder,
versionRequirementTable: MutableVersionRequirementTable?,
childSerializer: DescriptorSerializer
) {
super.serializeFunction(descriptor, proto, versionRequirementTable, childSerializer)
override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) {
super.serializeFunction(descriptor, proto)
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
proto.setExtension(JavaClassProtoBuf.isPackagePrivateMethod, true)
}
@@ -71,13 +53,8 @@ class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSeri
}
}
override fun serializeProperty(
descriptor: PropertyDescriptor,
proto: ProtoBuf.Property.Builder,
versionRequirementTable: MutableVersionRequirementTable?,
childSerializer: DescriptorSerializer
) {
super.serializeProperty(descriptor, proto, versionRequirementTable, childSerializer)
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) {
super.serializeProperty(descriptor, proto)
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
proto.setExtension(JavaClassProtoBuf.isPackagePrivateField, true)
}

View File

@@ -1,6 +1,17 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental
@@ -85,7 +96,7 @@ fun JavaClassDescriptor.convertToProto(): SerializedJavaClassWithSource {
val extension = JavaClassesSerializerExtension()
val classProto = try {
DescriptorSerializer.create(this, extension, null).classProto(this).build()
DescriptorSerializer.create(this, extension).classProto(this).build()
} catch (e: Exception) {
throw IllegalStateException(
"Error during writing proto for descriptor: ${DescriptorRenderer.DEBUG_TEXT.render(this)}\n" +

View File

@@ -30,18 +30,15 @@ import java.io.IOException
import java.util.*
open class LookupStorage(
targetDataDir: File,
pathConverter: FileToPathConverter
) : BasicMapsOwner(targetDataDir) {
open class LookupStorage(targetDataDir: File) : BasicMapsOwner(targetDataDir) {
companion object {
private val DELETED_TO_SIZE_TRESHOLD = 0.5
private val MINIMUM_GARBAGE_COLLECTIBLE_SIZE = 10000
}
private val countersFile = "counters".storageFile
private val idToFile = registerMap(IdToFileMap("id-to-file".storageFile, pathConverter))
private val fileToId = registerMap(FileToIdMap("file-to-id".storageFile, pathConverter))
private val idToFile = registerMap(IdToFileMap("id-to-file".storageFile))
private val fileToId = registerMap(FileToIdMap("file-to-id".storageFile))
private val lookupMap = registerMap(LookupMap("lookups".storageFile))
@Volatile
@@ -75,13 +72,12 @@ open class LookupStorage(
}
@Synchronized
fun addAll(lookups: MultiMap<LookupSymbol, String>, allPaths: Set<String>) {
val pathToId = allPaths.sorted().keysToMap { addFileIfNeeded(File(it)) }
fun addAll(lookups: Set<Map.Entry<LookupSymbol, Collection<String>>>, allPaths: Set<String>) {
val pathToId = allPaths.keysToMap { addFileIfNeeded(File(it)) }
for (lookupSymbol in lookups.keySet().sorted()) {
for ((lookupSymbol, paths) in lookups) {
val key = LookupSymbolKey(lookupSymbol.name, lookupSymbol.scope)
val paths = lookups[lookupSymbol]!!
val fileIds = paths.mapTo(TreeSet()) { pathToId[it]!! }
val fileIds = paths.mapTo(HashSet<Int>()) { pathToId[it]!! }
fileIds.addAll(lookupMap[key] ?: emptySet())
lookupMap[key] = fileIds
}
@@ -156,7 +152,7 @@ open class LookupStorage(
size = 0
deletedCount = 0
for ((file, oldId) in oldFileToId.entries.sortedBy { it.key.path }) {
for ((file, oldId) in oldFileToId.entries) {
val newId = addFileIfNeeded(file)
oldIdToNewId[oldId] = newId
}
@@ -178,19 +174,11 @@ open class LookupStorage(
flush(false)
}
@TestOnly
fun dump(lookupSymbols: Set<LookupSymbol>): String {
@TestOnly fun dump(lookupSymbols: Set<LookupSymbol>, basePath: File? = null): String {
flush(false)
val sb = StringBuilder()
val p = Printer(sb)
p.println("====== File to id map")
p.println(fileToId.dump())
p.println("====== Id to file map")
p.println(idToFile.dump())
val lookupsStrings = lookupSymbols.groupBy { LookupSymbolKey(it.name, it.scope) }
for (lookup in lookupMap.keys.sorted()) {
@@ -198,11 +186,12 @@ open class LookupStorage(
val key = if (lookup in lookupsStrings) {
lookupsStrings[lookup]!!.map { "${it.scope}#${it.name}" }.sorted().joinToString(", ")
} else {
}
else {
lookup.toString()
}
val value = fileIds.map { it.toString() }.sorted().joinToString(", ")
val value = fileIds.map { idToFile[it]?.let { if (basePath == null) it.absolutePath else it.toRelativeString(basePath) } ?: it.toString() }.sorted().joinToString(", ")
p.println("$key -> $value")
}
@@ -228,11 +217,4 @@ class LookupTrackerImpl(private val delegate: LookupTracker) : LookupTracker {
}
}
data class LookupSymbol(val name: String, val scope: String) : Comparable<LookupSymbol> {
override fun compareTo(other: LookupSymbol): Int {
val scopeCompare = scope.compareTo(other.scope)
if (scopeCompare != 0) return scopeCompare
return name.compareTo(other.name)
}
}
data class LookupSymbol(val name: String, val scope: String)

View File

@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.incremental
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.GeneratedJvmClass
import org.jetbrains.kotlin.build.JvmSourceRoot
@@ -28,65 +30,46 @@ import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.resolve.sam.SAM_LOOKUP_NAME
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
import org.jetbrains.kotlin.synthetic.SAM_LOOKUP_NAME
import java.io.File
import java.util.*
import kotlin.collections.HashSet
import kotlin.collections.LinkedHashSet
const val DELETE_MODULE_FILE_PROPERTY = "kotlin.delete.module.file.after.build"
fun makeModuleFile(
name: String,
isTest: Boolean,
outputDir: File,
sourcesToCompile: Iterable<File>,
commonSources: Iterable<File>,
javaSourceRoots: Iterable<JvmSourceRoot>,
classpath: Iterable<File>,
friendDirs: Iterable<File>
name: String,
isTest: Boolean,
outputDir: File,
sourcesToCompile: Iterable<File>,
javaSourceRoots: Iterable<JvmSourceRoot>,
classpath: Iterable<File>,
friendDirs: Iterable<File>
): File {
val builder = KotlinModuleXmlBuilder()
builder.addModule(
name,
outputDir.absolutePath,
// important to transform file to absolute paths,
// otherwise compiler will use module file's parent as base path (a temporary file; see below)
// (see org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.getAbsolutePaths)
sourcesToCompile.map { it.absoluteFile },
javaSourceRoots,
classpath,
commonSources.map { it.absoluteFile },
null,
"java-production",
isTest,
// this excludes the output directories from the class path, to be removed for true incremental compilation
setOf(outputDir),
friendDirs
name,
outputDir.absolutePath,
// important to transform file to absolute paths,
// otherwise compiler will use module file's parent as base path (a temporary file; see below)
// (see org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.getAbsolutePaths)
sourcesToCompile.map { it.absoluteFile },
javaSourceRoots,
classpath,
null,
"java-production",
isTest,
// this excludes the output directories from the class path, to be removed for true incremental compilation
setOf(outputDir),
friendDirs
)
val scriptFile = File.createTempFile("kjps", sanitizeJavaIdentifier(name) + ".script.xml")
scriptFile.writeText(builder.asText().toString())
val scriptFile = File.createTempFile("kjps", StringUtil.sanitizeJavaIdentifier(name) + ".script.xml")
FileUtil.writeToFile(scriptFile, builder.asText().toString())
return scriptFile
}
private fun sanitizeJavaIdentifier(string: String) =
buildString {
for (char in string) {
if (char.isJavaIdentifierPart()) {
if (length == 0 && !char.isJavaIdentifierStart()) {
append('_')
}
append(char)
}
}
}
fun makeCompileServices(
incrementalCaches: Map<TargetId, IncrementalCache>,
lookupTracker: LookupTracker,
compilationCanceledStatus: CompilationCanceledStatus?
incrementalCaches: Map<TargetId, IncrementalCache>,
lookupTracker: LookupTracker,
compilationCanceledStatus: CompilationCanceledStatus?
): Services =
with(Services.Builder()) {
register(LookupTracker::class.java, lookupTracker)
@@ -106,14 +89,12 @@ fun updateIncrementalCache(
for (generatedFile in generatedFiles) {
when {
generatedFile is GeneratedJvmClass -> cache.saveFileToCache(generatedFile, changesCollector)
generatedFile.outputFile.isModuleMappingFile() -> cache.saveModuleMappingToCache(
generatedFile.sourceFiles,
generatedFile.outputFile
)
generatedFile.outputFile.isModuleMappingFile() -> cache.saveModuleMappingToCache(generatedFile.sourceFiles, generatedFile.outputFile)
}
}
javaChangesTracker?.javaClassesUpdates?.forEach { (source, serializedJavaClass) ->
javaChangesTracker?.javaClassesUpdates?.forEach {
(source, serializedJavaClass) ->
cache.saveJavaClassProto(source, serializedJavaClass, changesCollector)
}
@@ -121,20 +102,20 @@ fun updateIncrementalCache(
}
fun LookupStorage.update(
lookupTracker: LookupTracker,
filesToCompile: Iterable<File>,
removedFiles: Iterable<File>
lookupTracker: LookupTracker,
filesToCompile: Iterable<File>,
removedFiles: Iterable<File>
) {
if (lookupTracker !is LookupTrackerImpl) throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}")
removeLookupsFrom(filesToCompile.asSequence() + removedFiles.asSequence())
addAll(lookupTracker.lookups, lookupTracker.pathInterner.values)
addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values)
}
data class DirtyData(
val dirtyLookupSymbols: Collection<LookupSymbol> = emptyList(),
val dirtyClassesFqNames: Collection<FqName> = emptyList()
val dirtyLookupSymbols: Collection<LookupSymbol> = emptyList(),
val dirtyClassesFqNames: Collection<FqName> = emptyList()
)
fun ChangesCollector.getDirtyData(
@@ -145,11 +126,10 @@ fun ChangesCollector.getDirtyData(
val dirtyClassesFqNames = HashSet<FqName>()
for (change in changes()) {
reporter.reportVerbose { "Process $change" }
reporter.report { "Process $change" }
if (change is ChangeInfo.SignatureChanged) {
val fqNames = if (!change.areSubclassesAffected) listOf(change.fqName) else withSubtypes(change.fqName, caches)
dirtyClassesFqNames.addAll(fqNames)
for (classFqName in fqNames) {
assert(!classFqName.isRoot) { "$classFqName is root when processing $change" }
@@ -158,7 +138,8 @@ fun ChangesCollector.getDirtyData(
val name = classFqName.shortName().identifier
dirtyLookupSymbols.add(LookupSymbol(name, scope))
}
} else if (change is ChangeInfo.MembersChanged) {
}
else if (change is ChangeInfo.MembersChanged) {
val fqNames = withSubtypes(change.fqName, caches)
// need to recompile subtypes because changed member might break override
dirtyClassesFqNames.addAll(fqNames)
@@ -175,16 +156,16 @@ fun ChangesCollector.getDirtyData(
}
fun mapLookupSymbolsToFiles(
lookupStorage: LookupStorage,
lookupSymbols: Iterable<LookupSymbol>,
reporter: ICReporter,
excludes: Set<File> = emptySet()
lookupStorage: LookupStorage,
lookupSymbols: Iterable<LookupSymbol>,
reporter: ICReporter,
excludes: Set<File> = emptySet()
): Set<File> {
val dirtyFiles = HashSet<File>()
for (lookup in lookupSymbols) {
val affectedFiles = lookupStorage.get(lookup).map(::File).filter { it !in excludes }
reporter.reportMarkDirtyMember(affectedFiles, scope = lookup.scope, name = lookup.name)
reporter.report { "${lookup.scope}#${lookup.name} caused recompilation of: ${reporter.pathsAsString(affectedFiles)}" }
dirtyFiles.addAll(affectedFiles)
}
@@ -197,40 +178,35 @@ fun mapClassesFqNamesToFiles(
reporter: ICReporter,
excludes: Set<File> = emptySet()
): Set<File> {
val fqNameToAffectedFiles = HashMap<FqName, MutableSet<File>>()
val dirtyFiles = HashSet<File>()
for (cache in caches) {
for (classFqName in classesFqNames) {
val srcFile = cache.getSourceFileIfClass(classFqName)
for (dirtyClassFqName in classesFqNames) {
val srcFile = cache.getSourceFileIfClass(dirtyClassFqName)
if (srcFile == null || srcFile in excludes || srcFile.isJavaFile()) continue
fqNameToAffectedFiles.getOrPut(classFqName) { HashSet() }.add(srcFile)
reporter.report { ("Class $dirtyClassFqName caused recompilation of: ${reporter.pathsAsString(srcFile)}") }
dirtyFiles.add(srcFile)
}
}
for ((classFqName, affectedFiles) in fqNameToAffectedFiles) {
reporter.reportMarkDirtyClass(affectedFiles, classFqName.asString())
}
return fqNameToAffectedFiles.values.flattenTo(HashSet())
return dirtyFiles
}
fun withSubtypes(
typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon>
typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon>
): Set<FqName> {
val types = LinkedHashSet(listOf(typeFqName))
val types = LinkedList(listOf(typeFqName))
val subtypes = hashSetOf<FqName>()
while (types.isNotEmpty()) {
val iterator = types.iterator()
val unprocessedType = iterator.next()
iterator.remove()
val unprocessedType = types.pollFirst()
caches.asSequence()
.flatMap { it.getSubtypesOf(unprocessedType) }
.filter { it !in subtypes }
.forEach { types.add(it) }
.flatMap { it.getSubtypesOf(unprocessedType) }
.filter { it !in subtypes }
.forEach { types.addLast(it) }
subtypes.add(unprocessedType)
}

View File

@@ -21,8 +21,11 @@ import java.io.File
fun File.isJavaFile() =
extension.equals("java", ignoreCase = true)
fun File.isKotlinFile(sourceFilesExtensions: List<String>): Boolean =
!isJavaFile() && sourceFilesExtensions.any { it.equals(extension, ignoreCase = true) }
fun File.isKotlinFile(): Boolean =
extension.let {
"kt".equals(it, ignoreCase = true) ||
"kts".equals(it, ignoreCase = true)
}
fun File.isClassFile(): Boolean =
extension.equals("class", ignoreCase = true)

View File

@@ -1,12 +1,11 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.js
import org.jetbrains.kotlin.incremental.IncrementalJsCache
import org.jetbrains.kotlin.utils.JsMetadataVersion
import java.io.File
class IncrementalDataProviderFromCache(private val cache: IncrementalJsCache) : IncrementalDataProvider {
@@ -15,13 +14,4 @@ class IncrementalDataProviderFromCache(private val cache: IncrementalJsCache) :
override val compiledPackageParts: Map<File, TranslationResultValue>
get() = cache.nonDirtyPackageParts()
override val metadataVersion: IntArray
get() = JsMetadataVersion.INSTANCE.toArray() // TODO: store and load correct metadata version
override val packageMetadata: Map<String, ByteArray>
get() = cache.packageMetadata()
override val serializedIrFiles: Map<File, IrTranslationResultValue>
get() = cache.nonDirtyIrParts()
}
}

View File

@@ -30,9 +30,9 @@ import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
import java.util.*
data class Difference(
val isClassAffected: Boolean = false,
val areSubclassesAffected: Boolean = false,
val changedMembersNames: Set<String> = emptySet()
val isClassAffected: Boolean = false,
val areSubclassesAffected: Boolean = false,
val changedMembersNames: Set<String> = emptySet()
)
sealed class ProtoData
@@ -49,17 +49,14 @@ fun ProtoMapValue.toProtoData(packageFqName: FqName): ProtoData =
}
internal val MessageLite.isPrivate: Boolean
get() = Visibilities.isPrivate(
ProtoEnumFlags.visibility(
get() = Visibilities.isPrivate(ProtoEnumFlags.visibility(
when (this) {
is ProtoBuf.Constructor -> Flags.VISIBILITY.get(flags)
is ProtoBuf.Function -> Flags.VISIBILITY.get(flags)
is ProtoBuf.Property -> Flags.VISIBILITY.get(flags)
is ProtoBuf.TypeAlias -> Flags.VISIBILITY.get(flags)
else -> error("Unknown message: $this")
}
)
)
}))
private fun MessageLite.name(nameResolver: NameResolver): String {
return when (this) {
@@ -82,21 +79,9 @@ abstract class DifferenceCalculator {
val result = hashSetOf<String>()
val oldMap =
oldList.groupBy {
it.getHashCode(
compareObject::oldGetIndexOfString,
compareObject::oldGetIndexOfClassId,
compareObject::oldGetTypeById
)
}
oldList.groupBy { it.getHashCode({ compareObject.oldGetIndexOfString(it) }, { compareObject.oldGetIndexOfClassId(it) }) }
val newMap =
newList.groupBy {
it.getHashCode(
compareObject::newGetIndexOfString,
compareObject::newGetIndexOfClassId,
compareObject::newGetTypeById
)
}
newList.groupBy { it.getHashCode({ compareObject.newGetIndexOfString(it) }, { compareObject.newGetIndexOfClassId(it) }) }
val hashes = oldMap.keys + newMap.keys
for (hash in hashes) {
@@ -115,8 +100,8 @@ abstract class DifferenceCalculator {
}
private fun calcDifferenceForEqualHashes(
oldList: List<MessageLite>,
newList: List<MessageLite>
oldList: List<MessageLite>,
newList: List<MessageLite>
): Collection<String> {
val result = hashSetOf<String>()
val newSet = HashSet(newList)
@@ -125,7 +110,8 @@ abstract class DifferenceCalculator {
val newMember = newSet.firstOrNull { compareObject.checkEquals(oldMember, it) }
if (newMember != null) {
newSet.remove(newMember)
} else {
}
else {
result.add(oldMember.name(compareObject.oldNameResolver))
}
}
@@ -138,20 +124,20 @@ abstract class DifferenceCalculator {
}
protected fun calcDifferenceForNames(
oldList: List<Int>,
newList: List<Int>
oldList: List<Int>,
newList: List<Int>
): Collection<String> {
val oldNames = oldList.map { compareObject.oldNameResolver.getString(it) }.toSet()
val newNames = newList.map { compareObject.newNameResolver.getString(it) }.toSet()
return oldNames.union(newNames) - oldNames.intersect(newNames)
}
private fun MessageLite.getHashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeTable: (Int) -> ProtoBuf.Type): Int {
private fun MessageLite.getHashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
return when (this) {
is ProtoBuf.Constructor -> hashCode(stringIndexes, fqNameIndexes, typeTable)
is ProtoBuf.Function -> hashCode(stringIndexes, fqNameIndexes, typeTable)
is ProtoBuf.Property -> hashCode(stringIndexes, fqNameIndexes, typeTable)
is ProtoBuf.TypeAlias -> hashCode(stringIndexes, fqNameIndexes, typeTable)
is ProtoBuf.Constructor -> hashCode(stringIndexes, fqNameIndexes)
is ProtoBuf.Function -> hashCode(stringIndexes, fqNameIndexes)
is ProtoBuf.Property -> hashCode(stringIndexes, fqNameIndexes)
is ProtoBuf.TypeAlias -> hashCode(stringIndexes, fqNameIndexes)
else -> error("Unknown message: $this")
}
}
@@ -168,15 +154,10 @@ abstract class DifferenceCalculator {
}
class DifferenceCalculatorForClass(
private val oldData: ClassProtoData,
private val newData: ClassProtoData
private val oldData: ClassProtoData,
private val newData: ClassProtoData
) : DifferenceCalculator() {
override val compareObject = ProtoCompareGenerated(
oldNameResolver = oldData.nameResolver,
newNameResolver = newData.nameResolver,
oldTypeTable = oldData.proto.typeTableOrNull,
newTypeTable = newData.proto.typeTableOrNull
)
override val compareObject = ProtoCompareGenerated(oldData.nameResolver, newData.nameResolver)
override fun difference(): Difference {
val (oldProto, oldNameResolver) = oldData
@@ -239,8 +220,11 @@ class DifferenceCalculatorForClass(
// when (x as Base) { is Impl -> ... }
areSubclassesAffected = true
}
ProtoBufClassKind.VERSION_REQUIREMENT_LIST,
ProtoBufClassKind.VERSION_REQUIREMENT_TABLE -> {
ProtoBufClassKind.TYPE_TABLE -> {
// TODO
}
ProtoCompareGenerated.ProtoBufClassKind.VERSION_REQUIREMENT,
ProtoCompareGenerated.ProtoBufClassKind.VERSION_REQUIREMENT_TABLE -> {
// TODO
}
ProtoBufClassKind.FLAGS,
@@ -254,7 +238,7 @@ class DifferenceCalculatorForClass(
}
ProtoBufClassKind.JVM_EXT_CLASS_MODULE_NAME,
ProtoBufClassKind.JS_EXT_CLASS_CONTAINING_FILE_ID -> {
// TODO
// TODO
}
ProtoBufClassKind.JVM_EXT_CLASS_LOCAL_VARIABLE_LIST -> {
// Not affected, local variables are not accessible outside of a file
@@ -266,17 +250,9 @@ class DifferenceCalculatorForClass(
ProtoBufClassKind.BUILT_INS_EXT_CLASS_ANNOTATION_LIST -> {
isClassAffected = true
}
ProtoBufClassKind.JVM_EXT_ANONYMOUS_OBJECT_ORIGIN_NAME -> {
ProtoCompareGenerated.ProtoBufClassKind.JVM_EXT_ANONYMOUS_OBJECT_ORIGIN_NAME -> {
// Not affected, this extension is not used in the compiler
}
ProtoBufClassKind.KLIB_EXT_CLASS_ANNOTATION_LIST -> {
isClassAffected = true
areSubclassesAffected = true
}
ProtoBufClassKind.JVM_EXT_JVM_CLASS_FLAGS -> {
isClassAffected = true
areSubclassesAffected = true
}
}
}
@@ -285,15 +261,10 @@ class DifferenceCalculatorForClass(
}
class DifferenceCalculatorForPackageFacade(
private val oldData: PackagePartProtoData,
private val newData: PackagePartProtoData
private val oldData: PackagePartProtoData,
private val newData: PackagePartProtoData
) : DifferenceCalculator() {
override val compareObject = ProtoCompareGenerated(
oldNameResolver = oldData.nameResolver,
newNameResolver = newData.nameResolver,
oldTypeTable = oldData.proto.typeTableOrNull,
newTypeTable = newData.proto.typeTableOrNull
)
override val compareObject = ProtoCompareGenerated(oldData.nameResolver, newData.nameResolver)
override fun difference(): Difference {
val oldProto = oldData.proto
@@ -318,9 +289,10 @@ class DifferenceCalculatorForPackageFacade(
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Package::getPropertyList))
ProtoBufPackageKind.TYPE_ALIAS_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Package::getTypeAliasList))
ProtoBufPackageKind.TYPE_TABLE,
ProtoBufPackageKind.VERSION_REQUIREMENT_TABLE,
ProtoBufPackageKind.JVM_EXT_PACKAGE_MODULE_NAME,
ProtoBufPackageKind.JS_EXT_PACKAGE_FQ_NAME -> {
ProtoBufPackageKind.JS_EXT_PACKAGE_FQ_NAME-> {
// TODO
}
ProtoBufPackageKind.JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST -> {
@@ -329,9 +301,6 @@ class DifferenceCalculatorForPackageFacade(
ProtoBufPackageKind.BUILT_INS_EXT_PACKAGE_FQ_NAME -> {
// Not affected
}
ProtoBufPackageKind.KLIB_EXT_PACKAGE_FQ_NAME -> {
// Not affected
}
}
}
@@ -341,9 +310,3 @@ class DifferenceCalculatorForPackageFacade(
private val ProtoBuf.Class.isSealed: Boolean
get() = ProtoBuf.Modality.SEALED == Flags.MODALITY.get(flags)
val ProtoBuf.Class.typeTableOrNull: ProtoBuf.TypeTable?
get() = if (hasTypeTable()) typeTable else null
val ProtoBuf.Package.typeTableOrNull: ProtoBuf.TypeTable?
get() = if (hasTypeTable()) typeTable else null

View File

@@ -24,20 +24,11 @@ import org.jetbrains.kotlin.utils.Printer
import java.io.File
abstract class BasicMap<K : Comparable<K>, V>(
internal val storageFile: File,
storageFile: File,
keyDescriptor: KeyDescriptor<K>,
valueExternalizer: DataExternalizer<V>
) {
protected val storage: LazyStorage<K, V>
private val nonCachingStorage = System.getProperty("kotlin.jps.non.caching.storage")?.toBoolean() ?: false
init {
storage = if (nonCachingStorage) {
NonCachingLazyStorage(storageFile, keyDescriptor, valueExternalizer)
} else {
CachingLazyStorage(storageFile, keyDescriptor, valueExternalizer)
}
}
protected val storage = LazyStorage(storageFile, keyDescriptor, valueExternalizer)
fun clean() {
storage.clean()

View File

@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.annotations.TestOnly
import java.io.File
import java.io.IOException
open class BasicMapsOwner(val cachesDir: File) {
private val maps = arrayListOf<BasicMap<*, *>>()
@@ -36,35 +35,16 @@ open class BasicMapsOwner(val cachesDir: File) {
}
open fun clean() {
forEachMapSafe("clean", BasicMap<*, *>::clean)
maps.forEach { it.clean() }
}
open fun close() {
forEachMapSafe("close", BasicMap<*, *>::close)
maps.forEach { it.close() }
}
open fun flush(memoryCachesOnly: Boolean) {
forEachMapSafe("flush") { it.flush(memoryCachesOnly) }
maps.forEach { it.flush(memoryCachesOnly) }
}
private fun forEachMapSafe(actionName: String, action: (BasicMap<*, *>) -> Unit) {
val actionExceptions = LinkedHashMap<String, Exception>()
maps.forEach {
try {
action(it)
} catch (e: Exception) {
actionExceptions[it.storageFile.name] = e
}
}
if (actionExceptions.isNotEmpty()) {
val desc = "Could not $actionName incremental caches in $cachesDir: ${actionExceptions.keys.joinToString(", ")}"
val allIOExceptions = actionExceptions.all { it is IOException }
val ex = if (allIOExceptions) IOException(desc) else Exception(desc)
actionExceptions.forEach { (_, e) -> ex.addSuppressed(e) }
throw ex
}
}
@TestOnly
fun dump(): String = maps.joinToString("\n\n") { it.dump() }
@TestOnly fun dump(): String = maps.joinToString("\n\n") { it.dump() }
}

View File

@@ -1,107 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.KeyDescriptor
import com.intellij.util.io.PersistentHashMap
import java.io.File
/**
* It's lazy in a sense that PersistentHashMap is created only on write
*/
class CachingLazyStorage<K, V>(
private val storageFile: File,
private val keyDescriptor: KeyDescriptor<K>,
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: PersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
if (storage != null) return storage
if (storageFile.exists()) {
storage = createMap()
return storage
}
return null
}
@Synchronized
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
return storage!!
}
override val keys: Collection<K>
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
override operator fun contains(key: K): Boolean =
getStorageIfExists()?.containsMapping(key) ?: false
override operator fun get(key: K): V? =
getStorageIfExists()?.get(key)
override operator fun set(key: K, value: V) {
getStorageOrCreateNew().put(key, value)
}
override fun remove(key: K) {
getStorageIfExists()?.remove(key)
}
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendData(key, { valueExternalizer.save(it, value) })
}
@Synchronized
override fun clean() {
try {
storage?.close()
} finally {
PersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
}
@Synchronized
override fun flush(memoryCachesOnly: Boolean) {
val existingStorage = storage ?: return
if (memoryCachesOnly) {
if (existingStorage.isDirty) {
existingStorage.dropMemoryCaches()
}
} else {
existingStorage.force()
}
}
@Synchronized
override fun close() {
storage?.close()
}
private fun createMap(): PersistentHashMap<K, V> = PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
}

View File

@@ -26,7 +26,7 @@ internal open class ClassOneToManyMap(
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
fun add(key: FqName, value: FqName) {
storage.append(key.asString(), listOf(value.asString()))
storage.append(key.asString(), value.asString())
}
operator fun get(key: FqName): Collection<FqName> =

View File

@@ -1,30 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
import java.io.File
class ComplementarySourceFilesMap(
storageFile: File,
private val pathConverter: FileToPathConverter
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
operator fun set(sourceFile: File, complementaryFiles: Collection<File>) {
storage[pathConverter.toPath(sourceFile)] = pathConverter.toPaths(complementaryFiles)
}
operator fun get(sourceFile: File): Collection<File> {
val paths = storage[pathConverter.toPath(sourceFile)].orEmpty()
return pathConverter.toFiles(paths)
}
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
fun remove(file: File): Collection<File> =
get(file).also { storage.remove(pathConverter.toPath(file)) }
}

View File

@@ -18,27 +18,26 @@ package org.jetbrains.kotlin.incremental.storage
import java.io.File
internal class FileToIdMap(
file: File,
private val pathConverter: FileToPathConverter
) : BasicStringMap<Int>(file, IntExternalizer) {
internal class FileToIdMap(file: File) : BasicMap<File, Int>(file, FileKeyDescriptor, IntExternalizer) {
override fun dumpKey(key: File): String = key.toString()
override fun dumpValue(value: Int): String = value.toString()
operator fun get(file: File): Int? = storage[pathConverter.toPath(file)]
operator fun get(file: File): Int? = storage[file]
operator fun set(file: File, id: Int) {
storage[pathConverter.toPath(file)] = id
storage[file] = id
}
fun remove(file: File) {
storage.remove(pathConverter.toPath(file))
storage.remove(file)
}
fun toMap(): Map<File, Int> {
val result = HashMap<File, Int>()
for (key in storage.keys) {
val value = storage[key] ?: continue
result[pathConverter.toFile(key)] = value
result[key] = value
}
return result
}

View File

@@ -1,25 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.storage
import java.io.File
interface FileToPathConverter {
fun toPath(file: File): String
fun toFile(path: String): File
}
fun FileToPathConverter.toPaths(files: Collection<File>): List<String> =
files.map { toPath(it) }
fun FileToPathConverter.toFiles(paths: Collection<String>): List<File> =
paths.map { toFile(it) }
object FileToCanonicalPathConverter : FileToPathConverter {
override fun toPath(file: File): String = file.canonicalPath
override fun toFile(path: String): File = File(path)
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
import java.io.File
class FilesMap(storageFile: File)
: BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
operator fun set(sourceFile: File, outputFiles: Collection<File>) {
storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath }
}
operator fun get(sourceFile: File): Collection<File> =
storage[sourceFile.absolutePath].orEmpty().map(::File)
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
fun remove(file: File): Collection<File> =
get(file).also { storage.remove(file.absolutePath) }
}

View File

@@ -16,24 +16,20 @@
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.EnumeratorStringDescriptor
import com.intellij.util.io.ExternalIntegerKeyDescriptor
import java.io.File
internal class IdToFileMap(
file: File,
private val pathConverter: FileToPathConverter
) : BasicMap<Int, String>(file, ExternalIntegerKeyDescriptor(), EnumeratorStringDescriptor.INSTANCE) {
internal class IdToFileMap(file: File) : BasicMap<Int, File>(file, ExternalIntegerKeyDescriptor(), FileKeyDescriptor) {
override fun dumpKey(key: Int): String = key.toString()
override fun dumpValue(value: String): String = value
override fun dumpValue(value: File): String = value.toString()
operator fun get(id: Int): File? = storage[id]?.let { pathConverter.toFile(it) }
operator fun get(id: Int): File? = storage[id]
operator fun contains(id: Int): Boolean = id in storage
operator fun set(id: Int, file: File) {
storage[id] = pathConverter.toPath(file)
storage[id] = file
}
fun remove(id: Int) {

View File

@@ -16,14 +16,107 @@
package org.jetbrains.kotlin.incremental.storage
interface LazyStorage<K, V> {
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.IOUtil
import com.intellij.util.io.KeyDescriptor
import com.intellij.util.io.PersistentHashMap
import java.io.DataOutput
import java.io.File
import java.io.IOException
/**
* It's lazy in a sense that PersistentHashMap is created only on write
*/
class LazyStorage<K, V>(
private val storageFile: File,
private val keyDescriptor: KeyDescriptor<K>,
private val valueExternalizer: DataExternalizer<V>
) {
@Volatile
private var storage: PersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
if (storage != null) return storage
if (storageFile.exists()) {
storage = createMap()
return storage
}
return null
}
@Synchronized
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
return storage!!
}
val keys: Collection<K>
operator fun contains(key: K): Boolean
operator fun get(key: K): V?
operator fun set(key: K, value: V)
fun remove(key: K)
fun append(key: K, value: V)
fun clean()
fun flush(memoryCachesOnly: Boolean)
fun close()
}
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
operator fun contains(key: K): Boolean =
getStorageIfExists()?.containsMapping(key) ?: false
operator fun get(key: K): V? =
getStorageIfExists()?.get(key)
operator fun set(key: K, value: V) {
getStorageOrCreateNew().put(key, value)
}
fun remove(key: K) {
getStorageIfExists()?.remove(key)
}
fun append(key: K, value: String) {
append(key) { out -> IOUtil.writeUTF(out, value) }
}
fun append(key: K, value: Int) {
append(key) { out -> out.writeInt(value) }
}
@Synchronized
fun clean() {
try {
storage?.close()
}
catch (ignored: Throwable) {
}
PersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
@Synchronized
fun flush(memoryCachesOnly: Boolean) {
val existingStorage = storage ?: return
if (memoryCachesOnly) {
if (existingStorage.isDirty) {
existingStorage.dropMemoryCaches()
}
}
else {
existingStorage.force()
}
}
@Synchronized
fun close() {
storage?.close()
}
private fun createMap(): PersistentHashMap<K, V> =
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
private fun append(key: K, append: (DataOutput)->Unit) {
getStorageOrCreateNew().appendData(key, append)
}
}

View File

@@ -24,7 +24,7 @@ internal class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Collection<I
override fun dumpValue(value: Collection<Int>): String = value.toString()
fun add(name: String, scope: String, fileId: Int) {
storage.append(LookupSymbolKey(name, scope), listOf(fileId))
storage.append(LookupSymbolKey(name, scope), fileId)
}
operator fun get(key: LookupSymbolKey): Collection<Int>? = storage[key]

View File

@@ -1,106 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.KeyDescriptor
import com.intellij.util.io.PersistentHashMap
import java.io.File
class NonCachingLazyStorage<K, V>(
private val storageFile: File,
private val keyDescriptor: KeyDescriptor<K>,
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: PersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
if (storage != null) return storage
if (storageFile.exists()) {
storage = createMap()
return storage
}
return null
}
@Synchronized
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
return storage!!
}
override val keys: Collection<K>
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
override operator fun contains(key: K): Boolean =
getStorageIfExists()?.containsMapping(key) ?: false
override operator fun get(key: K): V? =
getStorageIfExists()?.get(key)
override operator fun set(key: K, value: V) {
getStorageOrCreateNew().put(key, value)
}
override fun remove(key: K) {
getStorageIfExists()?.remove(key)
}
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
}
@Synchronized
override fun clean() {
try {
storage?.close()
} catch (ignored: Throwable) {
}
PersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
@Synchronized
override fun flush(memoryCachesOnly: Boolean) {
val existingStorage = storage ?: return
if (memoryCachesOnly) {
if (existingStorage.isDirty) {
existingStorage.dropMemoryCaches()
}
} else {
existingStorage.force()
}
}
@Synchronized
override fun close() {
storage?.close()
}
private fun createMap(): PersistentHashMap<K, V> =
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
}

View File

@@ -1,106 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.KeyDescriptor
import com.intellij.util.io.JpsPersistentHashMap
import java.io.File
class NonCachingLazyStorage<K, V>(
private val storageFile: File,
private val keyDescriptor: KeyDescriptor<K>,
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: JpsPersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): JpsPersistentHashMap<K, V>? {
if (storage != null) return storage
if (storageFile.exists()) {
storage = createMap()
return storage
}
return null
}
@Synchronized
private fun getStorageOrCreateNew(): JpsPersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
return storage!!
}
override val keys: Collection<K>
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
override operator fun contains(key: K): Boolean =
getStorageIfExists()?.containsMapping(key) ?: false
override operator fun get(key: K): V? =
getStorageIfExists()?.get(key)
override operator fun set(key: K, value: V) {
getStorageOrCreateNew().put(key, value)
}
override fun remove(key: K) {
getStorageIfExists()?.remove(key)
}
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendDataWithoutCache(key, value)
}
@Synchronized
override fun clean() {
try {
storage?.close()
} catch (ignored: Throwable) {
}
JpsPersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
@Synchronized
override fun flush(memoryCachesOnly: Boolean) {
val existingStorage = storage ?: return
if (memoryCachesOnly) {
if (existingStorage.isDirty) {
existingStorage.dropMemoryCaches()
}
} else {
existingStorage.force()
}
}
@Synchronized
override fun close() {
storage?.close()
}
private fun createMap(): JpsPersistentHashMap<K, V> =
JpsPersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.storage
import java.io.File
open class RelativeFileToPathConverter(baseDirFile: File?) : FileToPathConverter {
private val baseDirPath = baseDirFile?.canonicalFile?.invariantSeparatorsPath
override fun toPath(file: File): String {
val path = file.canonicalFile.invariantSeparatorsPath
return when {
baseDirPath != null && path.startsWith(baseDirPath) ->
PROJECT_DIR_PLACEHOLDER + path.substring(baseDirPath.length)
else -> path
}
}
override fun toFile(path: String): File =
when {
path.startsWith(PROJECT_DIR_PLACEHOLDER) -> {
val basePath = baseDirPath ?: error("Could not get project root dir")
File(basePath + path.substring(PROJECT_DIR_PLACEHOLDER.length))
}
else -> File(path)
}
private companion object {
private const val PROJECT_DIR_PLACEHOLDER = "${'$'}PROJECT_DIR$"
}
}

View File

@@ -21,40 +21,32 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import java.io.File
internal class SourceToJvmNameMap(
storageFile: File,
pathConverter: FileToPathConverter
) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile, pathConverter)
internal class SourceToFqNameMap(
storageFile: File,
pathConverter: FileToPathConverter
) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile, pathConverter)
internal class SourceToJvmNameMap(storageFile: File) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile)
internal class SourceToFqNameMap(storageFile: File) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile)
internal abstract class AbstractSourceToOutputMap<Name>(
private val nameTransformer: NameTransformer<Name>,
storageFile: File,
private val pathConverter: FileToPathConverter
private val nameTransformer: NameTransformer<Name>,
storageFile: File
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
fun clearOutputsForSource(sourceFile: File) {
remove(pathConverter.toPath(sourceFile))
remove(sourceFile.absolutePath)
}
fun add(sourceFile: File, className: Name) {
storage.append(pathConverter.toPath(sourceFile), listOf(nameTransformer.asString(className)))
storage.append(sourceFile.absolutePath, nameTransformer.asString(className))
}
fun contains(sourceFile: File): Boolean =
pathConverter.toPath(sourceFile) in storage
sourceFile.absolutePath in storage
operator fun get(sourceFile: File): Collection<Name> =
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asName)
storage[sourceFile.absolutePath].orEmpty().map(nameTransformer::asName)
fun getFqNames(sourceFile: File): Collection<FqName> =
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asFqName)
storage[sourceFile.absolutePath].orEmpty().map(nameTransformer::asFqName)
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
value.dumpCollection()
private fun remove(path: String) {
storage.remove(path)

View File

@@ -177,6 +177,20 @@ object PathStringDescriptor : EnumeratorStringDescriptor() {
override fun isEqual(val1: String, val2: String?) = FileUtil.pathsEqual(val1, val2)
}
object FileKeyDescriptor : KeyDescriptor<File> {
override fun read(input: DataInput): File = File(input.readUTF())
override fun save(output: DataOutput, value: File) {
output.writeUTF(value.canonicalPath)
}
override fun getHashCode(value: File?): Int =
FileUtil.FILE_HASHING_STRATEGY.computeHashCode(value)
override fun isEqual(val1: File?, val2: File?): Boolean =
FileUtil.FILE_HASHING_STRATEGY.equals(val1, val2)
}
open class CollectionExternalizer<T>(
private val elementExternalizer: DataExternalizer<T>,
private val newCollection: () -> MutableCollection<T>

View File

@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.modules
import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName
import com.intellij.openapi.util.text.StringUtil.escapeXml
import org.jetbrains.kotlin.build.JvmSourceRoot
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser.*
import org.jetbrains.kotlin.config.IncrementalCompilation
@@ -32,18 +34,16 @@ class KotlinModuleXmlBuilder {
}
fun addModule(
moduleName: String,
outputDir: String,
sourceFiles: Iterable<File>,
javaSourceRoots: Iterable<JvmSourceRoot>,
classpathRoots: Iterable<File>,
commonSourceFiles: Iterable<File>,
modularJdkRoot: File?,
targetTypeId: String,
isTests: Boolean,
directoriesToFilterOut: Set<File>,
friendDirs: Iterable<File>
): KotlinModuleXmlBuilder {
moduleName: String,
outputDir: String,
sourceFiles: Iterable<File>,
javaSourceRoots: Iterable<JvmSourceRoot>,
classpathRoots: Iterable<File>,
modularJdkRoot: File?,
targetTypeId: String,
isTests: Boolean,
directoriesToFilterOut: Set<File>,
friendDirs: Iterable<File>): KotlinModuleXmlBuilder {
assert(!done) { "Already done" }
p.println("<!-- Module script for ${if (isTests) "tests" else "production"} -->")
@@ -62,10 +62,6 @@ class KotlinModuleXmlBuilder {
p.println("<", SOURCES, " ", PATH, "=\"", getEscapedPath(sourceFile), "\"/>")
}
for (commonSourceFile in commonSourceFiles) {
p.println("<", COMMON_SOURCES, " ", PATH, "=\"", getEscapedPath(commonSourceFile), "\"/>")
}
processJavaSourceRoots(javaSourceRoots)
processClasspath(classpathRoots, directoriesToFilterOut)
@@ -82,7 +78,7 @@ class KotlinModuleXmlBuilder {
directoriesToFilterOut: Set<File>) {
p.println("<!-- Classpath -->")
for (file in files) {
val isOutput = directoriesToFilterOut.contains(file) && !IncrementalCompilation.isEnabledForJvm()
val isOutput = directoriesToFilterOut.contains(file) && !IncrementalCompilation.isEnabled()
if (isOutput) {
// For IDEA's make (incremental compilation) purposes, output directories of the current module and its dependencies
// appear on the class path, so we are at risk of seeing the results of the previous build, i.e. if some class was
@@ -135,13 +131,6 @@ class KotlinModuleXmlBuilder {
}
private fun getEscapedPath(sourceFile: File): String {
return escapeXml(sourceFile.invariantSeparatorsPath)
}
private companion object {
private val xmlEscapeReplacement = mapOf("<" to "&lt;", ">" to "&gt;", "&" to "&amp;", "'" to "&#39;", "\"" to "&quot;")
private val xmlEscapeRegex = Regex(xmlEscapeReplacement.keys.joinToString("|", "(?:", ")") { Regex.escape(it) })
private fun escapeXml(string: String) = string.replace(xmlEscapeRegex) { xmlEscapeReplacement.getValue(it.value) }
return escapeXml(toSystemIndependentName(sourceFile.path))
}
}

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