mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-19 15:51:29 +00:00
Compare commits
31 Commits
rr/selezne
...
kombo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
608d5a0a84 | ||
|
|
ccf4b8746c | ||
|
|
12e85d91e8 | ||
|
|
2522a80b0c | ||
|
|
73bc5bb06f | ||
|
|
574dbf11bf | ||
|
|
e3ae69b369 | ||
|
|
57767d5786 | ||
|
|
80b05eec28 | ||
|
|
71da052029 | ||
|
|
608514155a | ||
|
|
07913617a2 | ||
|
|
bbdb8f3b44 | ||
|
|
f08bafaabd | ||
|
|
52f75cb206 | ||
|
|
592889bc5c | ||
|
|
a65f5a18e7 | ||
|
|
b9fe5b3f75 | ||
|
|
55a75a8775 | ||
|
|
4978101707 | ||
|
|
f69254d599 | ||
|
|
874f3252cc | ||
|
|
4a3c6a4696 | ||
|
|
10f3b64e2a | ||
|
|
401e61e70d | ||
|
|
666b9db6da | ||
|
|
9f6f039ebb | ||
|
|
f0412f9926 | ||
|
|
d3a4864c6b | ||
|
|
d41dfe52c7 | ||
|
|
1c57dcf718 |
323
.editorconfig
Normal file
323
.editorconfig
Normal file
@@ -0,0 +1,323 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
# charset = utf-8
|
||||
# end_of_line = lf
|
||||
indent_size = 4
|
||||
# indent_style = space
|
||||
# insert_final_newline = false
|
||||
# max_line_length = 140
|
||||
tab_width = 4
|
||||
ij_continuation_indent_size = 8
|
||||
# ij_formatter_off_tag = @formatter:off
|
||||
# ij_formatter_on_tag = @formatter:on
|
||||
ij_formatter_tags_enabled = false
|
||||
# ij_smart_tabs = false
|
||||
# ij_wrap_on_typing = false
|
||||
|
||||
[*.java]
|
||||
# ij_java_align_consecutive_assignments = false
|
||||
# ij_java_align_consecutive_variable_declarations = false
|
||||
# ij_java_align_group_field_declarations = false
|
||||
# ij_java_align_multiline_annotation_parameters = false
|
||||
# ij_java_align_multiline_array_initializer_expression = false
|
||||
# ij_java_align_multiline_assignment = true
|
||||
# ij_java_align_multiline_binary_operation = true
|
||||
# ij_java_align_multiline_chained_methods = false
|
||||
# ij_java_align_multiline_extends_list = true
|
||||
# ij_java_align_multiline_for = true
|
||||
# ij_java_align_multiline_method_parentheses = false
|
||||
ij_java_align_multiline_parameters = false
|
||||
# ij_java_align_multiline_parameters_in_calls = true
|
||||
# ij_java_align_multiline_parenthesized_expression = true
|
||||
# ij_java_align_multiline_resources = true
|
||||
# ij_java_align_multiline_ternary_operation = true
|
||||
# ij_java_align_multiline_text_blocks = false
|
||||
# ij_java_align_multiline_throws_list = true
|
||||
# ij_java_align_subsequent_simple_methods = false
|
||||
# ij_java_align_throws_keyword = false
|
||||
# ij_java_annotation_parameter_wrap = off
|
||||
# ij_java_array_initializer_new_line_after_left_brace = false
|
||||
# ij_java_array_initializer_right_brace_on_new_line = false
|
||||
# ij_java_array_initializer_wrap = normal
|
||||
# ij_java_assert_statement_colon_on_next_line = false
|
||||
# ij_java_assert_statement_wrap = off
|
||||
# ij_java_assignment_wrap = normal
|
||||
# ij_java_binary_operation_sign_on_next_line = false
|
||||
# ij_java_binary_operation_wrap = on_every_item
|
||||
# ij_java_blank_lines_after_anonymous_class_header = 0
|
||||
# ij_java_blank_lines_after_class_header = 0
|
||||
# ij_java_blank_lines_after_imports = 1
|
||||
# ij_java_blank_lines_after_package = 1
|
||||
# ij_java_blank_lines_around_class = 1
|
||||
# ij_java_blank_lines_around_field = 0
|
||||
# ij_java_blank_lines_around_field_in_interface = 0
|
||||
# ij_java_blank_lines_around_initializer = 1
|
||||
# ij_java_blank_lines_around_method = 1
|
||||
# ij_java_blank_lines_around_method_in_interface = 1
|
||||
# ij_java_blank_lines_before_class_end = 0
|
||||
# ij_java_blank_lines_before_imports = 1
|
||||
# ij_java_blank_lines_before_method_body = 0
|
||||
# ij_java_blank_lines_before_package = 0
|
||||
# ij_java_block_brace_style = end_of_line
|
||||
# ij_java_block_comment_at_first_column = false
|
||||
# ij_java_call_parameters_new_line_after_left_paren = false
|
||||
# ij_java_call_parameters_right_paren_on_new_line = false
|
||||
# ij_java_call_parameters_wrap = normal
|
||||
# ij_java_case_statement_on_separate_line = true
|
||||
# ij_java_catch_on_new_line = true
|
||||
# ij_java_class_annotation_wrap = split_into_lines
|
||||
# ij_java_class_brace_style = end_of_line
|
||||
# ij_java_class_count_to_use_import_on_demand = 5
|
||||
# ij_java_class_names_in_javadoc = 1
|
||||
# ij_java_do_not_indent_top_level_class_members = false
|
||||
# ij_java_do_not_wrap_after_single_annotation = false
|
||||
# ij_java_do_while_brace_force = if_multiline
|
||||
# ij_java_doc_add_blank_line_after_description = true
|
||||
# ij_java_doc_add_blank_line_after_param_comments = false
|
||||
# ij_java_doc_add_blank_line_after_return = false
|
||||
# ij_java_doc_add_p_tag_on_empty_lines = true
|
||||
# ij_java_doc_align_exception_comments = true
|
||||
# ij_java_doc_align_param_comments = true
|
||||
# ij_java_doc_do_not_wrap_if_one_line = false
|
||||
# ij_java_doc_enable_formatting = true
|
||||
# ij_java_doc_enable_leading_asterisks = true
|
||||
# ij_java_doc_indent_on_continuation = false
|
||||
# ij_java_doc_keep_empty_lines = true
|
||||
# ij_java_doc_keep_empty_parameter_tag = true
|
||||
# ij_java_doc_keep_empty_return_tag = true
|
||||
# ij_java_doc_keep_empty_throws_tag = true
|
||||
# ij_java_doc_keep_invalid_tags = true
|
||||
# ij_java_doc_param_description_on_new_line = false
|
||||
# ij_java_doc_preserve_line_breaks = false
|
||||
# ij_java_doc_use_throws_not_exception_tag = true
|
||||
# ij_java_else_on_new_line = true
|
||||
# ij_java_enum_constants_wrap = off
|
||||
# ij_java_extends_keyword_wrap = normal
|
||||
# ij_java_extends_list_wrap = normal
|
||||
# ij_java_field_annotation_wrap = off
|
||||
ij_java_field_name_prefix = ""
|
||||
# ij_java_finally_on_new_line = true
|
||||
# ij_java_for_brace_force = if_multiline
|
||||
# ij_java_for_statement_new_line_after_left_paren = false
|
||||
# ij_java_for_statement_right_paren_on_new_line = false
|
||||
# ij_java_for_statement_wrap = on_every_item
|
||||
# ij_java_generate_final_locals = false
|
||||
# ij_java_generate_final_parameters = false
|
||||
# ij_java_if_brace_force = if_multiline
|
||||
# ij_java_imports_layout = *,|,javax.**,java.**,|,$*
|
||||
# ij_java_indent_case_from_switch = true
|
||||
# ij_java_insert_inner_class_imports = false
|
||||
# ij_java_insert_override_annotation = true
|
||||
# ij_java_keep_blank_lines_before_right_brace = 0
|
||||
# ij_java_keep_blank_lines_between_package_declaration_and_header = 2
|
||||
# ij_java_keep_blank_lines_in_code = 2
|
||||
# ij_java_keep_blank_lines_in_declarations = 2
|
||||
# ij_java_keep_control_statement_in_one_line = true
|
||||
# ij_java_keep_first_column_comment = false
|
||||
# ij_java_keep_indents_on_empty_lines = false
|
||||
# ij_java_keep_line_breaks = true
|
||||
# ij_java_keep_multiple_expressions_in_one_line = false
|
||||
# ij_java_keep_simple_blocks_in_one_line = false
|
||||
# ij_java_keep_simple_classes_in_one_line = false
|
||||
# ij_java_keep_simple_lambdas_in_one_line = false
|
||||
ij_java_keep_simple_methods_in_one_line = false
|
||||
# ij_java_label_indent_absolute = false
|
||||
# ij_java_label_indent_size = 0
|
||||
# ij_java_lambda_brace_style = end_of_line
|
||||
# ij_java_layout_static_imports_separately = true
|
||||
# ij_java_line_comment_add_space = false
|
||||
# ij_java_line_comment_at_first_column = false
|
||||
# ij_java_method_annotation_wrap = split_into_lines
|
||||
# ij_java_method_brace_style = end_of_line
|
||||
# ij_java_method_call_chain_wrap = normal
|
||||
ij_java_method_parameters_new_line_after_left_paren = true
|
||||
ij_java_method_parameters_right_paren_on_new_line = true
|
||||
# ij_java_method_parameters_wrap = on_every_item
|
||||
# ij_java_modifier_list_wrap = false
|
||||
# ij_java_names_count_to_use_import_on_demand = 3
|
||||
# ij_java_packages_to_use_import_on_demand = java.awt.*,javax.tools.**,javax.swing.*
|
||||
# ij_java_parameter_annotation_wrap = off
|
||||
# ij_java_parentheses_expression_new_line_after_left_paren = false
|
||||
# ij_java_parentheses_expression_right_paren_on_new_line = false
|
||||
# ij_java_place_assignment_sign_on_next_line = false
|
||||
# ij_java_prefer_longer_names = false
|
||||
# ij_java_prefer_parameters_wrap = false
|
||||
# ij_java_repeat_synchronized = true
|
||||
# ij_java_replace_instanceof_and_cast = false
|
||||
# ij_java_replace_null_check = true
|
||||
# ij_java_replace_sum_lambda_with_method_ref = true
|
||||
# ij_java_resource_list_new_line_after_left_paren = false
|
||||
# ij_java_resource_list_right_paren_on_new_line = false
|
||||
# ij_java_resource_list_wrap = off
|
||||
# ij_java_space_after_closing_angle_bracket_in_type_argument = false
|
||||
# ij_java_space_after_colon = true
|
||||
# ij_java_space_after_comma = true
|
||||
# ij_java_space_after_comma_in_type_arguments = true
|
||||
# ij_java_space_after_for_semicolon = true
|
||||
# ij_java_space_after_quest = true
|
||||
ij_java_space_after_type_cast = true
|
||||
# ij_java_space_before_annotation_array_initializer_left_brace = false
|
||||
# ij_java_space_before_annotation_parameter_list = false
|
||||
ij_java_space_before_array_initializer_left_brace = true
|
||||
# ij_java_space_before_catch_keyword = true
|
||||
# ij_java_space_before_catch_left_brace = true
|
||||
# ij_java_space_before_catch_parentheses = true
|
||||
# ij_java_space_before_class_left_brace = true
|
||||
# ij_java_space_before_colon = true
|
||||
# ij_java_space_before_colon_in_foreach = true
|
||||
# ij_java_space_before_comma = false
|
||||
# ij_java_space_before_do_left_brace = true
|
||||
# ij_java_space_before_else_keyword = true
|
||||
# ij_java_space_before_else_left_brace = true
|
||||
# ij_java_space_before_finally_keyword = true
|
||||
# ij_java_space_before_finally_left_brace = true
|
||||
# ij_java_space_before_for_left_brace = true
|
||||
# ij_java_space_before_for_parentheses = true
|
||||
# ij_java_space_before_for_semicolon = false
|
||||
# ij_java_space_before_if_left_brace = true
|
||||
# ij_java_space_before_if_parentheses = true
|
||||
# ij_java_space_before_method_call_parentheses = false
|
||||
# ij_java_space_before_method_left_brace = true
|
||||
# ij_java_space_before_method_parentheses = false
|
||||
# ij_java_space_before_opening_angle_bracket_in_type_parameter = false
|
||||
# ij_java_space_before_quest = true
|
||||
# ij_java_space_before_switch_left_brace = true
|
||||
# ij_java_space_before_switch_parentheses = true
|
||||
# ij_java_space_before_synchronized_left_brace = true
|
||||
# ij_java_space_before_synchronized_parentheses = true
|
||||
# ij_java_space_before_try_left_brace = true
|
||||
# ij_java_space_before_try_parentheses = true
|
||||
# ij_java_space_before_type_parameter_list = false
|
||||
# ij_java_space_before_while_keyword = true
|
||||
# ij_java_space_before_while_left_brace = true
|
||||
# ij_java_space_before_while_parentheses = true
|
||||
# ij_java_space_inside_one_line_enum_braces = false
|
||||
# ij_java_space_within_empty_array_initializer_braces = false
|
||||
# ij_java_space_within_empty_method_call_parentheses = false
|
||||
# ij_java_space_within_empty_method_parentheses = false
|
||||
# ij_java_spaces_around_additive_operators = true
|
||||
# ij_java_spaces_around_assignment_operators = true
|
||||
# ij_java_spaces_around_bitwise_operators = true
|
||||
# ij_java_spaces_around_equality_operators = true
|
||||
# ij_java_spaces_around_lambda_arrow = true
|
||||
# ij_java_spaces_around_logical_operators = true
|
||||
# ij_java_spaces_around_method_ref_dbl_colon = false
|
||||
# ij_java_spaces_around_multiplicative_operators = true
|
||||
# ij_java_spaces_around_relational_operators = true
|
||||
# ij_java_spaces_around_shift_operators = true
|
||||
# ij_java_spaces_around_type_bounds_in_type_parameters = true
|
||||
# ij_java_spaces_around_unary_operator = false
|
||||
# ij_java_spaces_within_angle_brackets = false
|
||||
# ij_java_spaces_within_annotation_parentheses = false
|
||||
# ij_java_spaces_within_array_initializer_braces = false
|
||||
ij_java_spaces_within_braces = false
|
||||
# ij_java_spaces_within_brackets = false
|
||||
# ij_java_spaces_within_cast_parentheses = false
|
||||
# ij_java_spaces_within_catch_parentheses = false
|
||||
# ij_java_spaces_within_for_parentheses = false
|
||||
# ij_java_spaces_within_if_parentheses = false
|
||||
# ij_java_spaces_within_method_call_parentheses = false
|
||||
# ij_java_spaces_within_method_parentheses = false
|
||||
# ij_java_spaces_within_parentheses = false
|
||||
# ij_java_spaces_within_switch_parentheses = false
|
||||
# ij_java_spaces_within_synchronized_parentheses = false
|
||||
# ij_java_spaces_within_try_parentheses = false
|
||||
# ij_java_spaces_within_while_parentheses = false
|
||||
# ij_java_special_else_if_treatment = true
|
||||
ij_java_static_field_name_prefix = ""
|
||||
# ij_java_subclass_name_suffix = Impl
|
||||
# ij_java_ternary_operation_signs_on_next_line = true
|
||||
# ij_java_ternary_operation_wrap = on_every_item
|
||||
# ij_java_test_name_suffix = Test
|
||||
# ij_java_throws_keyword_wrap = normal
|
||||
# ij_java_throws_list_wrap = on_every_item
|
||||
# ij_java_use_external_annotations = false
|
||||
# ij_java_use_fq_class_names = false
|
||||
# ij_java_use_relative_indents = false
|
||||
# ij_java_use_single_class_imports = true
|
||||
# ij_java_variable_annotation_wrap = off
|
||||
ij_java_visibility = public
|
||||
# ij_java_while_brace_force = if_multiline
|
||||
# ij_java_while_on_new_line = true
|
||||
# ij_java_wrap_comments = false
|
||||
# ij_java_wrap_first_method_in_call_chain = false
|
||||
# ij_java_wrap_long_lines = false
|
||||
|
||||
[{*.kt,*.kts,*.main.kts}]
|
||||
# ij_kotlin_align_in_columns_case_branch = false
|
||||
ij_kotlin_align_multiline_binary_operation = false
|
||||
ij_kotlin_align_multiline_extends_list = false
|
||||
# ij_kotlin_align_multiline_method_parentheses = false
|
||||
# ij_kotlin_align_multiline_parameters = true
|
||||
# ij_kotlin_align_multiline_parameters_in_calls = true
|
||||
# ij_kotlin_allow_trailing_comma = false
|
||||
ij_kotlin_assignment_wrap = normal
|
||||
# ij_kotlin_blank_lines_after_class_header = 0
|
||||
# ij_kotlin_blank_lines_around_block_when_branches = 0
|
||||
# ij_kotlin_block_comment_at_first_column = true
|
||||
ij_kotlin_call_parameters_new_line_after_left_paren = true
|
||||
ij_kotlin_call_parameters_right_paren_on_new_line = true
|
||||
ij_kotlin_call_parameters_wrap = on_every_item
|
||||
ij_kotlin_catch_on_new_line = false
|
||||
# ij_kotlin_class_annotation_wrap = split_into_lines
|
||||
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
|
||||
ij_kotlin_continuation_indent_for_chained_calls = false
|
||||
ij_kotlin_continuation_indent_for_expression_bodies = false
|
||||
ij_kotlin_continuation_indent_in_argument_lists = false
|
||||
ij_kotlin_continuation_indent_in_elvis = false
|
||||
ij_kotlin_continuation_indent_in_if_conditions = false
|
||||
ij_kotlin_continuation_indent_in_parameter_lists = false
|
||||
ij_kotlin_continuation_indent_in_supertype_lists = false
|
||||
ij_kotlin_else_on_new_line = false
|
||||
# ij_kotlin_enum_constants_wrap = off
|
||||
ij_kotlin_extends_list_wrap = normal
|
||||
# ij_kotlin_field_annotation_wrap = split_into_lines
|
||||
ij_kotlin_finally_on_new_line = false
|
||||
ij_kotlin_if_rparen_on_new_line = true
|
||||
# ij_kotlin_import_nested_classes = false
|
||||
# ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
|
||||
# ij_kotlin_keep_blank_lines_before_right_brace = 2
|
||||
# ij_kotlin_keep_blank_lines_in_code = 2
|
||||
# ij_kotlin_keep_blank_lines_in_declarations = 2
|
||||
ij_kotlin_keep_first_column_comment = true
|
||||
# ij_kotlin_keep_indents_on_empty_lines = false
|
||||
# ij_kotlin_keep_line_breaks = true
|
||||
# ij_kotlin_lbrace_on_next_line = false
|
||||
# ij_kotlin_line_comment_add_space = false
|
||||
ij_kotlin_line_comment_at_first_column = true
|
||||
# ij_kotlin_method_annotation_wrap = split_into_lines
|
||||
ij_kotlin_method_call_chain_wrap = normal
|
||||
ij_kotlin_method_parameters_new_line_after_left_paren = true
|
||||
ij_kotlin_method_parameters_right_paren_on_new_line = true
|
||||
# ij_kotlin_method_parameters_wrap = on_every_item
|
||||
# ij_kotlin_name_count_to_use_star_import = 5
|
||||
# ij_kotlin_name_count_to_use_star_import_for_members = 3
|
||||
# ij_kotlin_parameter_annotation_wrap = off
|
||||
# ij_kotlin_space_after_comma = true
|
||||
# ij_kotlin_space_after_extend_colon = true
|
||||
# ij_kotlin_space_after_type_colon = true
|
||||
# ij_kotlin_space_before_catch_parentheses = true
|
||||
# ij_kotlin_space_before_comma = false
|
||||
# ij_kotlin_space_before_extend_colon = true
|
||||
# ij_kotlin_space_before_for_parentheses = true
|
||||
# ij_kotlin_space_before_if_parentheses = true
|
||||
# ij_kotlin_space_before_lambda_arrow = true
|
||||
# ij_kotlin_space_before_type_colon = false
|
||||
# ij_kotlin_space_before_when_parentheses = true
|
||||
# ij_kotlin_space_before_while_parentheses = true
|
||||
# ij_kotlin_spaces_around_additive_operators = true
|
||||
# ij_kotlin_spaces_around_assignment_operators = true
|
||||
# ij_kotlin_spaces_around_equality_operators = true
|
||||
# ij_kotlin_spaces_around_function_type_arrow = true
|
||||
# ij_kotlin_spaces_around_logical_operators = true
|
||||
# ij_kotlin_spaces_around_multiplicative_operators = true
|
||||
# ij_kotlin_spaces_around_range = false
|
||||
# ij_kotlin_spaces_around_relational_operators = true
|
||||
# ij_kotlin_spaces_around_unary_operator = false
|
||||
# ij_kotlin_spaces_around_when_arrow = true
|
||||
# ij_kotlin_variable_annotation_wrap = off
|
||||
ij_kotlin_while_on_new_line = false
|
||||
# ij_kotlin_wrap_elvis_expressions = 1
|
||||
ij_kotlin_wrap_expression_body_functions = 1
|
||||
# ij_kotlin_wrap_first_method_in_call_chain = false
|
||||
@@ -18,7 +18,7 @@ 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 com.intellij.util.io.PersistentHashMap
|
||||
import java.io.File
|
||||
|
||||
|
||||
@@ -28,10 +28,10 @@ class NonCachingLazyStorage<K, V>(
|
||||
private val valueExternalizer: DataExternalizer<V>
|
||||
) : LazyStorage<K, V> {
|
||||
@Volatile
|
||||
private var storage: JpsPersistentHashMap<K, V>? = null
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): JpsPersistentHashMap<K, V>? {
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
if (storageFile.exists()) {
|
||||
@@ -43,7 +43,7 @@ class NonCachingLazyStorage<K, V>(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): JpsPersistentHashMap<K, V> {
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class NonCachingLazyStorage<K, V>(
|
||||
}
|
||||
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendDataWithoutCache(key, value)
|
||||
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -79,7 +79,7 @@ class NonCachingLazyStorage<K, V>(
|
||||
} catch (ignored: Throwable) {
|
||||
}
|
||||
|
||||
JpsPersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
PersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
storage = null
|
||||
}
|
||||
|
||||
@@ -101,6 +101,6 @@ class NonCachingLazyStorage<K, V>(
|
||||
storage?.close()
|
||||
}
|
||||
|
||||
private fun createMap(): JpsPersistentHashMap<K, V> =
|
||||
JpsPersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
private fun createMap(): PersistentHashMap<K, V> =
|
||||
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
@@ -2,6 +2,8 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.plugins.ide.idea.model.IdeaModel
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import proguard.gradle.ProGuardTask
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
|
||||
buildscript {
|
||||
|
||||
@@ -347,6 +349,29 @@ allprojects {
|
||||
maven("https://dl.google.com/dl/android/maven2")
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
internalKotlinRepo?.let(::maven)
|
||||
|
||||
val intellijVersion = rootProject.extra["versions.intellijSdk"] as String
|
||||
|
||||
if (intellijVersion.startsWith("202.0.")) {
|
||||
val repoDir = File(rootProject.projectDir, "buildSrc/prepare-deps/intellijRepo")
|
||||
maven("file://" + repoDir.absolutePath.replace(File.separatorChar, '/'))
|
||||
} else if (intellijVersion.startsWith("202.")) {
|
||||
ivy {
|
||||
url = URI("https://buildserver.labs.intellij.net/guestAuth/repository/download/ijplatform_master_Idea_Installers/$intellijVersion/jps")
|
||||
|
||||
patternLayout {
|
||||
artifact("[artifact]-[revision].[ext]")
|
||||
}
|
||||
|
||||
content {
|
||||
includeModule("com.jetbrains.intellij.idea", "jps-build-test")
|
||||
}
|
||||
|
||||
metadataSources {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configureJvmProject(javaHome!!, jvmTarget!!)
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.xml.stream.XMLOutputFactory
|
||||
|
||||
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
|
||||
import org.jetbrains.kotlin.gradle.tasks.CleanDataTask
|
||||
import java.io.File
|
||||
|
||||
plugins {
|
||||
base
|
||||
@@ -87,6 +88,47 @@ repositories {
|
||||
}
|
||||
}
|
||||
|
||||
if (intellijVersion.startsWith("202.0.")) {
|
||||
val repoDir = File(project.projectDir, "intellijRepo")
|
||||
maven("file://" + repoDir.absolutePath.replace(File.separatorChar, '/'))
|
||||
} else if (intellijVersion.startsWith("202.")) {
|
||||
ivy {
|
||||
url = URI("https://buildserver.labs.intellij.net/guestAuth/repository/download/ijplatform_master_Idea_Installers/$intellijVersion")
|
||||
|
||||
patternLayout {
|
||||
artifact("[artifact]-[revision].portable.zip")
|
||||
artifact("[artifact]-[revision].zip")
|
||||
artifact("[artifact]-[revision]-sources.zip")
|
||||
}
|
||||
|
||||
content {
|
||||
includeModule("com.jetbrains.intellij.idea", "ideaIC")
|
||||
includeModule("com.jetbrains.intellij.idea", "ideaIU")
|
||||
includeModule("com.jetbrains.intellij.idea", "intellij-core")
|
||||
}
|
||||
|
||||
metadataSources {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
|
||||
ivy {
|
||||
url = URI("https://buildserver.labs.intellij.net/guestAuth/repository/download/ijplatform_master_Idea_Installers/$intellijVersion/jps")
|
||||
|
||||
patternLayout {
|
||||
artifact("standalone-jps-[revision].zip")
|
||||
}
|
||||
|
||||
content {
|
||||
includeModule("com.jetbrains.intellij.idea", "jps-standalone")
|
||||
}
|
||||
|
||||
metadataSources {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maven("https://www.jetbrains.com/intellij-repository/$intellijReleaseType")
|
||||
maven("https://plugins.jetbrains.com/maven")
|
||||
maven("https://jetbrains.bintray.com/intellij-third-party-dependencies/")
|
||||
@@ -293,8 +335,8 @@ fun buildIvyRepositoryTaskAndRegisterCleanupTask(
|
||||
copy {
|
||||
val fileTree = when (extension) {
|
||||
"tar.gz" -> tarTree(file)
|
||||
"zip" -> zipTree(file)
|
||||
else -> error("Unsupported artifact extension: $extension")
|
||||
"zip", "jar" -> zipTree(file)
|
||||
else -> error("Unsupported artifact extension: $extension ($file)")
|
||||
}
|
||||
|
||||
from(
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.jetbrains.intellij.idea</groupId>
|
||||
<artifactId>ideaIC</artifactId>
|
||||
<version>202.0.1</version>
|
||||
<packaging>zip</packaging>
|
||||
</project>
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.jetbrains.intellij.idea</groupId>
|
||||
<artifactId>ideaIU</artifactId>
|
||||
<version>202.0.1</version>
|
||||
<packaging>zip</packaging>
|
||||
</project>
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.jetbrains.intellij.idea</groupId>
|
||||
<artifactId>intellij-core</artifactId>
|
||||
<version>202.0.1</version>
|
||||
<packaging>zip</packaging>
|
||||
</project>
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.jetbrains.intellij.idea</groupId>
|
||||
<artifactId>intellij-runtime-annotations</artifactId>
|
||||
<version>202.0.1</version>
|
||||
<packaging>zip</packaging>
|
||||
</project>
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.jetbrains.intellij.idea</groupId>
|
||||
<artifactId>jps-build-test</artifactId>
|
||||
<version>202.0.1</version>
|
||||
<packaging>jar</packaging>
|
||||
</project>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.jetbrains.intellij.idea</groupId>
|
||||
<artifactId>jps-standalone</artifactId>
|
||||
<version>202.0.1</version>
|
||||
<packaging>zip</packaging>
|
||||
</project>
|
||||
Binary file not shown.
@@ -26,7 +26,7 @@ fun CompatibilityPredicate.or(other: CompatibilityPredicate): CompatibilityPredi
|
||||
}
|
||||
|
||||
enum class Platform : CompatibilityPredicate {
|
||||
P183, P191, P192, P193, P201;
|
||||
P183, P191, P192, P193, P201, P202;
|
||||
|
||||
val version: Int = name.drop(1).toInt()
|
||||
|
||||
@@ -45,6 +45,7 @@ enum class Ide(val platform: Platform) : CompatibilityPredicate {
|
||||
IJ192(Platform.P192),
|
||||
IJ193(Platform.P193),
|
||||
IJ201(Platform.P201),
|
||||
IJ202(Platform.P202),
|
||||
|
||||
AS35(Platform.P183),
|
||||
AS36(Platform.P192),
|
||||
|
||||
@@ -167,7 +167,7 @@ class InterfaceImplBodyCodegen(
|
||||
name: String,
|
||||
desc: String,
|
||||
signature: String?,
|
||||
exceptions: Array<out String>?
|
||||
exceptions: Array<out String?>?
|
||||
): MethodVisitor {
|
||||
if (shouldCount) {
|
||||
isAnythingGenerated = true
|
||||
|
||||
@@ -42,7 +42,7 @@ class OriginCollectingClassBuilderFactory(private val builderMode: ClassBuilderM
|
||||
name: String,
|
||||
desc: String,
|
||||
signature: String?,
|
||||
exceptions: Array<out String>?
|
||||
exceptions: Array<out String?>?
|
||||
): MethodVisitor {
|
||||
val methodNode = super.newMethod(origin, access, name, desc, signature, exceptions) as MethodNode
|
||||
origins[methodNode] = origin
|
||||
|
||||
@@ -63,7 +63,7 @@ abstract class SignatureCollectingClassBuilderFactory(
|
||||
return super.newField(origin, access, name, desc, signature, value)
|
||||
}
|
||||
|
||||
override fun newMethod(origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor {
|
||||
override fun newMethod(origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String?>?): MethodVisitor {
|
||||
signatures.putValue(RawSignature(name, desc, MemberKind.METHOD), origin)
|
||||
if (!shouldGenerate(origin)) {
|
||||
return AbstractClassBuilder.EMPTY_METHOD_VISITOR
|
||||
|
||||
@@ -905,7 +905,7 @@ private class MethodNodeExaminer(
|
||||
val methodNode: MethodNode,
|
||||
disableTailCallOptimizationForFunctionReturningUnit: Boolean
|
||||
) {
|
||||
private val sourceFrames: Array<Frame<SourceValue>?> =
|
||||
private val sourceFrames: Array<Frame<SourceValue>> =
|
||||
MethodTransformer.analyze(containingClassInternalName, methodNode, IgnoringCopyOperationSourceInterpreter())
|
||||
private val controlFlowGraph = ControlFlowGraph.build(methodNode)
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ fun analyzeLiveness(node: MethodNode): List<VariableLivenessFrame> {
|
||||
|
||||
private fun analyzeVisibleByDebuggerVariables(
|
||||
node: MethodNode,
|
||||
typeAnnotatedFrames: Array<Frame<BasicValue>?>
|
||||
typeAnnotatedFrames: Array<Frame<BasicValue>>
|
||||
): Array<BitSet> {
|
||||
val res = Array(node.instructions.size()) { BitSet(node.maxLocals) }
|
||||
for (local in node.localVariables) {
|
||||
|
||||
@@ -83,7 +83,7 @@ class SignatureDumpingBuilderFactory(
|
||||
super.defineClass(origin, version, access, name, signature, superName, interfaces)
|
||||
}
|
||||
|
||||
override fun newMethod(origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor {
|
||||
override fun newMethod(origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String?>?): MethodVisitor {
|
||||
signatures += RawSignature(name, desc, MemberKind.METHOD) to origin.descriptor?.let {
|
||||
if (it is CallableDescriptor) it.unwrapInitialDescriptorForSuspendFunction() else it
|
||||
}
|
||||
|
||||
@@ -4,147 +4,52 @@
|
||||
*/
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.DynamicBundle;
|
||||
import com.intellij.codeInsight.ContainerProvider;
|
||||
import com.intellij.codeInsight.JavaContainerProvider;
|
||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
import com.intellij.codeInsight.folding.impl.JavaCodeFoldingSettingsBase;
|
||||
import com.intellij.codeInsight.folding.impl.JavaFoldingBuilderBase;
|
||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
||||
import com.intellij.core.CoreApplicationEnvironment;
|
||||
import com.intellij.core.CoreJavaDirectoryService;
|
||||
import com.intellij.core.CorePsiPackageImplementationHelper;
|
||||
import com.intellij.ide.highlighter.ArchiveFileType;
|
||||
import com.intellij.ide.highlighter.JavaClassFileType;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.lang.LanguageASTFactory;
|
||||
import com.intellij.core.JavaCoreApplicationEnvironment;
|
||||
import com.intellij.lang.MetaLanguage;
|
||||
import com.intellij.lang.folding.LanguageFolding;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.navigation.ItemPresentationProviders;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.extensions.ExtensionsArea;
|
||||
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint;
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.openapi.fileTypes.PlainTextLanguage;
|
||||
import com.intellij.openapi.fileTypes.PlainTextParserDefinition;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.FileContextProvider;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.augment.TypeAnnotationModifier;
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||
import com.intellij.psi.impl.LanguageConstantExpressionEvaluator;
|
||||
import com.intellij.psi.impl.PsiExpressionEvaluator;
|
||||
import com.intellij.psi.impl.PsiSubstitutorFactoryImpl;
|
||||
import com.intellij.psi.impl.compiled.ClassFileStubBuilder;
|
||||
import com.intellij.psi.impl.file.PsiPackageImplementationHelper;
|
||||
import com.intellij.psi.impl.search.MethodSuperSearcher;
|
||||
import com.intellij.psi.impl.source.tree.JavaASTFactory;
|
||||
import com.intellij.psi.impl.source.tree.PlainTextASTFactory;
|
||||
import com.intellij.psi.meta.MetaDataContributor;
|
||||
import com.intellij.psi.presentation.java.*;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.stubs.BinaryFileStubBuilders;
|
||||
import com.intellij.util.QueryExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
/**
|
||||
* adapted from com.intellij.core.JavaCoreApplicationEnvironment
|
||||
* TODO: initiate removal original from com.intellij.core since it seems that there are no usages left
|
||||
*/
|
||||
public class KotlinCoreApplicationEnvironment extends CoreApplicationEnvironment {
|
||||
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
|
||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
||||
registerExtensionPoints();
|
||||
return environment;
|
||||
}
|
||||
|
||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
return new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
||||
}
|
||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
}
|
||||
|
||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
private static void registerExtensionPoints() {
|
||||
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
|
||||
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
|
||||
|
||||
registerExtensionPoints();
|
||||
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
||||
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
registerExtensions();
|
||||
}
|
||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
registerApplicationExtensionPoint(ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
|
||||
|
||||
private void registerExtensionPoints() {
|
||||
ExtensionsArea area = Extensions.getRootArea();
|
||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, FileContextProvider.EP_NAME, FileContextProvider.class);
|
||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
|
||||
}
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(area);
|
||||
}
|
||||
|
||||
private void registerExtensions() {
|
||||
registerFileType(JavaClassFileType.INSTANCE, "class");
|
||||
registerFileType(JavaFileType.INSTANCE, "java");
|
||||
registerFileType(ArchiveFileType.INSTANCE, "jar;zip");
|
||||
registerFileType(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess");
|
||||
|
||||
addExplicitExtension(LanguageASTFactory.INSTANCE, PlainTextLanguage.INSTANCE, new PlainTextASTFactory());
|
||||
registerParserDefinition(new PlainTextParserDefinition());
|
||||
|
||||
addExplicitExtension(FileTypeFileViewProviders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileViewProviderFactory());
|
||||
addExplicitExtension(BinaryFileStubBuilders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileStubBuilder());
|
||||
|
||||
addExplicitExtension(LanguageASTFactory.INSTANCE, JavaLanguage.INSTANCE, new JavaASTFactory());
|
||||
registerParserDefinition(new JavaParserDefinition());
|
||||
addExplicitExtension(LanguageConstantExpressionEvaluator.INSTANCE, JavaLanguage.INSTANCE, new PsiExpressionEvaluator());
|
||||
|
||||
addExtension(ContainerProvider.EP_NAME, new JavaContainerProvider());
|
||||
|
||||
myApplication.registerService(PsiPackageImplementationHelper.class, new CorePsiPackageImplementationHelper());
|
||||
myApplication.registerService(PsiSubstitutorFactory.class, new PsiSubstitutorFactoryImpl());
|
||||
|
||||
myApplication.registerService(JavaDirectoryService.class, createJavaDirectoryService());
|
||||
myApplication.registerService(JavaVersionService.class, new JavaVersionService());
|
||||
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiPackage.class, new PackagePresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiClass.class, new ClassPresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiMethod.class, new MethodPresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiField.class, new FieldPresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiLocalVariable.class, new VariablePresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiParameter.class, new VariablePresentationProvider());
|
||||
|
||||
registerApplicationService(JavaCodeFoldingSettings.class, new JavaCodeFoldingSettingsBase());
|
||||
addExplicitExtension(LanguageFolding.INSTANCE, JavaLanguage.INSTANCE, new JavaFoldingBuilderBase() {
|
||||
@Override
|
||||
protected boolean shouldShowExplicitLambdaType(@NotNull PsiAnonymousClass anonymousClass, @NotNull PsiNewExpression expression) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isBelowRightMargin(@NotNull PsiFile file, int lineLength) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
registerApplicationExtensionPoint(SuperMethodsSearch.EP_NAME, QueryExecutor.class);
|
||||
addExtension(SuperMethodsSearch.EP_NAME, new MethodSuperSearcher());
|
||||
}
|
||||
|
||||
// overridden in upsource
|
||||
protected CoreJavaDirectoryService createJavaDirectoryService() {
|
||||
return new CoreJavaDirectoryService();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
@Nullable
|
||||
@Override
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.codeInsight.ContainerProvider;
|
||||
import com.intellij.codeInsight.JavaContainerProvider;
|
||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
import com.intellij.codeInsight.folding.impl.JavaCodeFoldingSettingsBase;
|
||||
import com.intellij.codeInsight.folding.impl.JavaFoldingBuilderBase;
|
||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
||||
import com.intellij.core.CoreApplicationEnvironment;
|
||||
import com.intellij.core.CoreJavaDirectoryService;
|
||||
import com.intellij.core.CorePsiPackageImplementationHelper;
|
||||
import com.intellij.ide.highlighter.ArchiveFileType;
|
||||
import com.intellij.ide.highlighter.JavaClassFileType;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.lang.LanguageASTFactory;
|
||||
import com.intellij.lang.MetaLanguage;
|
||||
import com.intellij.lang.folding.LanguageFolding;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.navigation.ItemPresentationProviders;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.extensions.ExtensionsArea;
|
||||
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint;
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.openapi.fileTypes.PlainTextLanguage;
|
||||
import com.intellij.openapi.fileTypes.PlainTextParserDefinition;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.augment.TypeAnnotationModifier;
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||
import com.intellij.psi.impl.LanguageConstantExpressionEvaluator;
|
||||
import com.intellij.psi.impl.PsiExpressionEvaluator;
|
||||
import com.intellij.psi.impl.PsiSubstitutorFactoryImpl;
|
||||
import com.intellij.psi.impl.compiled.ClassFileStubBuilder;
|
||||
import com.intellij.psi.impl.file.PsiPackageImplementationHelper;
|
||||
import com.intellij.psi.impl.search.MethodSuperSearcher;
|
||||
import com.intellij.psi.impl.source.tree.JavaASTFactory;
|
||||
import com.intellij.psi.impl.source.tree.PlainTextASTFactory;
|
||||
import com.intellij.psi.meta.MetaDataContributor;
|
||||
import com.intellij.psi.presentation.java.*;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.stubs.BinaryFileStubBuilders;
|
||||
import com.intellij.util.QueryExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
/**
|
||||
* adapted from com.intellij.core.JavaCoreApplicationEnvironment
|
||||
* TODO: initiate removal original from com.intellij.core since it seems that there are no usages left
|
||||
*/
|
||||
public class KotlinCoreApplicationEnvironment extends CoreApplicationEnvironment {
|
||||
|
||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
return new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
||||
}
|
||||
|
||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
|
||||
registerExtensionPoints();
|
||||
|
||||
registerExtensions();
|
||||
}
|
||||
|
||||
private void registerExtensionPoints() {
|
||||
ExtensionsArea area = Extensions.getRootArea();
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, FileContextProvider.EP_NAME, FileContextProvider.class);
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(area);
|
||||
}
|
||||
|
||||
private void registerExtensions() {
|
||||
registerFileType(JavaClassFileType.INSTANCE, "class");
|
||||
registerFileType(JavaFileType.INSTANCE, "java");
|
||||
registerFileType(ArchiveFileType.INSTANCE, "jar;zip");
|
||||
registerFileType(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess");
|
||||
|
||||
addExplicitExtension(LanguageASTFactory.INSTANCE, PlainTextLanguage.INSTANCE, new PlainTextASTFactory());
|
||||
registerParserDefinition(new PlainTextParserDefinition());
|
||||
|
||||
addExplicitExtension(FileTypeFileViewProviders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileViewProviderFactory());
|
||||
addExplicitExtension(BinaryFileStubBuilders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileStubBuilder());
|
||||
|
||||
addExplicitExtension(LanguageASTFactory.INSTANCE, JavaLanguage.INSTANCE, new JavaASTFactory());
|
||||
registerParserDefinition(new JavaParserDefinition());
|
||||
addExplicitExtension(LanguageConstantExpressionEvaluator.INSTANCE, JavaLanguage.INSTANCE, new PsiExpressionEvaluator());
|
||||
|
||||
addExtension(ContainerProvider.EP_NAME, new JavaContainerProvider());
|
||||
|
||||
myApplication.registerService(PsiPackageImplementationHelper.class, new CorePsiPackageImplementationHelper());
|
||||
myApplication.registerService(PsiSubstitutorFactory.class, new PsiSubstitutorFactoryImpl());
|
||||
|
||||
myApplication.registerService(JavaDirectoryService.class, createJavaDirectoryService());
|
||||
myApplication.registerService(JavaVersionService.class, new JavaVersionService());
|
||||
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiPackage.class, new PackagePresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiClass.class, new ClassPresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiMethod.class, new MethodPresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiField.class, new FieldPresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiLocalVariable.class, new VariablePresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiParameter.class, new VariablePresentationProvider());
|
||||
|
||||
registerApplicationService(JavaCodeFoldingSettings.class, new JavaCodeFoldingSettingsBase());
|
||||
addExplicitExtension(LanguageFolding.INSTANCE, JavaLanguage.INSTANCE, new JavaFoldingBuilderBase() {
|
||||
@Override
|
||||
protected boolean shouldShowExplicitLambdaType(@NotNull PsiAnonymousClass anonymousClass, @NotNull PsiNewExpression expression) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isBelowRightMargin(@NotNull PsiFile file, int lineLength) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
registerApplicationExtensionPoint(SuperMethodsSearch.EP_NAME, QueryExecutor.class);
|
||||
addExtension(SuperMethodsSearch.EP_NAME, new MethodSuperSearcher());
|
||||
}
|
||||
|
||||
// overridden in upsource
|
||||
protected CoreJavaDirectoryService createJavaDirectoryService() {
|
||||
return new CoreJavaDirectoryService();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.*
|
||||
|
||||
class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
|
||||
override fun chooseAnnotationsPlace(element: PsiElement): AnnotationPlace = AnnotationPlace.NOWHERE
|
||||
override fun chooseAnnotationsPlaceNoUi(element: PsiElement): AnnotationPlace = AnnotationPlace.NOWHERE
|
||||
|
||||
override fun isExternalAnnotationWritable(listOwner: PsiModifierListOwner, annotationFQN: String): Boolean = false
|
||||
override fun isExternalAnnotation(annotation: PsiAnnotation): Boolean = false
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.cli.jvm.compiler
|
||||
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.*
|
||||
|
||||
class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
|
||||
override fun chooseAnnotationsPlace(element: PsiElement): AnnotationPlace = AnnotationPlace.NOWHERE
|
||||
|
||||
override fun isExternalAnnotationWritable(listOwner: PsiModifierListOwner, annotationFQN: String): Boolean = false
|
||||
override fun isExternalAnnotation(annotation: PsiAnnotation): Boolean = false
|
||||
|
||||
override fun findExternalAnnotationsFiles(listOwner: PsiModifierListOwner): List<PsiFile>? = null
|
||||
override fun findExternalAnnotation(listOwner: PsiModifierListOwner, annotationFQN: String): PsiAnnotation? = null
|
||||
override fun findExternalAnnotations(listOwner: PsiModifierListOwner): Array<out PsiAnnotation>? = null
|
||||
|
||||
override fun annotateExternally(
|
||||
listOwner: PsiModifierListOwner,
|
||||
annotationFQName: String,
|
||||
fromFile: PsiFile,
|
||||
value: Array<out PsiNameValuePair>?
|
||||
) {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun deannotate(listOwner: PsiModifierListOwner, annotationFQN: String): Boolean {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun editExternalAnnotation(
|
||||
listOwner: PsiModifierListOwner,
|
||||
annotationFQN: String,
|
||||
value: Array<out PsiNameValuePair>?
|
||||
): Boolean {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean = false
|
||||
|
||||
override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass, annotationFQN: String): List<PsiAnnotation> = emptyList()
|
||||
|
||||
override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass): List<PsiAnnotation> = emptyList()
|
||||
|
||||
override fun findExternalAnnotations(listOwner: PsiModifierListOwner, annotationFQN: String): List<PsiAnnotation> = emptyList()
|
||||
}
|
||||
@@ -6,4 +6,9 @@
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
fun setupIdeaStandaloneExecution() {
|
||||
System.getProperties().setProperty("idea.home.path", System.getProperty("java.io.tmpdir"))
|
||||
System.getProperties().setProperty("project.structure.add.tools.jar.to.new.jdk", "false")
|
||||
System.getProperties().setProperty("psi.track.invalidation", "true")
|
||||
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
||||
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 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.cli.jvm.compiler
|
||||
|
||||
fun setupIdeaStandaloneExecution() {
|
||||
}
|
||||
@@ -8,9 +8,11 @@ package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
import com.intellij.core.CoreApplicationEnvironment
|
||||
import com.intellij.openapi.extensions.ExtensionsArea
|
||||
import java.io.File
|
||||
import java.nio.file.FileSystems
|
||||
|
||||
// BUNCH: 193
|
||||
fun registerExtensionPointAndExtensionsEx(pluginFile: File, fileName: String, area: ExtensionsArea) {
|
||||
val pluginRoot = FileSystems.getDefault().getPath(pluginFile.path)
|
||||
@Suppress("MissingRecentApi")
|
||||
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginFile, fileName, area)
|
||||
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginRoot, fileName, area)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.cli.jvm.compiler
|
||||
|
||||
import com.intellij.core.CoreApplicationEnvironment
|
||||
import com.intellij.openapi.extensions.ExtensionsArea
|
||||
import java.io.File
|
||||
|
||||
// BUNCH: 193
|
||||
fun registerExtensionPointAndExtensionsEx(pluginFile: File, fileName: String, area: ExtensionsArea) {
|
||||
@Suppress("MissingRecentApi")
|
||||
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginFile, fileName, area)
|
||||
}
|
||||
@@ -50,7 +50,9 @@ public class JUnit3RunnerWithInnersForJPS extends Runner implements Filterable,
|
||||
public JUnit3RunnerWithInnersForJPS(Class<?> klass) {
|
||||
this.klass = klass;
|
||||
requestedRunners.add(klass);
|
||||
ensureCompilerXmlExists();
|
||||
if (KotlinTestUtils.getKotlinComboRoot() == null) {
|
||||
ensureCompilerXmlExists();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -102,6 +102,26 @@ public class KotlinTestUtils {
|
||||
private KotlinTestUtils() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getKotlinComboRoot() {
|
||||
String kotlinRoot = System.getProperty("kombo.kotlin.root", null);
|
||||
if (kotlinRoot == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new File(kotlinRoot);
|
||||
}
|
||||
|
||||
public static String getAbsolutePath(String path) {
|
||||
File kotlinRoot = getKotlinComboRoot();
|
||||
|
||||
if (kotlinRoot == null) {
|
||||
return path;
|
||||
} else {
|
||||
return new File(kotlinRoot, path).getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static AnalysisResult analyzeFile(@NotNull KtFile file, @NotNull KotlinCoreEnvironment environment) {
|
||||
return JvmResolveUtil.analyze(file, environment);
|
||||
@@ -755,10 +775,11 @@ public class KotlinTestUtils {
|
||||
}
|
||||
|
||||
private static void runTestImpl(@NotNull DoTest test, @Nullable TestCase testCase, String testDataFilePath) throws Exception {
|
||||
String absTestDataFilePath = getAbsolutePath(testDataFilePath);
|
||||
if (testCase != null) {
|
||||
Function0<Unit> wrapWithMuteInDatabase = MuteWithDatabaseKt.wrapWithMuteInDatabase(testCase, () -> {
|
||||
try {
|
||||
test.invoke(testDataFilePath);
|
||||
test.invoke(absTestDataFilePath);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
@@ -774,7 +795,7 @@ public class KotlinTestUtils {
|
||||
DoTest wrappedTest = testCase != null ?
|
||||
MuteWithFileKt.testWithMuteInFile(test, testCase) :
|
||||
MuteWithFileKt.testWithMuteInFile(test, "");
|
||||
wrappedTest.invoke(testDataFilePath);
|
||||
wrappedTest.invoke(absTestDataFilePath);
|
||||
}
|
||||
|
||||
private static DoTest testWithCustomIgnoreDirective(DoTest test, TargetBackend targetBackend, String ignoreDirective) throws Exception {
|
||||
|
||||
@@ -140,7 +140,6 @@ public abstract class KtParsingTestCase extends KtPlatformLiteFixture {
|
||||
// That's for reparse routines
|
||||
final PomModelImpl pomModel = new PomModelImpl(myProject);
|
||||
myProject.registerService(PomModel.class, pomModel);
|
||||
new TreeAspect(pomModel);
|
||||
}
|
||||
|
||||
public void configureFromParserDefinition(ParserDefinition definition, String extension) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.test.testFramework;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory;
|
||||
import com.intellij.diagnostic.PerformanceWatcher;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
@@ -23,20 +25,33 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.impl.DocumentCommitProcessor;
|
||||
import com.intellij.psi.impl.DocumentCommitThread;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.rt.execution.junit.FileComparisonFailure;
|
||||
import com.intellij.testFramework.*;
|
||||
import com.intellij.testFramework.exceptionCases.AbstractExceptionCase;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import com.intellij.util.containers.PeekableIterator;
|
||||
import com.intellij.util.containers.PeekableIteratorWrapper;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import com.intellij.util.indexing.FileBasedIndexImpl;
|
||||
import com.intellij.util.lang.CompoundRuntimeException;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.Equality;
|
||||
@@ -47,11 +62,9 @@ import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.test.IdeaSystemPropertiesForParallelRunConfigurator;
|
||||
import org.jetbrains.kotlin.testFramework.MockComponentManagerCreationTracer;
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker;
|
||||
import org.jetbrains.kotlin.types.FlexibleTypeImpl;
|
||||
import org.junit.Assert;
|
||||
import org.junit.ComparisonFailure;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -61,14 +74,19 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@SuppressWarnings("ALL")
|
||||
public abstract class KtUsefulTestCase extends TestCase {
|
||||
public static final boolean IS_UNDER_TEAMCITY = System.getenv("TEAMCITY_VERSION") != null;
|
||||
private static final String TEMP_DIR_MARKER = "unitTest_";
|
||||
public static final String TEMP_DIR_MARKER = "unitTest_";
|
||||
public static final boolean OVERWRITE_TESTDATA = Boolean.getBoolean("idea.tests.overwrite.data");
|
||||
|
||||
private static final String ORIGINAL_TEMP_DIR = FileUtil.getTempDirectory();
|
||||
@@ -79,26 +97,69 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
private Application application;
|
||||
|
||||
static {
|
||||
IdeaSystemPropertiesForParallelRunConfigurator.setProperties();
|
||||
//TODO: investigate and enable
|
||||
//IdeaForkJoinWorkerThreadFactory.setupPoisonFactory();
|
||||
IdeaForkJoinWorkerThreadFactory.setupPoisonFactory();
|
||||
Logger.setFactory(TestLoggerFactory.class);
|
||||
}
|
||||
protected static final Logger LOG = Logger.getInstance(KtUsefulTestCase.class);
|
||||
|
||||
@NotNull
|
||||
protected final Disposable myTestRootDisposable = new TestDisposable();
|
||||
private final Disposable myTestRootDisposable = new TestDisposable();
|
||||
|
||||
private static final String ourPathToKeep = null;
|
||||
static Path ourPathToKeep;
|
||||
private final List<String> myPathsToKeep = new ArrayList<>();
|
||||
|
||||
private File myTempDir;
|
||||
private String myTempDir;
|
||||
|
||||
private static final String DEFAULT_SETTINGS_EXTERNALIZED;
|
||||
private static final CodeInsightSettings defaultSettings = new CodeInsightSettings();
|
||||
static {
|
||||
// Radar #5755208: Command line Java applications need a way to launch without a Dock icon.
|
||||
System.setProperty("apple.awt.UIElement", "true");
|
||||
|
||||
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true;
|
||||
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = true;
|
||||
try {
|
||||
Element oldS = new Element("temp");
|
||||
defaultSettings.writeExternal(oldS);
|
||||
DEFAULT_SETTINGS_EXTERNALIZED = JDOMUtil.writeElement(oldS);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass here the exception you want to be thrown first
|
||||
* E.g.<pre>
|
||||
* {@code
|
||||
* void tearDown() {
|
||||
* try {
|
||||
* doTearDowns();
|
||||
* }
|
||||
* catch(Exception e) {
|
||||
* addSuppressedException(e);
|
||||
* }
|
||||
* finally {
|
||||
* super.tearDown();
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
protected void addSuppressedException(@NotNull Throwable e) {
|
||||
List<Throwable> list = mySuppressedExceptions;
|
||||
if (list == null) {
|
||||
mySuppressedExceptions = list = new SmartList<>();
|
||||
}
|
||||
list.add(e);
|
||||
}
|
||||
private List<Throwable> mySuppressedExceptions;
|
||||
|
||||
|
||||
public KtUsefulTestCase() {
|
||||
}
|
||||
|
||||
public KtUsefulTestCase(@NotNull String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected boolean shouldContainTempFiles() {
|
||||
@@ -118,11 +179,17 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
super.setUp();
|
||||
|
||||
if (shouldContainTempFiles()) {
|
||||
String testName = FileUtil.sanitizeFileName(getTestName(true));
|
||||
if (StringUtil.isEmptyOrSpaces(testName)) testName = "";
|
||||
IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
|
||||
String testName = null;
|
||||
if (policy != null) {
|
||||
testName = policy.getPerTestTempDirName();
|
||||
}
|
||||
if (testName == null) {
|
||||
testName = FileUtil.sanitizeFileName(getTestName(true));
|
||||
}
|
||||
testName = new File(testName).getName(); // in case the test name contains file separators
|
||||
myTempDir = FileUtil.createTempDirectory(TEMP_DIR_MARKER, testName, false);
|
||||
FileUtil.resetCanonicalTempPathCache(myTempDir.getPath());
|
||||
myTempDir = FileUtil.createTempDirectory(TEMP_DIR_MARKER + testName, "", false).getPath();
|
||||
FileUtil.resetCanonicalTempPathCache(myTempDir);
|
||||
}
|
||||
|
||||
boolean isStressTest = isStressTest();
|
||||
@@ -133,6 +200,16 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
|
||||
// turn off Disposer debugging for performance tests
|
||||
Disposer.setDebugMode(!isStressTest);
|
||||
|
||||
if (isIconRequired()) {
|
||||
// ensure that IconLoader will use dummy empty icon
|
||||
IconLoader.deactivate();
|
||||
//IconManager.activate();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isIconRequired() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -141,6 +218,11 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
// don't use method references here to make stack trace reading easier
|
||||
//noinspection Convert2MethodRef
|
||||
new RunAll(
|
||||
() -> {
|
||||
if (isIconRequired()) {
|
||||
//IconManager.deactivate();
|
||||
}
|
||||
},
|
||||
() -> disposeRootDisposable(),
|
||||
() -> cleanupSwingDataStructures(),
|
||||
() -> cleanupDeleteOnExitHookList(),
|
||||
@@ -149,7 +231,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
if (shouldContainTempFiles()) {
|
||||
FileUtil.resetCanonicalTempPathCache(ORIGINAL_TEMP_DIR);
|
||||
if (hasTmpFilesToKeep()) {
|
||||
File[] files = myTempDir.listFiles();
|
||||
File[] files = new File(myTempDir).listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (!shouldKeepTmpFile(file)) {
|
||||
@@ -159,15 +241,14 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
}
|
||||
else {
|
||||
FileUtil.delete(myTempDir);
|
||||
FileUtil.delete(new File(myTempDir));
|
||||
}
|
||||
}
|
||||
},
|
||||
() -> UIUtil.removeLeakingAppleListeners()
|
||||
).run();
|
||||
() -> waitForAppLeakingThreads(10, TimeUnit.SECONDS)
|
||||
).run(ObjectUtils.notNull(mySuppressedExceptions, Collections.emptyList()));
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
// -- KOTLIN ADDITIONAL START --
|
||||
TestApplicationUtilKt.resetApplicationToNull(application);
|
||||
application = null;
|
||||
@@ -184,12 +265,12 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
|
||||
private boolean hasTmpFilesToKeep() {
|
||||
return ourPathToKeep != null && FileUtil.isAncestor(myTempDir.getPath(), ourPathToKeep, false) || !myPathsToKeep.isEmpty();
|
||||
return ourPathToKeep != null && FileUtil.isAncestor(myTempDir, ourPathToKeep.toString(), false) || !myPathsToKeep.isEmpty();
|
||||
}
|
||||
|
||||
private boolean shouldKeepTmpFile(@NotNull File file) {
|
||||
String path = file.getPath();
|
||||
if (FileUtil.pathsEqual(path, ourPathToKeep)) return true;
|
||||
if (FileUtil.pathsEqual(path, ourPathToKeep.toString())) return true;
|
||||
for (String pathToKeep : myPathsToKeep) {
|
||||
if (FileUtil.pathsEqual(path, pathToKeep)) return true;
|
||||
}
|
||||
@@ -197,7 +278,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
|
||||
private static final Set<String> DELETE_ON_EXIT_HOOK_DOT_FILES;
|
||||
private static final Class DELETE_ON_EXIT_HOOK_CLASS;
|
||||
private static final Class<?> DELETE_ON_EXIT_HOOK_CLASS;
|
||||
static {
|
||||
Class<?> aClass;
|
||||
try {
|
||||
@@ -233,12 +314,45 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private static void cleanupSwingDataStructures() throws Exception {
|
||||
Object manager = ReflectionUtil.getDeclaredMethod(Class.forName("javax.swing.KeyboardManager"), "getCurrentManager").invoke(null);
|
||||
Map componentKeyStrokeMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "componentKeyStrokeMap");
|
||||
Map<?, ?> componentKeyStrokeMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "componentKeyStrokeMap");
|
||||
componentKeyStrokeMap.clear();
|
||||
Map containerMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "containerMap");
|
||||
Map<?, ?> containerMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "containerMap");
|
||||
containerMap.clear();
|
||||
}
|
||||
|
||||
static void doCheckForSettingsDamage(@NotNull CodeStyleSettings oldCodeStyleSettings, @NotNull CodeStyleSettings currentCodeStyleSettings) {
|
||||
final CodeInsightSettings settings = CodeInsightSettings.getInstance();
|
||||
// don't use method references here to make stack trace reading easier
|
||||
//noinspection Convert2MethodRef
|
||||
new RunAll()
|
||||
.append(() -> {
|
||||
try {
|
||||
checkCodeInsightSettingsEqual(defaultSettings, settings);
|
||||
}
|
||||
catch (AssertionError error) {
|
||||
CodeInsightSettings clean = new CodeInsightSettings();
|
||||
for (Field field : clean.getClass().getFields()) {
|
||||
try {
|
||||
ReflectionUtil.copyFieldValue(clean, settings, field);
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
})
|
||||
.append(() -> {
|
||||
currentCodeStyleSettings.getIndentOptions(StdFileTypes.JAVA);
|
||||
try {
|
||||
checkCodeStyleSettingsEqual(oldCodeStyleSettings, currentCodeStyleSettings);
|
||||
}
|
||||
finally {
|
||||
currentCodeStyleSettings.clearCodeStyleSettings();
|
||||
}
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Disposable getTestRootDisposable() {
|
||||
return myTestRootDisposable;
|
||||
@@ -248,13 +362,11 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
protected void runTest() throws Throwable {
|
||||
final Throwable[] throwables = new Throwable[1];
|
||||
|
||||
AtomicBoolean completed = new AtomicBoolean(false);
|
||||
Runnable runnable = () -> {
|
||||
try {
|
||||
//TestLoggerFactory.onTestStarted();
|
||||
TestLoggerFactory.onTestStarted();
|
||||
super.runTest();
|
||||
TestLoggerFactory.onTestFinished(true);
|
||||
completed.set(true);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
TestLoggerFactory.onTestFinished(false);
|
||||
@@ -277,9 +389,6 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
if (throwables[0] != null) {
|
||||
throw throwables[0];
|
||||
}
|
||||
if (!completed.get()) {
|
||||
throw new IllegalStateException("test didn't start");
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean shouldRunTest() {
|
||||
@@ -287,19 +396,18 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
|
||||
protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
|
||||
//IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
|
||||
//if (policy != null && !policy.runInDispatchThread()) {
|
||||
// runnable.run();
|
||||
//}
|
||||
//else {
|
||||
if (runInDispatchThread()) {
|
||||
EdtTestUtilKt.runInEdtAndWait(() -> {
|
||||
runnable.run();
|
||||
return null;
|
||||
});
|
||||
//}
|
||||
}
|
||||
else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
private void defaultRunBare() throws Throwable {
|
||||
protected void defaultRunBare() throws Throwable {
|
||||
Throwable exception = null;
|
||||
try {
|
||||
long setupStart = System.nanoTime();
|
||||
@@ -320,11 +428,17 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
logPerClassCost(teardownCost, TOTAL_TEARDOWN_COST_MILLIS);
|
||||
}
|
||||
catch (Throwable tearingDown) {
|
||||
if (exception == null) exception = tearingDown;
|
||||
else exception = new CompoundRuntimeException(Arrays.asList(exception, tearingDown));
|
||||
if (exception == null) {
|
||||
exception = tearingDown;
|
||||
}
|
||||
else {
|
||||
exception = new CompoundRuntimeException(Arrays.asList(exception, tearingDown));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (exception != null) throw exception;
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,7 +478,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
|
||||
if (runInDispatchThread()) {
|
||||
TestRunnerUtil.replaceIdeEventQueueSafely();
|
||||
com.intellij.testFramework.EdtTestUtil.runInEdtAndWait(this::defaultRunBare);
|
||||
EdtTestUtil.runInEdtAndWait(this::defaultRunBare);
|
||||
}
|
||||
else {
|
||||
defaultRunBare();
|
||||
@@ -372,13 +486,20 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
|
||||
protected boolean runInDispatchThread() {
|
||||
//IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
|
||||
//if (policy != null) {
|
||||
// return policy.runInDispatchThread();
|
||||
//}
|
||||
IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
|
||||
if (policy != null) {
|
||||
return policy.runInDispatchThread();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If you want a more shorter name than runInEdtAndWait.
|
||||
*/
|
||||
protected void edt(@NotNull ThrowableRunnable<Throwable> runnable) {
|
||||
EdtTestUtil.runInEdtAndWait(runnable);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String toString(@NotNull Iterable<?> collection) {
|
||||
if (!collection.iterator().hasNext()) {
|
||||
@@ -511,9 +632,20 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
|
||||
public static <T> void assertContainsOrdered(@NotNull Collection<? extends T> collection, @NotNull Collection<? extends T> expected) {
|
||||
ArrayList<T> copy = new ArrayList<>(collection);
|
||||
copy.retainAll(expected);
|
||||
assertOrderedEquals(toString(collection), copy, expected);
|
||||
PeekableIterator<T> expectedIt = new PeekableIteratorWrapper<>(expected.iterator());
|
||||
PeekableIterator<T> actualIt = new PeekableIteratorWrapper<>(collection.iterator());
|
||||
|
||||
while (actualIt.hasNext() && expectedIt.hasNext()) {
|
||||
T expectedElem = expectedIt.peek();
|
||||
T actualElem = actualIt.peek();
|
||||
if (expectedElem.equals(actualElem)) {
|
||||
expectedIt.next();
|
||||
}
|
||||
actualIt.next();
|
||||
}
|
||||
if (expectedIt.hasNext()) {
|
||||
throw new ComparisonFailure("", toString(expected), toString(collection));
|
||||
}
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
@@ -588,7 +720,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
if (collection.size() != checkers.length) {
|
||||
Assert.fail(toString(collection));
|
||||
}
|
||||
Set<Consumer<T>> checkerSet = new HashSet<>(Arrays.asList(checkers));
|
||||
Set<Consumer<T>> checkerSet = ContainerUtil.set(checkers);
|
||||
int i = 0;
|
||||
Throwable lastError = null;
|
||||
for (final T actual : collection) {
|
||||
@@ -763,7 +895,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
System.out.println("File " + filePath + " created.");
|
||||
}
|
||||
fileText = FileUtil.loadFile(new File(filePath), CharsetToolkit.UTF8_CHARSET);
|
||||
fileText = FileUtil.loadFile(new File(filePath), StandardCharsets.UTF_8);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
VfsTestUtil.overwriteTestData(filePath, actualText);
|
||||
@@ -780,14 +912,14 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
|
||||
protected static void clearFields(@NotNull Object test) throws IllegalAccessException {
|
||||
Class aClass = test.getClass();
|
||||
Class<?> aClass = test.getClass();
|
||||
while (aClass != null) {
|
||||
clearDeclaredFields(test, aClass);
|
||||
aClass = aClass.getSuperclass();
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearDeclaredFields(@NotNull Object test, @NotNull Class aClass) throws IllegalAccessException {
|
||||
public static void clearDeclaredFields(@NotNull Object test, @NotNull Class<?> aClass) throws IllegalAccessException {
|
||||
for (final Field field : aClass.getDeclaredFields()) {
|
||||
final String name = field.getDeclaringClass().getName();
|
||||
if (!name.startsWith("junit.framework.") && !name.startsWith("com.intellij.testFramework.")) {
|
||||
@@ -813,6 +945,14 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkCodeInsightSettingsEqual(@NotNull CodeInsightSettings oldSettings, @NotNull CodeInsightSettings settings) {
|
||||
if (!oldSettings.equals(settings)) {
|
||||
Element newS = new Element("temp");
|
||||
settings.writeExternal(newS);
|
||||
Assert.assertEquals("Code insight settings damaged", DEFAULT_SETTINGS_EXTERNALIZED, JDOMUtil.writeElement(newS));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPerformanceTest() {
|
||||
String testName = getName();
|
||||
String className = getClass().getSimpleName();
|
||||
@@ -839,6 +979,21 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
return name != null && (name.contains("Stress") || name.contains("Slow"));
|
||||
}
|
||||
|
||||
public static void doPostponedFormatting(@NotNull Project project) {
|
||||
DocumentUtil.writeInRunUndoTransparentAction(() -> {
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that code block throw corresponding exception.
|
||||
*
|
||||
* @param exceptionCase Block annotated with some exception type
|
||||
*/
|
||||
protected void assertException(@NotNull AbstractExceptionCase<?> exceptionCase) {
|
||||
assertException(exceptionCase, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that code block throw corresponding exception with expected error msg.
|
||||
@@ -852,6 +1007,42 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
assertExceptionOccurred(true, exceptionCase, expectedErrorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the code block throws an exception of the specified class.
|
||||
*
|
||||
* @param exceptionClass Expected exception type
|
||||
* @param runnable Block annotated with some exception type
|
||||
*/
|
||||
public static <T extends Throwable> void assertThrows(@NotNull Class<? extends Throwable> exceptionClass,
|
||||
@NotNull ThrowableRunnable<T> runnable) {
|
||||
assertThrows(exceptionClass, null, runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the code block throws an exception of the specified class with expected error msg.
|
||||
* If expected error message is null it will not be checked.
|
||||
*
|
||||
* @param exceptionClass Expected exception type
|
||||
* @param expectedErrorMsgPart expected error message, of any
|
||||
* @param runnable Block annotated with some exception type
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "SameParameterValue"})
|
||||
public static <T extends Throwable> void assertThrows(@NotNull Class<? extends Throwable> exceptionClass,
|
||||
@Nullable String expectedErrorMsgPart,
|
||||
@NotNull ThrowableRunnable<T> runnable) {
|
||||
assertExceptionOccurred(true, new AbstractExceptionCase() {
|
||||
@Override
|
||||
public Class<Throwable> getExpectedExceptionClass() {
|
||||
return (Class<Throwable>)exceptionClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tryClosure() throws Throwable {
|
||||
runnable.run();
|
||||
}
|
||||
}, expectedErrorMsgPart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that code block doesn't throw corresponding exception.
|
||||
*
|
||||
@@ -874,21 +1065,23 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
|
||||
private static <T extends Throwable> void assertExceptionOccurred(boolean shouldOccur,
|
||||
@NotNull AbstractExceptionCase<T> exceptionCase,
|
||||
String expectedErrorMsg) throws T {
|
||||
String expectedErrorMsgPart) throws T {
|
||||
boolean wasThrown = false;
|
||||
try {
|
||||
exceptionCase.tryClosure();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
Throwable cause = e;
|
||||
|
||||
if (shouldOccur) {
|
||||
wasThrown = true;
|
||||
final String errorMessage = exceptionCase.getAssertionErrorMessage();
|
||||
assertEquals(errorMessage, exceptionCase.getExpectedExceptionClass(), e.getClass());
|
||||
if (expectedErrorMsg != null) {
|
||||
assertEquals("Compare error messages", expectedErrorMsg, e.getMessage());
|
||||
assertEquals(errorMessage, exceptionCase.getExpectedExceptionClass(), cause.getClass());
|
||||
if (expectedErrorMsgPart != null) {
|
||||
assertTrue(cause.getMessage(), cause.getMessage().contains(expectedErrorMsgPart));
|
||||
}
|
||||
}
|
||||
else if (exceptionCase.getExpectedExceptionClass().equals(e.getClass())) {
|
||||
else if (exceptionCase.getExpectedExceptionClass().equals(cause.getClass())) {
|
||||
wasThrown = true;
|
||||
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
@@ -896,7 +1089,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
e.printStackTrace(System.out);
|
||||
|
||||
fail("Exception isn't expected here. Exception message: " + e.getMessage());
|
||||
fail("Exception isn't expected here. Exception message: " + cause.getMessage());
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
@@ -933,7 +1126,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
|
||||
public static void refreshRecursively(@NotNull VirtualFile file) {
|
||||
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
|
||||
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor<Void>() {
|
||||
@Override
|
||||
public boolean visitFile(@NotNull VirtualFile file) {
|
||||
file.getChildren();
|
||||
@@ -943,11 +1136,27 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
file.refresh(false, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile refreshAndFindFile(@NotNull final File file) {
|
||||
return UIUtil.invokeAndWaitIfNeeded(() -> LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file));
|
||||
}
|
||||
|
||||
public static void waitForAppLeakingThreads(long timeout, @NotNull TimeUnit timeUnit) {
|
||||
EdtTestUtil.runInEdtAndWait(() -> {
|
||||
Application app = ApplicationManager.getApplication();
|
||||
if (app != null && !app.isDisposed()) {
|
||||
FileBasedIndexImpl index = (FileBasedIndexImpl)app.getServiceIfCreated(FileBasedIndex.class);
|
||||
if (index != null) {
|
||||
index.getChangedFilesCollector().waitForVfsEventsExecuted(timeout, timeUnit);
|
||||
}
|
||||
|
||||
DocumentCommitThread commitThread = (DocumentCommitThread)app.getServiceIfCreated(DocumentCommitProcessor.class);
|
||||
if (commitThread != null) {
|
||||
commitThread.waitForAllCommits(timeout, timeUnit);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected class TestDisposable implements Disposable {
|
||||
private volatile boolean myDisposed;
|
||||
|
||||
@@ -968,5 +1177,5 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
String testName = getTestName(false);
|
||||
return KtUsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,972 @@
|
||||
/*
|
||||
* 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.test.testFramework;
|
||||
|
||||
import com.intellij.diagnostic.PerformanceWatcher;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.rt.execution.junit.FileComparisonFailure;
|
||||
import com.intellij.testFramework.*;
|
||||
import com.intellij.testFramework.exceptionCases.AbstractExceptionCase;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import com.intellij.util.lang.CompoundRuntimeException;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.Equality;
|
||||
import gnu.trove.THashSet;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.TestCase;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.test.IdeaSystemPropertiesForParallelRunConfigurator;
|
||||
import org.jetbrains.kotlin.testFramework.MockComponentManagerCreationTracer;
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker;
|
||||
import org.jetbrains.kotlin.types.FlexibleTypeImpl;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
public abstract class KtUsefulTestCase extends TestCase {
|
||||
public static final boolean IS_UNDER_TEAMCITY = System.getenv("TEAMCITY_VERSION") != null;
|
||||
private static final String TEMP_DIR_MARKER = "unitTest_";
|
||||
public static final boolean OVERWRITE_TESTDATA = Boolean.getBoolean("idea.tests.overwrite.data");
|
||||
|
||||
private static final String ORIGINAL_TEMP_DIR = FileUtil.getTempDirectory();
|
||||
|
||||
private static final Map<String, Long> TOTAL_SETUP_COST_MILLIS = new HashMap<>();
|
||||
private static final Map<String, Long> TOTAL_TEARDOWN_COST_MILLIS = new HashMap<>();
|
||||
|
||||
private Application application;
|
||||
|
||||
static {
|
||||
IdeaSystemPropertiesForParallelRunConfigurator.setProperties();
|
||||
//TODO: investigate and enable
|
||||
//IdeaForkJoinWorkerThreadFactory.setupPoisonFactory();
|
||||
Logger.setFactory(TestLoggerFactory.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected final Disposable myTestRootDisposable = new TestDisposable();
|
||||
|
||||
private static final String ourPathToKeep = null;
|
||||
private final List<String> myPathsToKeep = new ArrayList<>();
|
||||
|
||||
private File myTempDir;
|
||||
|
||||
static {
|
||||
// Radar #5755208: Command line Java applications need a way to launch without a Dock icon.
|
||||
System.setProperty("apple.awt.UIElement", "true");
|
||||
|
||||
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true;
|
||||
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = true;
|
||||
}
|
||||
|
||||
protected boolean shouldContainTempFiles() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
// -- KOTLIN ADDITIONAL START --
|
||||
application = ApplicationManager.getApplication();
|
||||
|
||||
if (application != null && application.isDisposed()) {
|
||||
MockComponentManagerCreationTracer.diagnoseDisposedButNotClearedApplication(application);
|
||||
}
|
||||
// -- KOTLIN ADDITIONAL END --
|
||||
|
||||
super.setUp();
|
||||
|
||||
if (shouldContainTempFiles()) {
|
||||
String testName = FileUtil.sanitizeFileName(getTestName(true));
|
||||
if (StringUtil.isEmptyOrSpaces(testName)) testName = "";
|
||||
testName = new File(testName).getName(); // in case the test name contains file separators
|
||||
myTempDir = FileUtil.createTempDirectory(TEMP_DIR_MARKER, testName, false);
|
||||
FileUtil.resetCanonicalTempPathCache(myTempDir.getPath());
|
||||
}
|
||||
|
||||
boolean isStressTest = isStressTest();
|
||||
ApplicationInfoImpl.setInStressTest(isStressTest);
|
||||
if (isPerformanceTest()) {
|
||||
Timings.getStatistics();
|
||||
}
|
||||
|
||||
// turn off Disposer debugging for performance tests
|
||||
Disposer.setDebugMode(!isStressTest);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
try {
|
||||
// don't use method references here to make stack trace reading easier
|
||||
//noinspection Convert2MethodRef
|
||||
new RunAll(
|
||||
() -> disposeRootDisposable(),
|
||||
() -> cleanupSwingDataStructures(),
|
||||
() -> cleanupDeleteOnExitHookList(),
|
||||
() -> Disposer.setDebugMode(true),
|
||||
() -> {
|
||||
if (shouldContainTempFiles()) {
|
||||
FileUtil.resetCanonicalTempPathCache(ORIGINAL_TEMP_DIR);
|
||||
if (hasTmpFilesToKeep()) {
|
||||
File[] files = myTempDir.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (!shouldKeepTmpFile(file)) {
|
||||
FileUtil.delete(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
FileUtil.delete(myTempDir);
|
||||
}
|
||||
}
|
||||
},
|
||||
() -> UIUtil.removeLeakingAppleListeners()
|
||||
).run();
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
// -- KOTLIN ADDITIONAL START --
|
||||
TestApplicationUtilKt.resetApplicationToNull(application);
|
||||
application = null;
|
||||
// -- KOTLIN ADDITIONAL END --
|
||||
}
|
||||
}
|
||||
|
||||
protected final void disposeRootDisposable() {
|
||||
Disposer.dispose(getTestRootDisposable());
|
||||
}
|
||||
|
||||
protected void addTmpFileToKeep(@NotNull File file) {
|
||||
myPathsToKeep.add(file.getPath());
|
||||
}
|
||||
|
||||
private boolean hasTmpFilesToKeep() {
|
||||
return ourPathToKeep != null && FileUtil.isAncestor(myTempDir.getPath(), ourPathToKeep, false) || !myPathsToKeep.isEmpty();
|
||||
}
|
||||
|
||||
private boolean shouldKeepTmpFile(@NotNull File file) {
|
||||
String path = file.getPath();
|
||||
if (FileUtil.pathsEqual(path, ourPathToKeep)) return true;
|
||||
for (String pathToKeep : myPathsToKeep) {
|
||||
if (FileUtil.pathsEqual(path, pathToKeep)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final Set<String> DELETE_ON_EXIT_HOOK_DOT_FILES;
|
||||
private static final Class DELETE_ON_EXIT_HOOK_CLASS;
|
||||
static {
|
||||
Class<?> aClass;
|
||||
try {
|
||||
aClass = Class.forName("java.io.DeleteOnExitHook");
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@SuppressWarnings("unchecked") Set<String> files = ReflectionUtil.getStaticFieldValue(aClass, Set.class, "files");
|
||||
DELETE_ON_EXIT_HOOK_CLASS = aClass;
|
||||
DELETE_ON_EXIT_HOOK_DOT_FILES = files;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SynchronizeOnThis")
|
||||
private static void cleanupDeleteOnExitHookList() {
|
||||
// try to reduce file set retained by java.io.DeleteOnExitHook
|
||||
List<String> list;
|
||||
synchronized (DELETE_ON_EXIT_HOOK_CLASS) {
|
||||
if (DELETE_ON_EXIT_HOOK_DOT_FILES.isEmpty()) return;
|
||||
list = new ArrayList<>(DELETE_ON_EXIT_HOOK_DOT_FILES);
|
||||
}
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
String path = list.get(i);
|
||||
File file = new File(path);
|
||||
if (file.delete() || !file.exists()) {
|
||||
synchronized (DELETE_ON_EXIT_HOOK_CLASS) {
|
||||
DELETE_ON_EXIT_HOOK_DOT_FILES.remove(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private static void cleanupSwingDataStructures() throws Exception {
|
||||
Object manager = ReflectionUtil.getDeclaredMethod(Class.forName("javax.swing.KeyboardManager"), "getCurrentManager").invoke(null);
|
||||
Map componentKeyStrokeMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "componentKeyStrokeMap");
|
||||
componentKeyStrokeMap.clear();
|
||||
Map containerMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "containerMap");
|
||||
containerMap.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Disposable getTestRootDisposable() {
|
||||
return myTestRootDisposable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
final Throwable[] throwables = new Throwable[1];
|
||||
|
||||
AtomicBoolean completed = new AtomicBoolean(false);
|
||||
Runnable runnable = () -> {
|
||||
try {
|
||||
//TestLoggerFactory.onTestStarted();
|
||||
super.runTest();
|
||||
TestLoggerFactory.onTestFinished(true);
|
||||
completed.set(true);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
TestLoggerFactory.onTestFinished(false);
|
||||
e.fillInStackTrace();
|
||||
throwables[0] = e.getTargetException();
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
TestLoggerFactory.onTestFinished(false);
|
||||
e.fillInStackTrace();
|
||||
throwables[0] = e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
TestLoggerFactory.onTestFinished(false);
|
||||
throwables[0] = e;
|
||||
}
|
||||
};
|
||||
|
||||
invokeTestRunnable(runnable);
|
||||
|
||||
if (throwables[0] != null) {
|
||||
throw throwables[0];
|
||||
}
|
||||
if (!completed.get()) {
|
||||
throw new IllegalStateException("test didn't start");
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean shouldRunTest() {
|
||||
return TestFrameworkUtil.canRunTest(getClass());
|
||||
}
|
||||
|
||||
protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
|
||||
//IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
|
||||
//if (policy != null && !policy.runInDispatchThread()) {
|
||||
// runnable.run();
|
||||
//}
|
||||
//else {
|
||||
EdtTestUtilKt.runInEdtAndWait(() -> {
|
||||
runnable.run();
|
||||
return null;
|
||||
});
|
||||
//}
|
||||
}
|
||||
|
||||
private void defaultRunBare() throws Throwable {
|
||||
Throwable exception = null;
|
||||
try {
|
||||
long setupStart = System.nanoTime();
|
||||
setUp();
|
||||
long setupCost = (System.nanoTime() - setupStart) / 1000000;
|
||||
logPerClassCost(setupCost, TOTAL_SETUP_COST_MILLIS);
|
||||
|
||||
runTest();
|
||||
}
|
||||
catch (Throwable running) {
|
||||
exception = running;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
long teardownStart = System.nanoTime();
|
||||
tearDown();
|
||||
long teardownCost = (System.nanoTime() - teardownStart) / 1000000;
|
||||
logPerClassCost(teardownCost, TOTAL_TEARDOWN_COST_MILLIS);
|
||||
}
|
||||
catch (Throwable tearingDown) {
|
||||
if (exception == null) exception = tearingDown;
|
||||
else exception = new CompoundRuntimeException(Arrays.asList(exception, tearingDown));
|
||||
}
|
||||
}
|
||||
if (exception != null) throw exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the setup cost grouped by test fixture class (superclass of the current test class).
|
||||
*
|
||||
* @param cost setup cost in milliseconds
|
||||
*/
|
||||
private void logPerClassCost(long cost, @NotNull Map<String, Long> costMap) {
|
||||
Class<?> superclass = getClass().getSuperclass();
|
||||
Long oldCost = costMap.get(superclass.getName());
|
||||
long newCost = oldCost == null ? cost : oldCost + cost;
|
||||
costMap.put(superclass.getName(), newCost);
|
||||
}
|
||||
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
static void logSetupTeardownCosts() {
|
||||
System.out.println("Setup costs");
|
||||
long totalSetup = 0;
|
||||
for (Map.Entry<String, Long> entry : TOTAL_SETUP_COST_MILLIS.entrySet()) {
|
||||
System.out.println(String.format(" %s: %d ms", entry.getKey(), entry.getValue()));
|
||||
totalSetup += entry.getValue();
|
||||
}
|
||||
System.out.println("Teardown costs");
|
||||
long totalTeardown = 0;
|
||||
for (Map.Entry<String, Long> entry : TOTAL_TEARDOWN_COST_MILLIS.entrySet()) {
|
||||
System.out.println(String.format(" %s: %d ms", entry.getKey(), entry.getValue()));
|
||||
totalTeardown += entry.getValue();
|
||||
}
|
||||
System.out.println(String.format("Total overhead: setup %d ms, teardown %d ms", totalSetup, totalTeardown));
|
||||
System.out.println(String.format("##teamcity[buildStatisticValue key='ideaTests.totalSetupMs' value='%d']", totalSetup));
|
||||
System.out.println(String.format("##teamcity[buildStatisticValue key='ideaTests.totalTeardownMs' value='%d']", totalTeardown));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runBare() throws Throwable {
|
||||
if (!shouldRunTest()) return;
|
||||
|
||||
if (runInDispatchThread()) {
|
||||
TestRunnerUtil.replaceIdeEventQueueSafely();
|
||||
com.intellij.testFramework.EdtTestUtil.runInEdtAndWait(this::defaultRunBare);
|
||||
}
|
||||
else {
|
||||
defaultRunBare();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean runInDispatchThread() {
|
||||
//IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
|
||||
//if (policy != null) {
|
||||
// return policy.runInDispatchThread();
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String toString(@NotNull Iterable<?> collection) {
|
||||
if (!collection.iterator().hasNext()) {
|
||||
return "<empty>";
|
||||
}
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (final Object o : collection) {
|
||||
if (o instanceof THashSet) {
|
||||
builder.append(new TreeSet<>((THashSet<?>)o));
|
||||
}
|
||||
else {
|
||||
builder.append(o);
|
||||
}
|
||||
builder.append('\n');
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertOrderedEquals(@NotNull T[] actual, @NotNull T... expected) {
|
||||
assertOrderedEquals(Arrays.asList(actual), expected);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertOrderedEquals(@NotNull Iterable<? extends T> actual, @NotNull T... expected) {
|
||||
assertOrderedEquals("", actual, expected);
|
||||
}
|
||||
|
||||
public static void assertOrderedEquals(@NotNull byte[] actual, @NotNull byte[] expected) {
|
||||
assertEquals(expected.length, actual.length);
|
||||
for (int i = 0; i < actual.length; i++) {
|
||||
byte a = actual[i];
|
||||
byte e = expected[i];
|
||||
assertEquals("not equals at index: "+i, e, a);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertOrderedEquals(@NotNull int[] actual, @NotNull int[] expected) {
|
||||
if (actual.length != expected.length) {
|
||||
fail("Expected size: "+expected.length+"; actual: "+actual.length+"\nexpected: "+Arrays.toString(expected)+"\nactual : "+Arrays.toString(actual));
|
||||
}
|
||||
for (int i = 0; i < actual.length; i++) {
|
||||
int a = actual[i];
|
||||
int e = expected[i];
|
||||
assertEquals("not equals at index: "+i, e, a);
|
||||
}
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertOrderedEquals(@NotNull String errorMsg, @NotNull Iterable<? extends T> actual, @NotNull T... expected) {
|
||||
assertOrderedEquals(errorMsg, actual, Arrays.asList(expected));
|
||||
}
|
||||
|
||||
public static <T> void assertOrderedEquals(@NotNull Iterable<? extends T> actual, @NotNull Iterable<? extends T> expected) {
|
||||
assertOrderedEquals("", actual, expected);
|
||||
}
|
||||
|
||||
public static <T> void assertOrderedEquals(@NotNull String errorMsg,
|
||||
@NotNull Iterable<? extends T> actual,
|
||||
@NotNull Iterable<? extends T> expected) {
|
||||
//noinspection unchecked
|
||||
assertOrderedEquals(errorMsg, actual, expected, Equality.CANONICAL);
|
||||
}
|
||||
|
||||
public static <T> void assertOrderedEquals(@NotNull String errorMsg,
|
||||
@NotNull Iterable<? extends T> actual,
|
||||
@NotNull Iterable<? extends T> expected,
|
||||
@NotNull Equality<? super T> comparator) {
|
||||
if (!equals(actual, expected, comparator)) {
|
||||
String expectedString = toString(expected);
|
||||
String actualString = toString(actual);
|
||||
Assert.assertEquals(errorMsg, expectedString, actualString);
|
||||
Assert.fail("Warning! 'toString' does not reflect the difference.\nExpected: " + expectedString + "\nActual: " + actualString);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> boolean equals(@NotNull Iterable<? extends T> a1,
|
||||
@NotNull Iterable<? extends T> a2,
|
||||
@NotNull Equality<? super T> comparator) {
|
||||
Iterator<? extends T> it1 = a1.iterator();
|
||||
Iterator<? extends T> it2 = a2.iterator();
|
||||
while (it1.hasNext() || it2.hasNext()) {
|
||||
if (!it1.hasNext() || !it2.hasNext()) return false;
|
||||
if (!comparator.equals(it1.next(), it2.next())) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertOrderedCollection(@NotNull T[] collection, @NotNull Consumer<T>... checkers) {
|
||||
assertOrderedCollection(Arrays.asList(collection), checkers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks {@code actual} contains same elements (in {@link #equals(Object)} meaning) as {@code expected} irrespective of their order
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <T> void assertSameElements(@NotNull T[] actual, @NotNull T... expected) {
|
||||
assertSameElements(Arrays.asList(actual), expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks {@code actual} contains same elements (in {@link #equals(Object)} meaning) as {@code expected} irrespective of their order
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <T> void assertSameElements(@NotNull Collection<? extends T> actual, @NotNull T... expected) {
|
||||
assertSameElements(actual, Arrays.asList(expected));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks {@code actual} contains same elements (in {@link #equals(Object)} meaning) as {@code expected} irrespective of their order
|
||||
*/
|
||||
public static <T> void assertSameElements(@NotNull Collection<? extends T> actual, @NotNull Collection<? extends T> expected) {
|
||||
assertSameElements("", actual, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks {@code actual} contains same elements (in {@link #equals(Object)} meaning) as {@code expected} irrespective of their order
|
||||
*/
|
||||
public static <T> void assertSameElements(@NotNull String message, @NotNull Collection<? extends T> actual, @NotNull Collection<? extends T> expected) {
|
||||
if (actual.size() != expected.size() || !new HashSet<>(expected).equals(new HashSet<T>(actual))) {
|
||||
Assert.assertEquals(message, new HashSet<>(expected), new HashSet<T>(actual));
|
||||
}
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertContainsOrdered(@NotNull Collection<? extends T> collection, @NotNull T... expected) {
|
||||
assertContainsOrdered(collection, Arrays.asList(expected));
|
||||
}
|
||||
|
||||
public static <T> void assertContainsOrdered(@NotNull Collection<? extends T> collection, @NotNull Collection<? extends T> expected) {
|
||||
ArrayList<T> copy = new ArrayList<>(collection);
|
||||
copy.retainAll(expected);
|
||||
assertOrderedEquals(toString(collection), copy, expected);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertContainsElements(@NotNull Collection<? extends T> collection, @NotNull T... expected) {
|
||||
assertContainsElements(collection, Arrays.asList(expected));
|
||||
}
|
||||
|
||||
public static <T> void assertContainsElements(@NotNull Collection<? extends T> collection, @NotNull Collection<? extends T> expected) {
|
||||
ArrayList<T> copy = new ArrayList<>(collection);
|
||||
copy.retainAll(expected);
|
||||
assertSameElements(toString(collection), copy, expected);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String toString(@NotNull Object[] collection, @NotNull String separator) {
|
||||
return toString(Arrays.asList(collection), separator);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertDoesntContain(@NotNull Collection<? extends T> collection, @NotNull T... notExpected) {
|
||||
assertDoesntContain(collection, Arrays.asList(notExpected));
|
||||
}
|
||||
|
||||
public static <T> void assertDoesntContain(@NotNull Collection<? extends T> collection, @NotNull Collection<? extends T> notExpected) {
|
||||
ArrayList<T> expected = new ArrayList<>(collection);
|
||||
expected.removeAll(notExpected);
|
||||
assertSameElements(collection, expected);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String toString(@NotNull Collection<?> collection, @NotNull String separator) {
|
||||
List<String> list = ContainerUtil.map2List(collection, String::valueOf);
|
||||
Collections.sort(list);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean flag = false;
|
||||
for (final String o : list) {
|
||||
if (flag) {
|
||||
builder.append(separator);
|
||||
}
|
||||
builder.append(o);
|
||||
flag = true;
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertOrderedCollection(@NotNull Collection<? extends T> collection, @NotNull Consumer<T>... checkers) {
|
||||
if (collection.size() != checkers.length) {
|
||||
Assert.fail(toString(collection));
|
||||
}
|
||||
int i = 0;
|
||||
for (final T actual : collection) {
|
||||
try {
|
||||
checkers[i].consume(actual);
|
||||
}
|
||||
catch (AssertionFailedError e) {
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
System.out.println(i + ": " + actual);
|
||||
throw e;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertUnorderedCollection(@NotNull T[] collection, @NotNull Consumer<T>... checkers) {
|
||||
assertUnorderedCollection(Arrays.asList(collection), checkers);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertUnorderedCollection(@NotNull Collection<? extends T> collection, @NotNull Consumer<T>... checkers) {
|
||||
if (collection.size() != checkers.length) {
|
||||
Assert.fail(toString(collection));
|
||||
}
|
||||
Set<Consumer<T>> checkerSet = new HashSet<>(Arrays.asList(checkers));
|
||||
int i = 0;
|
||||
Throwable lastError = null;
|
||||
for (final T actual : collection) {
|
||||
boolean flag = true;
|
||||
for (final Consumer<T> condition : checkerSet) {
|
||||
Throwable error = accepts(condition, actual);
|
||||
if (error == null) {
|
||||
checkerSet.remove(condition);
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
lastError = error;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
//noinspection ConstantConditions,CallToPrintStackTrace
|
||||
lastError.printStackTrace();
|
||||
Assert.fail("Incorrect element(" + i + "): " + actual);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> Throwable accepts(@NotNull Consumer<? super T> condition, final T actual) {
|
||||
try {
|
||||
condition.consume(actual);
|
||||
return null;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
@Contract("null, _ -> fail")
|
||||
@NotNull
|
||||
public static <T> T assertInstanceOf(Object o, @NotNull Class<T> aClass) {
|
||||
Assert.assertNotNull("Expected instance of: " + aClass.getName() + " actual: " + null, o);
|
||||
Assert.assertTrue("Expected instance of: " + aClass.getName() + " actual: " + o.getClass().getName(), aClass.isInstance(o));
|
||||
@SuppressWarnings("unchecked") T t = (T)o;
|
||||
return t;
|
||||
}
|
||||
|
||||
public static <T> T assertOneElement(@NotNull Collection<? extends T> collection) {
|
||||
Iterator<? extends T> iterator = collection.iterator();
|
||||
String toString = toString(collection);
|
||||
Assert.assertTrue(toString, iterator.hasNext());
|
||||
T t = iterator.next();
|
||||
Assert.assertFalse(toString, iterator.hasNext());
|
||||
return t;
|
||||
}
|
||||
|
||||
public static <T> T assertOneElement(@NotNull T[] ts) {
|
||||
Assert.assertEquals(Arrays.asList(ts).toString(), 1, ts.length);
|
||||
return ts[0];
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> void assertOneOf(T value, @NotNull T... values) {
|
||||
for (T v : values) {
|
||||
if (Objects.equals(value, v)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Assert.fail(value + " should be equal to one of " + Arrays.toString(values));
|
||||
}
|
||||
|
||||
public static void printThreadDump() {
|
||||
PerformanceWatcher.dumpThreadsToConsole("Thread dump:");
|
||||
}
|
||||
|
||||
public static void assertEmpty(@NotNull Object[] array) {
|
||||
assertOrderedEquals(array);
|
||||
}
|
||||
|
||||
public static void assertNotEmpty(final Collection<?> collection) {
|
||||
assertNotNull(collection);
|
||||
assertFalse(collection.isEmpty());
|
||||
}
|
||||
|
||||
public static void assertEmpty(@NotNull Collection<?> collection) {
|
||||
assertEmpty(collection.toString(), collection);
|
||||
}
|
||||
|
||||
public static void assertNullOrEmpty(@Nullable Collection<?> collection) {
|
||||
if (collection == null) return;
|
||||
assertEmpty("", collection);
|
||||
}
|
||||
|
||||
public static void assertEmpty(final String s) {
|
||||
assertTrue(s, StringUtil.isEmpty(s));
|
||||
}
|
||||
|
||||
public static <T> void assertEmpty(@NotNull String errorMsg, @NotNull Collection<? extends T> collection) {
|
||||
assertOrderedEquals(errorMsg, collection, Collections.emptyList());
|
||||
}
|
||||
|
||||
public static void assertSize(int expectedSize, @NotNull Object[] array) {
|
||||
if (array.length != expectedSize) {
|
||||
assertEquals(toString(Arrays.asList(array)), expectedSize, array.length);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertSize(int expectedSize, @NotNull Collection<?> c) {
|
||||
if (c.size() != expectedSize) {
|
||||
assertEquals(toString(c), expectedSize, c.size());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected <T extends Disposable> T disposeOnTearDown(@NotNull T disposable) {
|
||||
Disposer.register(getTestRootDisposable(), disposable);
|
||||
return disposable;
|
||||
}
|
||||
|
||||
public static void assertSameLines(@NotNull String expected, @NotNull String actual) {
|
||||
assertSameLines(null, expected, actual);
|
||||
}
|
||||
|
||||
public static void assertSameLines(@Nullable String message, @NotNull String expected, @NotNull String actual) {
|
||||
String expectedText = StringUtil.convertLineSeparators(expected.trim());
|
||||
String actualText = StringUtil.convertLineSeparators(actual.trim());
|
||||
Assert.assertEquals(message, expectedText, actualText);
|
||||
}
|
||||
|
||||
public static void assertExists(@NotNull File file){
|
||||
assertTrue("File should exist " + file, file.exists());
|
||||
}
|
||||
|
||||
public static void assertDoesntExist(@NotNull File file){
|
||||
assertFalse("File should not exist " + file, file.exists());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String getTestName(boolean lowercaseFirstLetter) {
|
||||
return getTestName(getName(), lowercaseFirstLetter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getTestName(@Nullable String name, boolean lowercaseFirstLetter) {
|
||||
return name == null ? "" : PlatformTestUtil.getTestName(name, lowercaseFirstLetter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String getTestDirectoryName() {
|
||||
final String testName = getTestName(true);
|
||||
return testName.replaceAll("_.*", "");
|
||||
}
|
||||
|
||||
public static void assertSameLinesWithFile(@NotNull String filePath, @NotNull String actualText) {
|
||||
assertSameLinesWithFile(filePath, actualText, true);
|
||||
}
|
||||
|
||||
public static void assertSameLinesWithFile(@NotNull String filePath,
|
||||
@NotNull String actualText,
|
||||
@NotNull Supplier<String> messageProducer) {
|
||||
assertSameLinesWithFile(filePath, actualText, true, messageProducer);
|
||||
}
|
||||
|
||||
public static void assertSameLinesWithFile(@NotNull String filePath, @NotNull String actualText, boolean trimBeforeComparing) {
|
||||
assertSameLinesWithFile(filePath, actualText, trimBeforeComparing, null);
|
||||
}
|
||||
|
||||
public static void assertSameLinesWithFile(@NotNull String filePath,
|
||||
@NotNull String actualText,
|
||||
boolean trimBeforeComparing,
|
||||
@Nullable Supplier<String> messageProducer) {
|
||||
String fileText;
|
||||
try {
|
||||
if (OVERWRITE_TESTDATA) {
|
||||
VfsTestUtil.overwriteTestData(filePath, actualText);
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
System.out.println("File " + filePath + " created.");
|
||||
}
|
||||
fileText = FileUtil.loadFile(new File(filePath), CharsetToolkit.UTF8_CHARSET);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
VfsTestUtil.overwriteTestData(filePath, actualText);
|
||||
throw new AssertionFailedError("No output text found. File " + filePath + " created.");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String expected = StringUtil.convertLineSeparators(trimBeforeComparing ? fileText.trim() : fileText);
|
||||
String actual = StringUtil.convertLineSeparators(trimBeforeComparing ? actualText.trim() : actualText);
|
||||
if (!Comparing.equal(expected, actual)) {
|
||||
throw new FileComparisonFailure(messageProducer == null ? null : messageProducer.get(), expected, actual, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void clearFields(@NotNull Object test) throws IllegalAccessException {
|
||||
Class aClass = test.getClass();
|
||||
while (aClass != null) {
|
||||
clearDeclaredFields(test, aClass);
|
||||
aClass = aClass.getSuperclass();
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearDeclaredFields(@NotNull Object test, @NotNull Class aClass) throws IllegalAccessException {
|
||||
for (final Field field : aClass.getDeclaredFields()) {
|
||||
final String name = field.getDeclaringClass().getName();
|
||||
if (!name.startsWith("junit.framework.") && !name.startsWith("com.intellij.testFramework.")) {
|
||||
final int modifiers = field.getModifiers();
|
||||
if ((modifiers & Modifier.FINAL) == 0 && (modifiers & Modifier.STATIC) == 0 && !field.getType().isPrimitive()) {
|
||||
field.setAccessible(true);
|
||||
field.set(test, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkCodeStyleSettingsEqual(@NotNull CodeStyleSettings expected, @NotNull CodeStyleSettings settings) {
|
||||
if (!expected.equals(settings)) {
|
||||
Element oldS = new Element("temp");
|
||||
expected.writeExternal(oldS);
|
||||
Element newS = new Element("temp");
|
||||
settings.writeExternal(newS);
|
||||
|
||||
String newString = JDOMUtil.writeElement(newS);
|
||||
String oldString = JDOMUtil.writeElement(oldS);
|
||||
Assert.assertEquals("Code style settings damaged", oldString, newString);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPerformanceTest() {
|
||||
String testName = getName();
|
||||
String className = getClass().getSimpleName();
|
||||
return TestFrameworkUtil.isPerformanceTest(testName, className);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true for a test which performs A LOT of computations.
|
||||
* Such test should typically avoid performing expensive checks, e.g. data structure consistency complex validations.
|
||||
* If you want your test to be treated as "Stress", please mention one of these words in its name: "Stress", "Slow".
|
||||
* For example: {@code public void testStressPSIFromDifferentThreads()}
|
||||
*/
|
||||
public boolean isStressTest() {
|
||||
return isStressTest(getName(), getClass().getName());
|
||||
}
|
||||
|
||||
private static boolean isStressTest(String testName, String className) {
|
||||
return TestFrameworkUtil.isPerformanceTest(testName, className) ||
|
||||
containsStressWords(testName) ||
|
||||
containsStressWords(className);
|
||||
}
|
||||
|
||||
private static boolean containsStressWords(@Nullable String name) {
|
||||
return name != null && (name.contains("Stress") || name.contains("Slow"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks that code block throw corresponding exception with expected error msg.
|
||||
* If expected error message is null it will not be checked.
|
||||
*
|
||||
* @param exceptionCase Block annotated with some exception type
|
||||
* @param expectedErrorMsg expected error message
|
||||
*/
|
||||
protected void assertException(@NotNull AbstractExceptionCase exceptionCase, @Nullable String expectedErrorMsg) {
|
||||
//noinspection unchecked
|
||||
assertExceptionOccurred(true, exceptionCase, expectedErrorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that code block doesn't throw corresponding exception.
|
||||
*
|
||||
* @param exceptionCase Block annotated with some exception type
|
||||
*/
|
||||
protected <T extends Throwable> void assertNoException(@NotNull AbstractExceptionCase<T> exceptionCase) throws T {
|
||||
assertExceptionOccurred(false, exceptionCase, null);
|
||||
}
|
||||
|
||||
protected void assertNoThrowable(@NotNull Runnable closure) {
|
||||
String throwableName = null;
|
||||
try {
|
||||
closure.run();
|
||||
}
|
||||
catch (Throwable thr) {
|
||||
throwableName = thr.getClass().getName();
|
||||
}
|
||||
assertNull(throwableName);
|
||||
}
|
||||
|
||||
private static <T extends Throwable> void assertExceptionOccurred(boolean shouldOccur,
|
||||
@NotNull AbstractExceptionCase<T> exceptionCase,
|
||||
String expectedErrorMsg) throws T {
|
||||
boolean wasThrown = false;
|
||||
try {
|
||||
exceptionCase.tryClosure();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if (shouldOccur) {
|
||||
wasThrown = true;
|
||||
final String errorMessage = exceptionCase.getAssertionErrorMessage();
|
||||
assertEquals(errorMessage, exceptionCase.getExpectedExceptionClass(), e.getClass());
|
||||
if (expectedErrorMsg != null) {
|
||||
assertEquals("Compare error messages", expectedErrorMsg, e.getMessage());
|
||||
}
|
||||
}
|
||||
else if (exceptionCase.getExpectedExceptionClass().equals(e.getClass())) {
|
||||
wasThrown = true;
|
||||
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
System.out.println();
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
e.printStackTrace(System.out);
|
||||
|
||||
fail("Exception isn't expected here. Exception message: " + e.getMessage());
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (shouldOccur && !wasThrown) {
|
||||
fail(exceptionCase.getAssertionErrorMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean annotatedWith(@NotNull Class<? extends Annotation> annotationClass) {
|
||||
Class<?> aClass = getClass();
|
||||
String methodName = "test" + getTestName(false);
|
||||
boolean methodChecked = false;
|
||||
while (aClass != null && aClass != Object.class) {
|
||||
if (aClass.getAnnotation(annotationClass) != null) return true;
|
||||
if (!methodChecked) {
|
||||
Method method = ReflectionUtil.getDeclaredMethod(aClass, methodName);
|
||||
if (method != null) {
|
||||
if (method.getAnnotation(annotationClass) != null) return true;
|
||||
methodChecked = true;
|
||||
}
|
||||
}
|
||||
aClass = aClass.getSuperclass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String getHomePath() {
|
||||
return PathManager.getHomePath().replace(File.separatorChar, '/');
|
||||
}
|
||||
|
||||
public static void refreshRecursively(@NotNull VirtualFile file) {
|
||||
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
|
||||
@Override
|
||||
public boolean visitFile(@NotNull VirtualFile file) {
|
||||
file.getChildren();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
file.refresh(false, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile refreshAndFindFile(@NotNull final File file) {
|
||||
return UIUtil.invokeAndWaitIfNeeded(() -> LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file));
|
||||
}
|
||||
|
||||
protected class TestDisposable implements Disposable {
|
||||
private volatile boolean myDisposed;
|
||||
|
||||
public TestDisposable() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
myDisposed = true;
|
||||
}
|
||||
|
||||
public boolean isDisposed() {
|
||||
return myDisposed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String testName = getTestName(false);
|
||||
return KtUsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -7,8 +7,11 @@ val propertiesFile: File = File(scriptDirectory , "versions.properties")
|
||||
FileReader(propertiesFile).use {
|
||||
val properties = Properties()
|
||||
properties.load(it)
|
||||
properties.forEach { (k, v) ->
|
||||
extra[k.toString()] = v
|
||||
properties.forEach { (rawKey, value) ->
|
||||
val key = rawKey.toString()
|
||||
if (!extra.has(key)) {
|
||||
extra[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
versions.intellijSdk=193.6494.35
|
||||
versions.intellijSdk=202.0.1
|
||||
versions.androidBuildTools=r23.0.1
|
||||
versions.idea.NodeJS=181.3494.12
|
||||
versions.idea.NodeJS=193.6494.7
|
||||
versions.jar.asm-all=7.0.1
|
||||
versions.jar.guava=27.1-jre
|
||||
versions.jar.guava=28.2-jre
|
||||
versions.jar.groovy-all=2.4.17
|
||||
versions.jar.lombok-ast=0.2.3
|
||||
versions.jar.swingx-core=1.6.2-2
|
||||
versions.jar.kxml2=2.3.0
|
||||
versions.jar.streamex=0.6.8
|
||||
versions.jar.gson=2.8.5
|
||||
versions.jar.streamex=0.7.2
|
||||
versions.jar.gson=2.8.6
|
||||
versions.jar.oro=2.0.8
|
||||
versions.jar.picocontainer=1.2
|
||||
versions.jar.serviceMessages=2019.1.4
|
||||
versions.jar.lz4-java=1.6.0
|
||||
versions.jar.lz4-java=1.7.1
|
||||
ignore.jar.snappy-in-java=true
|
||||
versions.gradle-api=4.5.1
|
||||
versions.shadow=5.2.0
|
||||
18
gradle/versions.properties.193
Normal file
18
gradle/versions.properties.193
Normal file
@@ -0,0 +1,18 @@
|
||||
versions.intellijSdk=193.6494.35
|
||||
versions.androidBuildTools=r23.0.1
|
||||
versions.idea.NodeJS=181.3494.12
|
||||
versions.jar.asm-all=7.0.1
|
||||
versions.jar.guava=27.1-jre
|
||||
versions.jar.groovy-all=2.4.17
|
||||
versions.jar.lombok-ast=0.2.3
|
||||
versions.jar.swingx-core=1.6.2-2
|
||||
versions.jar.kxml2=2.3.0
|
||||
versions.jar.streamex=0.6.8
|
||||
versions.jar.gson=2.8.5
|
||||
versions.jar.oro=2.0.8
|
||||
versions.jar.picocontainer=1.2
|
||||
versions.jar.serviceMessages=2019.1.4
|
||||
versions.jar.lz4-java=1.6.0
|
||||
ignore.jar.snappy-in-java=true
|
||||
versions.gradle-api=4.5.1
|
||||
versions.shadow=5.2.0
|
||||
@@ -95,7 +95,7 @@ dependencies {
|
||||
|
||||
compileOnly(commonDep("org.jetbrains", "markdown"))
|
||||
compileOnly(commonDep("com.google.code.findbugs", "jsr305"))
|
||||
if (Platform[201].orHigher()) {
|
||||
if (Platform[201]()) {
|
||||
compileOnly(intellijPluginDep("platform-langInjection"))
|
||||
} else {
|
||||
compileOnly(intellijPluginDep("IntelliLang"))
|
||||
@@ -149,7 +149,7 @@ dependencies {
|
||||
testRuntime(project(it))
|
||||
}
|
||||
|
||||
testCompile(intellijPluginDep(if (Platform[201].orHigher()) "platform-langInjection" else "IntelliLang"))
|
||||
testCompile(intellijPluginDep(if (Platform[201]()) "platform-langInjection" else "IntelliLang"))
|
||||
testCompile(intellijPluginDep("copyright"))
|
||||
testCompile(intellijPluginDep("properties"))
|
||||
testCompile(intellijPluginDep("java-i18n"))
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.util
|
||||
|
||||
import com.intellij.AbstractBundle
|
||||
import com.intellij.DynamicBundle
|
||||
|
||||
abstract class AbstractKotlinBundle protected constructor(pathToBundle: String) : AbstractBundle(pathToBundle) {
|
||||
abstract class AbstractKotlinBundle protected constructor(pathToBundle: String) : DynamicBundle(pathToBundle) {
|
||||
protected fun String.withHtml(): String = "<html>$this</html>"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* 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.util
|
||||
|
||||
import com.intellij.AbstractBundle
|
||||
|
||||
abstract class AbstractKotlinBundle protected constructor(pathToBundle: String) : AbstractBundle(pathToBundle) {
|
||||
protected fun String.withHtml(): String = "<html>$this</html>"
|
||||
}
|
||||
@@ -9,6 +9,6 @@ import com.intellij.psi.PsiMethod
|
||||
import com.intellij.util.Processor
|
||||
|
||||
// BUNCH 193
|
||||
typealias StringProcessor = Processor<String>
|
||||
typealias PsiMethodProcessor = Processor<PsiMethod>
|
||||
typealias StringProcessor = Processor<in String>
|
||||
typealias PsiMethodProcessor = Processor<in PsiMethod>
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* 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.idea.caches
|
||||
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.util.Processor
|
||||
|
||||
// BUNCH 193
|
||||
typealias StringProcessor = Processor<String>
|
||||
typealias PsiMethodProcessor = Processor<PsiMethod>
|
||||
|
||||
@@ -8,8 +8,9 @@ package org.jetbrains.kotlin.idea.highlighter
|
||||
import com.intellij.codeInsight.intention.EmptyIntentionAction
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.lang.annotation.Annotation
|
||||
import com.intellij.lang.annotation.AnnotationBuilder
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.util.TextRange
|
||||
@@ -31,53 +32,43 @@ class AnnotationPresentationInfo(
|
||||
for (range in ranges) {
|
||||
for (diagnostic in diagnostics) {
|
||||
val fixes = fixesMap[diagnostic]
|
||||
val annotation = create(diagnostic, range, holder)
|
||||
|
||||
fixes.forEach {
|
||||
when (it) {
|
||||
is KotlinUniversalQuickFix -> annotation.registerUniversalFix(it, null, null)
|
||||
is IntentionAction -> annotation.registerFix(it)
|
||||
create(diagnostic, range, holder) { annotation ->
|
||||
fixes.forEach {
|
||||
when (it) {
|
||||
is KotlinUniversalQuickFix -> annotation.newFix(it).universal().registerFix()
|
||||
is IntentionAction -> annotation.newFix(it).registerFix()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (diagnostic.severity == Severity.WARNING) {
|
||||
annotation.problemGroup = KotlinSuppressableWarningProblemGroup(diagnostic.factory)
|
||||
if (diagnostic.severity == Severity.WARNING) {
|
||||
annotation.problemGroup(KotlinSuppressableWarningProblemGroup(diagnostic.factory))
|
||||
|
||||
if (fixes.isEmpty()) {
|
||||
// if there are no quick fixes we need to register an EmptyIntentionAction to enable 'suppress' actions
|
||||
annotation.registerFix(EmptyIntentionAction(diagnostic.factory.name))
|
||||
if (fixes.isEmpty()) {
|
||||
// if there are no quick fixes we need to register an EmptyIntentionAction to enable 'suppress' actions
|
||||
annotation.newFix(EmptyIntentionAction(diagnostic.factory.name)).registerFix()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun create(diagnostic: Diagnostic, range: TextRange, holder: AnnotationHolder): Annotation {
|
||||
val defaultMessage = nonDefaultMessage ?: getDefaultMessage(diagnostic)
|
||||
|
||||
val annotation = when (diagnostic.severity) {
|
||||
Severity.ERROR -> holder.createErrorAnnotation(range, defaultMessage)
|
||||
Severity.WARNING -> {
|
||||
if (highlightType == ProblemHighlightType.WEAK_WARNING) {
|
||||
holder.createWeakWarningAnnotation(range, defaultMessage)
|
||||
} else {
|
||||
holder.createWarningAnnotation(range, defaultMessage)
|
||||
}
|
||||
}
|
||||
Severity.INFO -> holder.createInfoAnnotation(range, defaultMessage)
|
||||
private fun create(diagnostic: Diagnostic, range: TextRange, holder: AnnotationHolder, consumer: (AnnotationBuilder) -> Unit) {
|
||||
val severity = when (diagnostic.severity) {
|
||||
Severity.ERROR -> HighlightSeverity.ERROR
|
||||
Severity.WARNING -> if (highlightType == ProblemHighlightType.WEAK_WARNING) {
|
||||
HighlightSeverity.WEAK_WARNING
|
||||
} else HighlightSeverity.WARNING
|
||||
Severity.INFO -> HighlightSeverity.WEAK_WARNING
|
||||
}
|
||||
|
||||
annotation.tooltip = getMessage(diagnostic)
|
||||
|
||||
if (highlightType != null) {
|
||||
annotation.highlightType = highlightType
|
||||
}
|
||||
|
||||
if (textAttributes != null) {
|
||||
annotation.textAttributes = textAttributes
|
||||
}
|
||||
|
||||
return annotation
|
||||
holder.newAnnotation(severity, nonDefaultMessage ?: getDefaultMessage(diagnostic))
|
||||
.range(range)
|
||||
.tooltip(getMessage(diagnostic))
|
||||
.also { builder -> highlightType?.let { builder.highlightType(it) } }
|
||||
.also { builder -> textAttributes?.let { builder.textAttributes(it) } }
|
||||
.also { consumer(it) }
|
||||
.create()
|
||||
}
|
||||
|
||||
private fun getMessage(diagnostic: Diagnostic): String {
|
||||
@@ -103,4 +94,5 @@ class AnnotationPresentationInfo(
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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.idea.highlighter
|
||||
|
||||
import com.intellij.codeInsight.intention.EmptyIntentionAction
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.lang.annotation.Annotation
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import com.intellij.xml.util.XmlStringUtil
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.idea.inspections.KotlinUniversalQuickFix
|
||||
|
||||
class AnnotationPresentationInfo(
|
||||
val ranges: List<TextRange>,
|
||||
val nonDefaultMessage: String? = null,
|
||||
val highlightType: ProblemHighlightType? = null,
|
||||
val textAttributes: TextAttributesKey? = null
|
||||
) {
|
||||
|
||||
fun processDiagnostics(holder: AnnotationHolder, diagnostics: List<Diagnostic>, fixesMap: MultiMap<Diagnostic, IntentionAction>) {
|
||||
for (range in ranges) {
|
||||
for (diagnostic in diagnostics) {
|
||||
val fixes = fixesMap[diagnostic]
|
||||
val annotation = create(diagnostic, range, holder)
|
||||
|
||||
fixes.forEach {
|
||||
when (it) {
|
||||
is KotlinUniversalQuickFix -> annotation.registerUniversalFix(it, null, null)
|
||||
is IntentionAction -> annotation.registerFix(it)
|
||||
}
|
||||
}
|
||||
|
||||
if (diagnostic.severity == Severity.WARNING) {
|
||||
annotation.problemGroup = KotlinSuppressableWarningProblemGroup(diagnostic.factory)
|
||||
|
||||
if (fixes.isEmpty()) {
|
||||
// if there are no quick fixes we need to register an EmptyIntentionAction to enable 'suppress' actions
|
||||
annotation.registerFix(EmptyIntentionAction(diagnostic.factory.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun create(diagnostic: Diagnostic, range: TextRange, holder: AnnotationHolder): Annotation {
|
||||
val defaultMessage = nonDefaultMessage ?: getDefaultMessage(diagnostic)
|
||||
|
||||
val annotation = when (diagnostic.severity) {
|
||||
Severity.ERROR -> holder.createErrorAnnotation(range, defaultMessage)
|
||||
Severity.WARNING -> {
|
||||
if (highlightType == ProblemHighlightType.WEAK_WARNING) {
|
||||
holder.createWeakWarningAnnotation(range, defaultMessage)
|
||||
} else {
|
||||
holder.createWarningAnnotation(range, defaultMessage)
|
||||
}
|
||||
}
|
||||
Severity.INFO -> holder.createInfoAnnotation(range, defaultMessage)
|
||||
}
|
||||
|
||||
annotation.tooltip = getMessage(diagnostic)
|
||||
|
||||
if (highlightType != null) {
|
||||
annotation.highlightType = highlightType
|
||||
}
|
||||
|
||||
if (textAttributes != null) {
|
||||
annotation.textAttributes = textAttributes
|
||||
}
|
||||
|
||||
return annotation
|
||||
}
|
||||
|
||||
private fun getMessage(diagnostic: Diagnostic): String {
|
||||
var message = IdeErrorMessages.render(diagnostic)
|
||||
if (ApplicationManager.getApplication().isInternal || ApplicationManager.getApplication().isUnitTestMode) {
|
||||
val factoryName = diagnostic.factory.name
|
||||
message = if (message.startsWith("<html>")) {
|
||||
"<html>[$factoryName] ${message.substring("<html>".length)}"
|
||||
} else {
|
||||
"[$factoryName] $message"
|
||||
}
|
||||
}
|
||||
if (!message.startsWith("<html>")) {
|
||||
message = "<html><body>${XmlStringUtil.escapeString(message)}</body></html>"
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
private fun getDefaultMessage(diagnostic: Diagnostic): String {
|
||||
val message = DefaultErrorMessages.render(diagnostic)
|
||||
if (ApplicationManager.getApplication().isInternal || ApplicationManager.getApplication().isUnitTestMode) {
|
||||
return "[${diagnostic.factory.name}] $message"
|
||||
}
|
||||
return message
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public class ModuleHighlightUtil2 {
|
||||
}
|
||||
}
|
||||
else if (root.getFileSystem() instanceof JarFileSystem && "jar".equalsIgnoreCase(root.getExtension())) {
|
||||
return LightJavaModule.getModule(PsiManager.getInstance(project), root);
|
||||
return LightJavaModule.findModule(PsiManager.getInstance(project), root);
|
||||
}
|
||||
}
|
||||
else if ((root = index.getSourceRootForFile(file)) != null) {
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.idea.modules;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import com.intellij.psi.PsiJavaModule;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.light.LightJavaModule;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.core.FileIndexUtilsKt;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import static com.intellij.psi.PsiJavaModule.MODULE_INFO_FILE;
|
||||
|
||||
// Copied from com.intellij.codeInsight.daemon.impl.analysis.ModuleHighlightUtil
|
||||
public class ModuleHighlightUtil2 {
|
||||
private static final Attributes.Name MULTI_RELEASE = new Attributes.Name("Multi-Release");
|
||||
|
||||
@Nullable
|
||||
static PsiJavaModule getModuleDescriptor(@NotNull VirtualFile file, @NotNull Project project) {
|
||||
ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project);
|
||||
if (index.isInLibrary(file)) {
|
||||
VirtualFile root;
|
||||
if ((root = index.getClassRootForFile(file)) != null) {
|
||||
VirtualFile descriptorFile = root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE);
|
||||
if (descriptorFile == null) {
|
||||
VirtualFile alt = root.findFileByRelativePath("META-INF/versions/9/" + PsiJavaModule.MODULE_INFO_CLS_FILE);
|
||||
if (alt != null && isMultiReleaseJar(root)) {
|
||||
descriptorFile = alt;
|
||||
}
|
||||
}
|
||||
if (descriptorFile != null) {
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(descriptorFile);
|
||||
if (psiFile instanceof PsiJavaFile) {
|
||||
return ((PsiJavaFile) psiFile).getModuleDeclaration();
|
||||
}
|
||||
}
|
||||
else if (root.getFileSystem() instanceof JarFileSystem && "jar".equalsIgnoreCase(root.getExtension())) {
|
||||
return LightJavaModule.getModule(PsiManager.getInstance(project), root);
|
||||
}
|
||||
}
|
||||
else if ((root = index.getSourceRootForFile(file)) != null) {
|
||||
VirtualFile descriptorFile = root.findChild(MODULE_INFO_FILE);
|
||||
if (descriptorFile != null) {
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(descriptorFile);
|
||||
if (psiFile instanceof PsiJavaFile) {
|
||||
return ((PsiJavaFile) psiFile).getModuleDeclaration();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Module module = index.getModuleForFile(file);
|
||||
if (module != null) {
|
||||
boolean isTest = FileIndexUtilsKt.isInTestSourceContentKotlinAware(index, file);
|
||||
VirtualFile modularRoot = ArraysKt.singleOrNull(ModuleRootManager.getInstance(module).getSourceRoots(isTest),
|
||||
root -> root.findChild(MODULE_INFO_FILE) != null);
|
||||
if (modularRoot != null) {
|
||||
VirtualFile moduleInfo = modularRoot.findChild(MODULE_INFO_FILE);
|
||||
assert moduleInfo != null : modularRoot;
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(moduleInfo);
|
||||
if (psiFile instanceof PsiJavaFile) {
|
||||
return ((PsiJavaFile) psiFile).getModuleDeclaration();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isMultiReleaseJar(VirtualFile root) {
|
||||
if (root.getFileSystem() instanceof JarFileSystem) {
|
||||
VirtualFile manifest = root.findFileByRelativePath(JarFile.MANIFEST_NAME);
|
||||
if (manifest != null) {
|
||||
try (InputStream stream = manifest.getInputStream()) {
|
||||
return Boolean.valueOf(new Manifest(stream).getMainAttributes().getValue(MULTI_RELEASE));
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.idea.util.application
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.openapi.progress.impl.CancellationCheck
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.annotations.Nls
|
||||
|
||||
fun <T> runReadAction(action: () -> T): T {
|
||||
return ApplicationManager.getApplication().runReadAction<T>(action)
|
||||
@@ -29,22 +29,22 @@ fun <T> runWriteAction(action: () -> T): T {
|
||||
return ApplicationManager.getApplication().runWriteAction<T>(action)
|
||||
}
|
||||
|
||||
fun Project.executeWriteCommand(@Nls name: String, command: () -> Unit) {
|
||||
fun Project.executeWriteCommand(name: String, command: () -> Unit) {
|
||||
CommandProcessor.getInstance().executeCommand(this, { runWriteAction(command) }, name, null)
|
||||
}
|
||||
|
||||
fun <T> Project.executeWriteCommand(@Nls name: String, groupId: Any? = null, command: () -> T): T {
|
||||
fun <T> Project.executeWriteCommand(name: String, groupId: Any? = null, command: () -> T): T {
|
||||
return executeCommand<T>(name, groupId) { runWriteAction(command) }
|
||||
}
|
||||
|
||||
fun <T> Project.executeCommand(@Nls name: String, groupId: Any? = null, command: () -> T): T {
|
||||
fun <T> Project.executeCommand(name: String, groupId: Any? = null, command: () -> T): T {
|
||||
@Suppress("UNCHECKED_CAST") var result: T = null as T
|
||||
CommandProcessor.getInstance().executeCommand(this, { result = command() }, name, groupId)
|
||||
@Suppress("USELESS_CAST")
|
||||
return result as T
|
||||
}
|
||||
|
||||
fun <T> runWithCancellationCheck(block: () -> T): T = block()
|
||||
fun <T> runWithCancellationCheck(block: () -> T): T = CancellationCheck.runWithCancellationCheck(block)
|
||||
|
||||
inline fun invokeLater(crossinline action: () -> Unit) {
|
||||
ApplicationManager.getApplication().invokeLater { action() }
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.idea.util.application
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.annotations.Nls
|
||||
|
||||
fun <T> runReadAction(action: () -> T): T {
|
||||
return ApplicationManager.getApplication().runReadAction<T>(action)
|
||||
}
|
||||
|
||||
fun <T> runWriteAction(action: () -> T): T {
|
||||
return ApplicationManager.getApplication().runWriteAction<T>(action)
|
||||
}
|
||||
|
||||
fun Project.executeWriteCommand(@Nls name: String, command: () -> Unit) {
|
||||
CommandProcessor.getInstance().executeCommand(this, { runWriteAction(command) }, name, null)
|
||||
}
|
||||
|
||||
fun <T> Project.executeWriteCommand(@Nls name: String, groupId: Any? = null, command: () -> T): T {
|
||||
return executeCommand<T>(name, groupId) { runWriteAction(command) }
|
||||
}
|
||||
|
||||
fun <T> Project.executeCommand(@Nls name: String, groupId: Any? = null, command: () -> T): T {
|
||||
@Suppress("UNCHECKED_CAST") var result: T = null as T
|
||||
CommandProcessor.getInstance().executeCommand(this, { result = command() }, name, groupId)
|
||||
@Suppress("USELESS_CAST")
|
||||
return result as T
|
||||
}
|
||||
|
||||
fun <T> runWithCancellationCheck(block: () -> T): T = block()
|
||||
|
||||
inline fun invokeLater(crossinline action: () -> Unit) {
|
||||
ApplicationManager.getApplication().invokeLater { action() }
|
||||
}
|
||||
|
||||
inline fun isUnitTestMode(): Boolean = ApplicationManager.getApplication().isUnitTestMode
|
||||
@@ -59,7 +59,7 @@ dependencies {
|
||||
testRuntime(intellijPluginDep("coverage"))
|
||||
testRuntime(intellijPluginDep("gradle"))
|
||||
testRuntime(intellijPluginDep("Groovy"))
|
||||
if (Platform[201].orHigher()) {
|
||||
if (Platform[201]()) {
|
||||
testRuntime(intellijPluginDep("platform-langInjection"))
|
||||
} else {
|
||||
testRuntime(intellijPluginDep("IntelliLang"))
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion.test.handlers
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupFocusDegree
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
||||
|
||||
// BUNCH: 193
|
||||
fun LookupImpl.setFocusedFocusDegree() {
|
||||
focusDegree = LookupImpl.FocusDegree.FOCUSED
|
||||
this.lookupFocusDegree = LookupFocusDegree.FOCUSED
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* 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.idea.completion.test.handlers
|
||||
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
||||
|
||||
// BUNCH: 193
|
||||
fun LookupImpl.setFocusedFocusDegree() {
|
||||
focusDegree = LookupImpl.FocusDegree.FOCUSED
|
||||
}
|
||||
@@ -13,8 +13,8 @@ import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExten
|
||||
|
||||
// BUNCH: 193
|
||||
abstract class AbstractProjectResolverExtensionCompat : AbstractProjectResolverExtension() {
|
||||
override fun createModule(gradleModule: IdeaModule, projectDataNode: DataNode<ProjectData>): DataNode<ModuleData> {
|
||||
return super.createModule(gradleModule, projectDataNode).also {
|
||||
override fun createModule(gradleModule: IdeaModule, projectDataNode: DataNode<ProjectData>): DataNode<ModuleData>? {
|
||||
return super.createModule(gradleModule, projectDataNode)?.also {
|
||||
initializeModuleNode(gradleModule, it, projectDataNode)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.idea.configuration
|
||||
|
||||
import com.intellij.openapi.externalSystem.model.DataNode
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData
|
||||
import org.gradle.tooling.model.idea.IdeaModule
|
||||
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
|
||||
|
||||
// BUNCH: 193
|
||||
abstract class AbstractProjectResolverExtensionCompat : AbstractProjectResolverExtension() {
|
||||
override fun createModule(gradleModule: IdeaModule, projectDataNode: DataNode<ProjectData>): DataNode<ModuleData> {
|
||||
return super.createModule(gradleModule, projectDataNode).also {
|
||||
initializeModuleNode(gradleModule, it, projectDataNode)
|
||||
}
|
||||
}
|
||||
|
||||
// Inline after class remove
|
||||
abstract fun initializeModuleNode(
|
||||
gradleModule: IdeaModule,
|
||||
moduleDataNode: DataNode<ModuleData>,
|
||||
projectDataNode: DataNode<ProjectData>,
|
||||
)
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.externalSystem.service.project.autoimport.AsyncFileChangeListenerBase
|
||||
import com.intellij.openapi.externalSystem.autoimport.AsyncFileChangeListenerBase
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
@@ -22,9 +22,8 @@ fun addVfsListener(watcher: GradleScriptInputsWatcher) {
|
||||
}
|
||||
|
||||
// do nothing
|
||||
override fun prepareFileDeletion(file: VirtualFile) {}
|
||||
override fun apply() {}
|
||||
override fun reset() {}
|
||||
override fun init() {}
|
||||
|
||||
},
|
||||
watcher.project
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.idea.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.externalSystem.service.project.autoimport.AsyncFileChangeListenerBase
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
|
||||
fun addVfsListener(watcher: GradleScriptInputsWatcher) {
|
||||
VirtualFileManager.getInstance().addAsyncFileListener(
|
||||
object : AsyncFileChangeListenerBase() {
|
||||
override fun isRelevant(path: String): Boolean {
|
||||
return isInAffectedGradleProjectFiles(watcher.project, path)
|
||||
}
|
||||
|
||||
override fun updateFile(file: VirtualFile, event: VFileEvent) {
|
||||
watcher.fileChanged(event.path, file.timeStamp)
|
||||
}
|
||||
|
||||
// do nothing
|
||||
override fun prepareFileDeletion(file: VirtualFile) {}
|
||||
override fun apply() {}
|
||||
override fun reset() {}
|
||||
|
||||
},
|
||||
watcher.project
|
||||
)
|
||||
}
|
||||
@@ -147,8 +147,8 @@ public abstract class AbstractModelBuilderTest {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<Class> getToolingExtensionClasses() {
|
||||
Set<Class> classes = ContainerUtil.<Class>set(
|
||||
private static Set<Class<?>> getToolingExtensionClasses() {
|
||||
Set<Class<?>> classes = ContainerUtil.set(
|
||||
ExternalProject.class,
|
||||
// gradle-tooling-extension-api jar
|
||||
ProjectImportAction.class,
|
||||
@@ -163,7 +163,7 @@ public abstract class AbstractModelBuilderTest {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<Class> doGetToolingExtensionClasses() {
|
||||
private static Set<Class<?>> doGetToolingExtensionClasses() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ public abstract class AbstractModelBuilderTest {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Set<Class> getModels();
|
||||
protected abstract Set<Class<?>> getModels();
|
||||
|
||||
|
||||
private static void ensureTempDirCreated() throws IOException {
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* 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.idea.codeInsight.gradle;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.codehaus.groovy.runtime.typehandling.ShortTypeHandling;
|
||||
import org.gradle.tooling.BuildActionExecuter;
|
||||
import org.gradle.tooling.GradleConnector;
|
||||
import org.gradle.tooling.ProjectConnection;
|
||||
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
|
||||
import org.gradle.util.GradleVersion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.ClassSetProjectImportModelProvider;
|
||||
import org.jetbrains.plugins.gradle.model.ExternalProject;
|
||||
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
|
||||
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper;
|
||||
import org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestName;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
|
||||
// part of org.jetbrains.plugins.gradle.tooling.builder.AbstractModelBuilderTest
|
||||
@RunWith(value = Parameterized.class)
|
||||
public abstract class AbstractModelBuilderTest {
|
||||
|
||||
public static final Object[][] SUPPORTED_GRADLE_VERSIONS = {{"4.9"}, {"5.6.4"}};
|
||||
|
||||
private static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*: with Gradle-.*)\\]");
|
||||
|
||||
private static File ourTempDir;
|
||||
|
||||
@NotNull
|
||||
private final String gradleVersion;
|
||||
private File testDir;
|
||||
private ProjectImportAction.AllModels allModels;
|
||||
|
||||
@Rule public TestName name = new TestName();
|
||||
@Rule public VersionMatcherRule versionMatcherRule = new VersionMatcherRule();
|
||||
|
||||
public AbstractModelBuilderTest(@NotNull String gradleVersion) {
|
||||
this.gradleVersion = gradleVersion;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "{index}: with Gradle-{0}")
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays.asList(SUPPORTED_GRADLE_VERSIONS);
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
assumeThat(gradleVersion, versionMatcherRule.getMatcher());
|
||||
|
||||
ensureTempDirCreated();
|
||||
|
||||
String methodName = name.getMethodName();
|
||||
Matcher m = TEST_METHOD_NAME_PATTERN.matcher(methodName);
|
||||
if (m.matches()) {
|
||||
methodName = m.group(1);
|
||||
}
|
||||
|
||||
testDir = new File(ourTempDir, methodName);
|
||||
FileUtil.ensureExists(testDir);
|
||||
|
||||
InputStream buildScriptStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.DEFAULT_SCRIPT_NAME);
|
||||
try {
|
||||
FileUtil.writeToFile(
|
||||
new File(testDir, GradleConstants.DEFAULT_SCRIPT_NAME),
|
||||
FileUtil.loadTextAndClose(buildScriptStream)
|
||||
);
|
||||
}
|
||||
finally {
|
||||
StreamUtil.closeStream(buildScriptStream);
|
||||
}
|
||||
|
||||
InputStream settingsStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.SETTINGS_FILE_NAME);
|
||||
try {
|
||||
if (settingsStream != null) {
|
||||
FileUtil.writeToFile(
|
||||
new File(testDir, GradleConstants.SETTINGS_FILE_NAME),
|
||||
FileUtil.loadTextAndClose(settingsStream)
|
||||
);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
StreamUtil.closeStream(settingsStream);
|
||||
}
|
||||
|
||||
GradleConnector connector = GradleConnector.newConnector();
|
||||
|
||||
URI distributionUri = new DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion));
|
||||
connector.useDistribution(distributionUri);
|
||||
connector.forProjectDirectory(testDir);
|
||||
int daemonMaxIdleTime = 10;
|
||||
try {
|
||||
daemonMaxIdleTime = Integer.parseInt(System.getProperty("gradleDaemonMaxIdleTime", "10"));
|
||||
}
|
||||
catch (NumberFormatException ignore) {
|
||||
}
|
||||
|
||||
((DefaultGradleConnector) connector).daemonMaxIdleTime(daemonMaxIdleTime, TimeUnit.SECONDS);
|
||||
ProjectConnection connection = connector.connect();
|
||||
|
||||
try {
|
||||
ProjectImportAction projectImportAction = new ProjectImportAction(false);
|
||||
projectImportAction.addProjectImportModelProvider(new ClassSetProjectImportModelProvider(getModels()));
|
||||
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
|
||||
File initScript = GradleExecutionHelper.generateInitScript(false, getToolingExtensionClasses());
|
||||
assertNotNull(initScript);
|
||||
String jdkHome = IdeaTestUtil.requireRealJdkHome();
|
||||
buildActionExecutor.setJavaHome(new File(jdkHome));
|
||||
buildActionExecutor.setJvmArguments("-Xmx128m", "-XX:MaxPermSize=64m");
|
||||
buildActionExecutor
|
||||
.withArguments("--info", "--recompile-scripts", GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath());
|
||||
allModels = buildActionExecutor.run();
|
||||
assertNotNull(allModels);
|
||||
}
|
||||
finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<Class> getToolingExtensionClasses() {
|
||||
Set<Class> classes = ContainerUtil.<Class>set(
|
||||
ExternalProject.class,
|
||||
// gradle-tooling-extension-api jar
|
||||
ProjectImportAction.class,
|
||||
// gradle-tooling-extension-impl jar
|
||||
ModelBuildScriptClasspathBuilderImpl.class,
|
||||
Multimap.class,
|
||||
ShortTypeHandling.class
|
||||
);
|
||||
|
||||
ContainerUtil.addAllNotNull(classes, doGetToolingExtensionClasses());
|
||||
return classes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<Class> doGetToolingExtensionClasses() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (testDir != null) {
|
||||
FileUtil.delete(testDir);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Set<Class> getModels();
|
||||
|
||||
|
||||
private static void ensureTempDirCreated() throws IOException {
|
||||
if (ourTempDir != null) return;
|
||||
|
||||
ourTempDir = new File(FileUtil.getTempDirectory(), "gradleTests");
|
||||
FileUtil.delete(ourTempDir);
|
||||
FileUtil.ensureExists(ourTempDir);
|
||||
}
|
||||
|
||||
public static class DistributionLocator {
|
||||
private static final String RELEASE_REPOSITORY_ENV = "GRADLE_RELEASE_REPOSITORY";
|
||||
private static final String SNAPSHOT_REPOSITORY_ENV = "GRADLE_SNAPSHOT_REPOSITORY";
|
||||
private static final String GRADLE_RELEASE_REPO = "https://services.gradle.org/distributions";
|
||||
private static final String GRADLE_SNAPSHOT_REPO = "https://services.gradle.org/distributions-snapshots";
|
||||
|
||||
@NotNull private final String myReleaseRepoUrl;
|
||||
@NotNull private final String mySnapshotRepoUrl;
|
||||
|
||||
public DistributionLocator() {
|
||||
this(DistributionLocator.getRepoUrl(false), DistributionLocator.getRepoUrl(true));
|
||||
}
|
||||
|
||||
public DistributionLocator(@NotNull String releaseRepoUrl, @NotNull String snapshotRepoUrl) {
|
||||
myReleaseRepoUrl = releaseRepoUrl;
|
||||
mySnapshotRepoUrl = snapshotRepoUrl;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public URI getDistributionFor(@NotNull GradleVersion version) throws URISyntaxException {
|
||||
return getDistribution(getDistributionRepository(version), version, "gradle", "bin");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getDistributionRepository(@NotNull GradleVersion version) {
|
||||
return version.isSnapshot() ? mySnapshotRepoUrl : myReleaseRepoUrl;
|
||||
}
|
||||
|
||||
private static URI getDistribution(
|
||||
@NotNull String repositoryUrl,
|
||||
@NotNull GradleVersion version,
|
||||
@NotNull String archiveName,
|
||||
@NotNull String archiveClassifier
|
||||
) throws URISyntaxException {
|
||||
return new URI(String.format("%s/%s-%s-%s.zip", repositoryUrl, archiveName, version.getVersion(), archiveClassifier));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getRepoUrl(boolean isSnapshotUrl) {
|
||||
String envRepoUrl = System.getenv(isSnapshotUrl ? SNAPSHOT_REPOSITORY_ENV : RELEASE_REPOSITORY_ENV);
|
||||
if (envRepoUrl != null) return envRepoUrl;
|
||||
|
||||
return isSnapshotUrl ? GRADLE_SNAPSHOT_REPO : GRADLE_RELEASE_REPO;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ dependencies {
|
||||
compileOnly(intellijPluginDep("testng"))
|
||||
compileOnly(intellijPluginDep("coverage"))
|
||||
compileOnly(intellijPluginDep("java-decompiler"))
|
||||
if (Platform[201].orHigher()) {
|
||||
if (Platform[201]()) {
|
||||
compileOnly(intellijPluginDep("platform-langInjection"))
|
||||
} else {
|
||||
compileOnly(intellijPluginDep("IntelliLang"))
|
||||
|
||||
@@ -33,15 +33,17 @@ class ShowKotlinBytecodeAction : AnAction() {
|
||||
val project = e.project ?: return
|
||||
val toolWindowManager = ToolWindowManager.getInstance(project)
|
||||
|
||||
var toolWindow = toolWindowManager.getToolWindow(TOOLWINDOW_ID)
|
||||
if (toolWindow == null) {
|
||||
toolWindow = toolWindowManager.registerToolWindow("Kotlin Bytecode", false, ToolWindowAnchor.RIGHT)
|
||||
toolWindow.icon = KotlinIcons.SMALL_LOGO_13
|
||||
val toolWindow = toolWindowManager.getToolWindow(TOOLWINDOW_ID) ?: toolWindowManager.registerToolWindow(
|
||||
"Kotlin Bytecode",
|
||||
false,
|
||||
ToolWindowAnchor.RIGHT,
|
||||
)
|
||||
.apply {
|
||||
setIcon(KotlinIcons.SMALL_LOGO_13)
|
||||
val contentFactory = ContentFactory.SERVICE.getInstance()
|
||||
contentManager.addContent(contentFactory.createContent(KotlinBytecodeToolWindow(project, this), "", false))
|
||||
}
|
||||
|
||||
val contentManager = toolWindow.contentManager
|
||||
val contentFactory = ContentFactory.SERVICE.getInstance()
|
||||
contentManager.addContent(contentFactory.createContent(KotlinBytecodeToolWindow(project, toolWindow), "", false))
|
||||
}
|
||||
toolWindow.activate(null)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.idea.actions
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.wm.ToolWindowAnchor
|
||||
import com.intellij.openapi.wm.ToolWindowManager
|
||||
import com.intellij.ui.content.ContentFactory
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.internal.KotlinBytecodeToolWindow
|
||||
|
||||
class ShowKotlinBytecodeAction : AnAction() {
|
||||
val TOOLWINDOW_ID = "Kotlin Bytecode"
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val project = e.project ?: return
|
||||
val toolWindowManager = ToolWindowManager.getInstance(project)
|
||||
|
||||
var toolWindow = toolWindowManager.getToolWindow(TOOLWINDOW_ID)
|
||||
if (toolWindow == null) {
|
||||
toolWindow = toolWindowManager.registerToolWindow("Kotlin Bytecode", false, ToolWindowAnchor.RIGHT)
|
||||
toolWindow.icon = KotlinIcons.SMALL_LOGO_13
|
||||
|
||||
val contentManager = toolWindow.contentManager
|
||||
val contentFactory = ContentFactory.SERVICE.getInstance()
|
||||
contentManager.addContent(contentFactory.createContent(KotlinBytecodeToolWindow(project, toolWindow), "", false))
|
||||
}
|
||||
toolWindow.activate(null)
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
val file = e.getData(CommonDataKeys.PSI_FILE)
|
||||
e.presentation.isEnabled = e.project != null && file?.fileType == KotlinFileType.INSTANCE
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,12 @@ import com.intellij.execution.filters.OpenFileHyperlinkInfo
|
||||
import com.intellij.execution.impl.ConsoleViewImpl
|
||||
import com.intellij.execution.runners.ExecutionUtil
|
||||
import com.intellij.execution.ui.ConsoleViewContentType
|
||||
import com.intellij.ide.scratch.ScratchFileType
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.wm.ToolWindow
|
||||
@@ -113,8 +113,8 @@ private class ToolWindowScratchOutputHandler(private val parentDisposable: Dispo
|
||||
OpenFileHyperlinkInfo(
|
||||
project,
|
||||
psiFile.virtualFile,
|
||||
expression.lineStart,
|
||||
),
|
||||
expression.lineStart
|
||||
)
|
||||
)
|
||||
print(" ", ConsoleViewContentType.NORMAL_OUTPUT)
|
||||
}
|
||||
@@ -149,7 +149,7 @@ private class ToolWindowScratchOutputHandler(private val parentDisposable: Dispo
|
||||
toolWindow.show(null)
|
||||
}
|
||||
|
||||
toolWindow.icon = ExecutionUtil.getLiveIndicator(scratchIcon())
|
||||
toolWindow.setIcon(ExecutionUtil.getLiveIndicator(ScratchFileType.INSTANCE.icon))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ private class ToolWindowScratchOutputHandler(private val parentDisposable: Dispo
|
||||
toolWindow.hide(null)
|
||||
}
|
||||
|
||||
toolWindow.icon = scratchIcon()
|
||||
toolWindow.setIcon(ScratchFileType.INSTANCE.icon ?: error("Text icon is expected to be present"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,22 +187,18 @@ private class ToolWindowScratchOutputHandler(private val parentDisposable: Dispo
|
||||
val project = file.project
|
||||
val toolWindowManager = ToolWindowManager.getInstance(project)
|
||||
toolWindowManager.registerToolWindow(ScratchToolWindowFactory.ID, true, ToolWindowAnchor.BOTTOM)
|
||||
val window = toolWindowManager.getToolWindow(ScratchToolWindowFactory.ID)
|
||||
val window =
|
||||
toolWindowManager.getToolWindow(ScratchToolWindowFactory.ID) ?: error("ScratchToolWindowFactory.ID should be registered")
|
||||
ScratchToolWindowFactory().createToolWindowContent(project, window)
|
||||
|
||||
Disposer.register(
|
||||
parentDisposable,
|
||||
Disposable {
|
||||
toolWindowManager.unregisterToolWindow(ScratchToolWindowFactory.ID)
|
||||
},
|
||||
)
|
||||
Disposer.register(parentDisposable, Disposable {
|
||||
toolWindowManager.unregisterToolWindow(ScratchToolWindowFactory.ID)
|
||||
})
|
||||
|
||||
return window
|
||||
}
|
||||
}
|
||||
|
||||
private fun scratchIcon() = PlainTextFileType.INSTANCE.icon
|
||||
|
||||
private fun getLineInfo(psiFile: PsiFile, expression: ScratchExpression) =
|
||||
"${psiFile.name}:${expression.lineStart + 1}"
|
||||
|
||||
@@ -213,8 +209,8 @@ private class ScratchToolWindowFactory : ToolWindowFactory {
|
||||
|
||||
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
|
||||
val consoleView = ConsoleViewImpl(project, true)
|
||||
toolWindow.isToHideOnEmptyContent = true
|
||||
toolWindow.icon = scratchIcon()
|
||||
toolWindow.setToHideOnEmptyContent(true)
|
||||
toolWindow.setIcon(ScratchFileType.INSTANCE.icon ?: error("Text icon should be present"))
|
||||
toolWindow.hide(null)
|
||||
|
||||
val contentManager = toolWindow.contentManager
|
||||
@@ -242,33 +238,27 @@ private object TestOutputHandler : ScratchOutputHandlerAdapter() {
|
||||
}
|
||||
|
||||
override fun onFinish(file: ScratchFile) {
|
||||
TransactionGuard.submitTransaction(
|
||||
file.project,
|
||||
Runnable {
|
||||
val psiFile = file.getPsiFile()
|
||||
?: error(
|
||||
"PsiFile cannot be found for scratch to render inlays in tests:\n" +
|
||||
"project.isDisposed = ${file.project.isDisposed}\n" +
|
||||
"inlays = ${inlays.joinToString { it.second }}\n" +
|
||||
"errors = ${errors.joinToString()}",
|
||||
)
|
||||
TransactionGuard.submitTransaction(file.project, Runnable {
|
||||
val psiFile = file.getPsiFile()
|
||||
?: error(
|
||||
"PsiFile cannot be found for scratch to render inlays in tests:\n" +
|
||||
"project.isDisposed = ${file.project.isDisposed}\n" +
|
||||
"inlays = ${inlays.joinToString { it.second }}\n" +
|
||||
"errors = ${errors.joinToString()}"
|
||||
)
|
||||
|
||||
if (inlays.isNotEmpty()) {
|
||||
testPrint(
|
||||
psiFile,
|
||||
inlays.map { (expression, text) ->
|
||||
"/** ${getLineInfo(psiFile, expression)} $text */"
|
||||
},
|
||||
)
|
||||
inlays.clear()
|
||||
}
|
||||
if (inlays.isNotEmpty()) {
|
||||
testPrint(psiFile, inlays.map { (expression, text) ->
|
||||
"/** ${getLineInfo(psiFile, expression)} $text */"
|
||||
})
|
||||
inlays.clear()
|
||||
}
|
||||
|
||||
if (errors.isNotEmpty()) {
|
||||
testPrint(psiFile, listOf(errors.joinToString(prefix = "/** ", postfix = " */")))
|
||||
errors.clear()
|
||||
}
|
||||
},
|
||||
)
|
||||
if (errors.isNotEmpty()) {
|
||||
testPrint(psiFile, listOf(errors.joinToString(prefix = "/** ", postfix = " */")))
|
||||
errors.clear()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun testPrint(file: PsiFile, comments: List<String>) {
|
||||
@@ -276,7 +266,7 @@ private object TestOutputHandler : ScratchOutputHandlerAdapter() {
|
||||
for (comment in comments) {
|
||||
file.addAfter(
|
||||
KtPsiFactory(file.project).createComment(comment),
|
||||
file.lastChild,
|
||||
file.lastChild
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* 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.idea.scratch.output
|
||||
|
||||
import com.intellij.execution.filters.OpenFileHyperlinkInfo
|
||||
import com.intellij.execution.impl.ConsoleViewImpl
|
||||
import com.intellij.execution.runners.ExecutionUtil
|
||||
import com.intellij.execution.ui.ConsoleViewContentType
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.wm.ToolWindow
|
||||
import com.intellij.openapi.wm.ToolWindowAnchor
|
||||
import com.intellij.openapi.wm.ToolWindowFactory
|
||||
import com.intellij.openapi.wm.ToolWindowManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.idea.scratch.ScratchExpression
|
||||
import org.jetbrains.kotlin.idea.scratch.ScratchFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
|
||||
/**
|
||||
* Method to retrieve shared instance of scratches ToolWindow output handler.
|
||||
*
|
||||
* [releaseToolWindowHandler] must be called for every output handler received from this method.
|
||||
*
|
||||
* Can be called from EDT only.
|
||||
*
|
||||
* @return new toolWindow output handler if one does not exist, otherwise returns the existing one. When application in test mode,
|
||||
* returns [TestOutputHandler].
|
||||
*/
|
||||
fun requestToolWindowHandler(): ScratchOutputHandler {
|
||||
return if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
TestOutputHandler
|
||||
} else {
|
||||
ScratchToolWindowHandlerKeeper.requestOutputHandler()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called once with the output handler received from the [requestToolWindowHandler] call.
|
||||
*
|
||||
* When release is called for every request, the output handler is actually disposed.
|
||||
*
|
||||
* When application in test mode, does nothing.
|
||||
*
|
||||
* Can be called from EDT only.
|
||||
*/
|
||||
fun releaseToolWindowHandler(scratchOutputHandler: ScratchOutputHandler) {
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode) {
|
||||
ScratchToolWindowHandlerKeeper.releaseOutputHandler(scratchOutputHandler)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements logic of shared pointer for the toolWindow output handler.
|
||||
*
|
||||
* Not thread safe! Can be used only from the EDT.
|
||||
*/
|
||||
private object ScratchToolWindowHandlerKeeper {
|
||||
private var toolWindowHandler: ScratchOutputHandler? = null
|
||||
private var toolWindowDisposable = Disposer.newDisposable()
|
||||
private var counter = 0
|
||||
|
||||
fun requestOutputHandler(): ScratchOutputHandler {
|
||||
if (counter == 0) {
|
||||
toolWindowHandler = ToolWindowScratchOutputHandler(toolWindowDisposable)
|
||||
}
|
||||
|
||||
counter += 1
|
||||
return toolWindowHandler!!
|
||||
}
|
||||
|
||||
fun releaseOutputHandler(scratchOutputHandler: ScratchOutputHandler) {
|
||||
require(counter > 0) { "Counter is $counter, nothing to release!" }
|
||||
require(toolWindowHandler === scratchOutputHandler) { "$scratchOutputHandler differs from stored $toolWindowHandler" }
|
||||
|
||||
counter -= 1
|
||||
if (counter == 0) {
|
||||
Disposer.dispose(toolWindowDisposable)
|
||||
toolWindowDisposable = Disposer.newDisposable()
|
||||
toolWindowHandler = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ToolWindowScratchOutputHandler(private val parentDisposable: Disposable) : ScratchOutputHandlerAdapter() {
|
||||
|
||||
override fun handle(file: ScratchFile, expression: ScratchExpression, output: ScratchOutput) {
|
||||
printToConsole(file) {
|
||||
val psiFile = file.getPsiFile()
|
||||
if (psiFile != null) {
|
||||
printHyperlink(
|
||||
getLineInfo(psiFile, expression),
|
||||
OpenFileHyperlinkInfo(
|
||||
project,
|
||||
psiFile.virtualFile,
|
||||
expression.lineStart,
|
||||
),
|
||||
)
|
||||
print(" ", ConsoleViewContentType.NORMAL_OUTPUT)
|
||||
}
|
||||
print(output.text, output.type.convert())
|
||||
}
|
||||
}
|
||||
|
||||
override fun error(file: ScratchFile, message: String) {
|
||||
printToConsole(file) {
|
||||
print(message, ConsoleViewContentType.ERROR_OUTPUT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun printToConsole(file: ScratchFile, print: ConsoleViewImpl.() -> Unit) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
val project = file.project.takeIf { !it.isDisposed } ?: return@invokeLater
|
||||
|
||||
val toolWindow = getToolWindow(project) ?: createToolWindow(file)
|
||||
|
||||
val contents = toolWindow.contentManager.contents
|
||||
for (content in contents) {
|
||||
val component = content.component
|
||||
if (component is ConsoleViewImpl) {
|
||||
component.print()
|
||||
component.print("\n", ConsoleViewContentType.NORMAL_OUTPUT)
|
||||
}
|
||||
}
|
||||
|
||||
toolWindow.setAvailable(true, null)
|
||||
|
||||
if (!file.options.isInteractiveMode) {
|
||||
toolWindow.show(null)
|
||||
}
|
||||
|
||||
toolWindow.icon = ExecutionUtil.getLiveIndicator(scratchIcon())
|
||||
}
|
||||
}
|
||||
|
||||
override fun clear(file: ScratchFile) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
val toolWindow = getToolWindow(file.project) ?: return@invokeLater
|
||||
val contents = toolWindow.contentManager.contents
|
||||
for (content in contents) {
|
||||
val component = content.component
|
||||
if (component is ConsoleViewImpl) {
|
||||
component.clear()
|
||||
}
|
||||
}
|
||||
|
||||
if (!file.options.isInteractiveMode) {
|
||||
toolWindow.hide(null)
|
||||
}
|
||||
|
||||
toolWindow.icon = scratchIcon()
|
||||
}
|
||||
}
|
||||
|
||||
private fun ScratchOutputType.convert() = when (this) {
|
||||
ScratchOutputType.OUTPUT -> ConsoleViewContentType.SYSTEM_OUTPUT
|
||||
ScratchOutputType.RESULT -> ConsoleViewContentType.NORMAL_OUTPUT
|
||||
ScratchOutputType.ERROR -> ConsoleViewContentType.ERROR_OUTPUT
|
||||
}
|
||||
|
||||
private fun getToolWindow(project: Project): ToolWindow? {
|
||||
val toolWindowManager = ToolWindowManager.getInstance(project)
|
||||
return toolWindowManager.getToolWindow(ScratchToolWindowFactory.ID)
|
||||
}
|
||||
|
||||
private fun createToolWindow(file: ScratchFile): ToolWindow {
|
||||
val project = file.project
|
||||
val toolWindowManager = ToolWindowManager.getInstance(project)
|
||||
toolWindowManager.registerToolWindow(ScratchToolWindowFactory.ID, true, ToolWindowAnchor.BOTTOM)
|
||||
val window = toolWindowManager.getToolWindow(ScratchToolWindowFactory.ID)
|
||||
ScratchToolWindowFactory().createToolWindowContent(project, window)
|
||||
|
||||
Disposer.register(
|
||||
parentDisposable,
|
||||
Disposable {
|
||||
toolWindowManager.unregisterToolWindow(ScratchToolWindowFactory.ID)
|
||||
},
|
||||
)
|
||||
|
||||
return window
|
||||
}
|
||||
}
|
||||
|
||||
private fun scratchIcon() = PlainTextFileType.INSTANCE.icon
|
||||
|
||||
private fun getLineInfo(psiFile: PsiFile, expression: ScratchExpression) =
|
||||
"${psiFile.name}:${expression.lineStart + 1}"
|
||||
|
||||
private class ScratchToolWindowFactory : ToolWindowFactory {
|
||||
companion object {
|
||||
const val ID = "Scratch Output"
|
||||
}
|
||||
|
||||
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
|
||||
val consoleView = ConsoleViewImpl(project, true)
|
||||
toolWindow.isToHideOnEmptyContent = true
|
||||
toolWindow.icon = scratchIcon()
|
||||
toolWindow.hide(null)
|
||||
|
||||
val contentManager = toolWindow.contentManager
|
||||
val content = contentManager.factory.createContent(consoleView.component, null, false)
|
||||
contentManager.addContent(content)
|
||||
val editor = consoleView.editor
|
||||
if (editor is EditorEx) {
|
||||
editor.isRendererMode = true
|
||||
}
|
||||
|
||||
Disposer.register(project, consoleView)
|
||||
}
|
||||
}
|
||||
|
||||
private object TestOutputHandler : ScratchOutputHandlerAdapter() {
|
||||
private val errors = arrayListOf<String>()
|
||||
private val inlays = arrayListOf<Pair<ScratchExpression, String>>()
|
||||
|
||||
override fun handle(file: ScratchFile, expression: ScratchExpression, output: ScratchOutput) {
|
||||
inlays.add(expression to output.text)
|
||||
}
|
||||
|
||||
override fun error(file: ScratchFile, message: String) {
|
||||
errors.add(message)
|
||||
}
|
||||
|
||||
override fun onFinish(file: ScratchFile) {
|
||||
TransactionGuard.submitTransaction(
|
||||
file.project,
|
||||
Runnable {
|
||||
val psiFile = file.getPsiFile()
|
||||
?: error(
|
||||
"PsiFile cannot be found for scratch to render inlays in tests:\n" +
|
||||
"project.isDisposed = ${file.project.isDisposed}\n" +
|
||||
"inlays = ${inlays.joinToString { it.second }}\n" +
|
||||
"errors = ${errors.joinToString()}",
|
||||
)
|
||||
|
||||
if (inlays.isNotEmpty()) {
|
||||
testPrint(
|
||||
psiFile,
|
||||
inlays.map { (expression, text) ->
|
||||
"/** ${getLineInfo(psiFile, expression)} $text */"
|
||||
},
|
||||
)
|
||||
inlays.clear()
|
||||
}
|
||||
|
||||
if (errors.isNotEmpty()) {
|
||||
testPrint(psiFile, listOf(errors.joinToString(prefix = "/** ", postfix = " */")))
|
||||
errors.clear()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun testPrint(file: PsiFile, comments: List<String>) {
|
||||
WriteCommandAction.runWriteCommandAction(file.project) {
|
||||
for (comment in comments) {
|
||||
file.addAfter(
|
||||
KtPsiFactory(file.project).createComment(comment),
|
||||
file.lastChild,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.JBSplitter;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.KotlinJvmBundle;
|
||||
@@ -473,7 +472,6 @@ class SplitEditorToolbar extends JPanel implements Disposable {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public void addGutterToTrack(@NotNull EditorGutterComponentEx gutterComponentEx) {}
|
||||
|
||||
public void refresh() {
|
||||
@@ -481,7 +479,6 @@ class SplitEditorToolbar extends JPanel implements Disposable {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
@Override
|
||||
public void dispose() {}
|
||||
}
|
||||
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* 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.idea.scratch.ui;
|
||||
|
||||
|
||||
import com.intellij.codeHighlighting.BackgroundEditorHighlighter;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.structureView.StructureViewBuilder;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
|
||||
import com.intellij.openapi.fileEditor.*;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.JBSplitter;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.KotlinJvmBundle;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Two panel editor with three states: Editor, Preview and Editor with Preview.
|
||||
* Based on SplitFileEditor by Valentin Fondaratov
|
||||
* <p/>
|
||||
* <b>NOTE:</b> This class is a copy of {@link com.intellij.openapi.fileEditor.TextEditorWithPreview} from the most recent intellij-community
|
||||
* repository. We cannot use bundled version of this class because it doesn't yet have customization methods
|
||||
* (namely {@link TextEditorWithPreview#createLeftToolbarActionGroup()}).
|
||||
* <p/>
|
||||
* {@link SplitEditorToolbar} is also copied from the platform.
|
||||
* <p/>
|
||||
* This class also may have some minimal customizations to allow tracking when its layout have been changed. In the future we hope to
|
||||
* remove this copied class entirely and to use the bundled version.
|
||||
*/
|
||||
public class TextEditorWithPreview extends UserDataHolderBase implements FileEditor {
|
||||
protected final TextEditor myEditor;
|
||||
protected final FileEditor myPreview;
|
||||
@NotNull
|
||||
private final MyListenersMultimap myListenersGenerator = new MyListenersMultimap();
|
||||
private Layout myLayout;
|
||||
private JComponent myComponent;
|
||||
private SplitEditorToolbar myToolbarWrapper;
|
||||
private final String myName;
|
||||
|
||||
public TextEditorWithPreview(@NotNull TextEditor editor, @NotNull FileEditor preview, @NotNull String editorName) {
|
||||
myEditor = editor;
|
||||
myPreview = preview;
|
||||
myName = editorName;
|
||||
}
|
||||
|
||||
public TextEditorWithPreview(@NotNull TextEditor editor, @NotNull FileEditor preview) {
|
||||
this(editor, preview, "TextEditorWithPreview");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BackgroundEditorHighlighter getBackgroundHighlighter() {
|
||||
return myEditor.getBackgroundHighlighter();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FileEditorLocation getCurrentLocation() {
|
||||
return myEditor.getCurrentLocation();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public StructureViewBuilder getStructureViewBuilder() {
|
||||
return myEditor.getStructureViewBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
Disposer.dispose(myEditor);
|
||||
Disposer.dispose(myPreview);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectNotify() {
|
||||
myEditor.selectNotify();
|
||||
myPreview.selectNotify();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deselectNotify() {
|
||||
myEditor.deselectNotify();
|
||||
myPreview.deselectNotify();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
if (myComponent == null) {
|
||||
final JBSplitter splitter = new JBSplitter(false, 0.5f, 0.15f, 0.85f);
|
||||
splitter.setSplitterProportionKey(getSplitterProportionKey());
|
||||
splitter.setFirstComponent(myEditor.getComponent());
|
||||
splitter.setSecondComponent(myPreview.getComponent());
|
||||
splitter.setDividerWidth(3);
|
||||
|
||||
myToolbarWrapper = createMarkdownToolbarWrapper(splitter);
|
||||
Disposer.register(this, myToolbarWrapper);
|
||||
|
||||
if (myLayout == null) {
|
||||
String lastUsed = PropertiesComponent.getInstance().getValue(getLayoutPropertyName());
|
||||
setLayout(Layout.fromName(lastUsed, Layout.SHOW_EDITOR_AND_PREVIEW));
|
||||
}
|
||||
adjustEditorsVisibility();
|
||||
|
||||
myComponent = JBUI.Panels.simplePanel(splitter).addToTop(myToolbarWrapper);
|
||||
}
|
||||
return myComponent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SplitEditorToolbar createMarkdownToolbarWrapper (@NotNull JComponent targetComponentForActions) {
|
||||
final ActionToolbar leftToolbar = createToolbar();
|
||||
if (leftToolbar != null) {
|
||||
leftToolbar.setTargetComponent(targetComponentForActions);
|
||||
leftToolbar.setReservePlaceAutoPopupIcon(false);
|
||||
}
|
||||
|
||||
final ActionToolbar rightToolbar = createRightToolbar();
|
||||
rightToolbar.setTargetComponent(targetComponentForActions);
|
||||
rightToolbar.setReservePlaceAutoPopupIcon(false);
|
||||
|
||||
return new SplitEditorToolbar(leftToolbar, rightToolbar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(@NotNull FileEditorState state) {
|
||||
if (state instanceof MyFileEditorState) {
|
||||
final MyFileEditorState compositeState = (MyFileEditorState)state;
|
||||
if (compositeState.getFirstState() != null) {
|
||||
myEditor.setState(compositeState.getFirstState());
|
||||
}
|
||||
if (compositeState.getSecondState() != null) {
|
||||
myPreview.setState(compositeState.getSecondState());
|
||||
}
|
||||
if (compositeState.getSplitLayout() != null) {
|
||||
setLayout(compositeState.getSplitLayout());
|
||||
invalidateLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustEditorsVisibility() {
|
||||
myEditor.getComponent().setVisible(myLayout == Layout.SHOW_EDITOR || myLayout == Layout.SHOW_EDITOR_AND_PREVIEW);
|
||||
myPreview.getComponent().setVisible(myLayout == Layout.SHOW_PREVIEW || myLayout == Layout.SHOW_EDITOR_AND_PREVIEW);
|
||||
}
|
||||
|
||||
private void invalidateLayout() {
|
||||
adjustEditorsVisibility();
|
||||
myToolbarWrapper.refresh();
|
||||
myComponent.repaint();
|
||||
|
||||
final JComponent focusComponent = getPreferredFocusedComponent();
|
||||
if (focusComponent != null) {
|
||||
IdeFocusManager.findInstanceByComponent(focusComponent).requestFocus(focusComponent, true);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String getSplitterProportionKey() {
|
||||
return "TextEditorWithPreview.SplitterProportionKey";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
switch (myLayout) {
|
||||
case SHOW_EDITOR_AND_PREVIEW:
|
||||
case SHOW_EDITOR:
|
||||
return myEditor.getPreferredFocusedComponent();
|
||||
case SHOW_PREVIEW:
|
||||
return myPreview.getPreferredFocusedComponent();
|
||||
default:
|
||||
throw new IllegalStateException(myLayout.myName);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FileEditorState getState(@NotNull FileEditorStateLevel level) {
|
||||
return new MyFileEditorState(myLayout, myEditor.getState(level), myPreview.getState(level));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
|
||||
myEditor.addPropertyChangeListener(listener);
|
||||
myPreview.addPropertyChangeListener(listener);
|
||||
|
||||
final DoublingEventListenerDelegate delegate = myListenersGenerator.addListenerAndGetDelegate(listener);
|
||||
myEditor.addPropertyChangeListener(delegate);
|
||||
myPreview.addPropertyChangeListener(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {
|
||||
myEditor.removePropertyChangeListener(listener);
|
||||
myPreview.removePropertyChangeListener(listener);
|
||||
|
||||
final DoublingEventListenerDelegate delegate = myListenersGenerator.removeListenerAndGetDelegate(listener);
|
||||
if (delegate != null) {
|
||||
myEditor.removePropertyChangeListener(delegate);
|
||||
myPreview.removePropertyChangeListener(delegate);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TextEditor getTextEditor() {
|
||||
return myEditor;
|
||||
}
|
||||
|
||||
public Layout getLayout() {
|
||||
return myLayout;
|
||||
}
|
||||
|
||||
protected void setLayout(@NotNull Layout layout) {
|
||||
myLayout = layout;
|
||||
}
|
||||
|
||||
static class MyFileEditorState implements FileEditorState {
|
||||
private final Layout mySplitLayout;
|
||||
private final FileEditorState myFirstState;
|
||||
private final FileEditorState mySecondState;
|
||||
|
||||
MyFileEditorState(Layout layout, FileEditorState firstState, FileEditorState secondState) {
|
||||
mySplitLayout = layout;
|
||||
myFirstState = firstState;
|
||||
mySecondState = secondState;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Layout getSplitLayout() {
|
||||
return mySplitLayout;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FileEditorState getFirstState() {
|
||||
return myFirstState;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FileEditorState getSecondState() {
|
||||
return mySecondState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeMergedWith(FileEditorState otherState, FileEditorStateLevel level) {
|
||||
return otherState instanceof MyFileEditorState
|
||||
&& (myFirstState == null || myFirstState.canBeMergedWith(((MyFileEditorState)otherState).myFirstState, level))
|
||||
&& (mySecondState == null || mySecondState.canBeMergedWith(((MyFileEditorState)otherState).mySecondState, level));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
return myEditor.isModified() || myPreview.isModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return myEditor.isValid() && myPreview.isValid();
|
||||
}
|
||||
|
||||
private class DoublingEventListenerDelegate implements PropertyChangeListener {
|
||||
@NotNull
|
||||
private final PropertyChangeListener myDelegate;
|
||||
|
||||
private DoublingEventListenerDelegate(@NotNull PropertyChangeListener delegate) {
|
||||
myDelegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
myDelegate.propertyChange(
|
||||
new PropertyChangeEvent(TextEditorWithPreview.this, evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()));
|
||||
}
|
||||
}
|
||||
|
||||
private class MyListenersMultimap {
|
||||
private final Map<PropertyChangeListener, Pair<Integer, DoublingEventListenerDelegate>> myMap = new HashMap<>();
|
||||
|
||||
@NotNull
|
||||
public DoublingEventListenerDelegate addListenerAndGetDelegate(@NotNull PropertyChangeListener listener) {
|
||||
if (!myMap.containsKey(listener)) {
|
||||
myMap.put(listener, Pair.create(1, new DoublingEventListenerDelegate(listener)));
|
||||
}
|
||||
else {
|
||||
final Pair<Integer, DoublingEventListenerDelegate> oldPair = myMap.get(listener);
|
||||
myMap.put(listener, Pair.create(oldPair.getFirst() + 1, oldPair.getSecond()));
|
||||
}
|
||||
|
||||
return myMap.get(listener).getSecond();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DoublingEventListenerDelegate removeListenerAndGetDelegate(@NotNull PropertyChangeListener listener) {
|
||||
final Pair<Integer, DoublingEventListenerDelegate> oldPair = myMap.get(listener);
|
||||
if (oldPair == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (oldPair.getFirst() == 1) {
|
||||
myMap.remove(listener);
|
||||
}
|
||||
else {
|
||||
myMap.put(listener, Pair.create(oldPair.getFirst() - 1, oldPair.getSecond()));
|
||||
}
|
||||
return oldPair.getSecond();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected ActionToolbar createToolbar() {
|
||||
ActionGroup actionGroup = createLeftToolbarActionGroup();
|
||||
if (actionGroup != null) {
|
||||
return ActionManager.getInstance().createActionToolbar("TextEditorWithPreview", actionGroup, true);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected ActionGroup createLeftToolbarActionGroup() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ActionToolbar createRightToolbar() {
|
||||
final ActionGroup viewActions = createViewActionGroup();
|
||||
final ActionGroup group = createRightToolbarActionGroup();
|
||||
final ActionGroup rightToolbarActions = group == null
|
||||
? viewActions
|
||||
: new DefaultActionGroup(group, Separator.create(), viewActions);
|
||||
return ActionManager.getInstance().createActionToolbar("TextEditorWithPreview", rightToolbarActions, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected ActionGroup createViewActionGroup() {
|
||||
return new DefaultActionGroup(
|
||||
getShowEditorAction(),
|
||||
getShowEditorAndPreviewAction(),
|
||||
getShowPreviewAction()
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected ActionGroup createRightToolbarActionGroup() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected ToggleAction getShowEditorAction() {
|
||||
return new ChangeViewModeAction(Layout.SHOW_EDITOR);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected ToggleAction getShowPreviewAction() {
|
||||
return new ChangeViewModeAction(Layout.SHOW_PREVIEW);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected ToggleAction getShowEditorAndPreviewAction() {
|
||||
return new ChangeViewModeAction(Layout.SHOW_EDITOR_AND_PREVIEW);
|
||||
}
|
||||
|
||||
public enum Layout {
|
||||
SHOW_EDITOR(KotlinJvmBundle.message("editor.editor.only"), AllIcons.General.LayoutEditorOnly),
|
||||
SHOW_PREVIEW(KotlinJvmBundle.message("editor.preview.only"), AllIcons.General.LayoutPreviewOnly),
|
||||
SHOW_EDITOR_AND_PREVIEW(KotlinJvmBundle.message("editor.editor.and.preview"), AllIcons.General.LayoutEditorPreview);
|
||||
|
||||
private final String myName;
|
||||
private final Icon myIcon;
|
||||
|
||||
Layout(String name, Icon icon) {
|
||||
myName = name;
|
||||
myIcon = icon;
|
||||
}
|
||||
|
||||
public static Layout fromName(String name, Layout defaultValue) {
|
||||
for (Layout layout : Layout.values()) {
|
||||
if (layout.myName.equals(name)) {
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return myIcon;
|
||||
}
|
||||
}
|
||||
|
||||
private class ChangeViewModeAction extends ToggleAction implements DumbAware {
|
||||
private final Layout myActionLayout;
|
||||
|
||||
ChangeViewModeAction(Layout layout) {
|
||||
super(layout.getName(), layout.getName(), layout.getIcon());
|
||||
myActionLayout = layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(@NotNull AnActionEvent e) {
|
||||
return myLayout == myActionLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(@NotNull AnActionEvent e, boolean state) {
|
||||
if (state) {
|
||||
setLayout(myActionLayout);
|
||||
PropertiesComponent.getInstance().setValue(getLayoutPropertyName(), myLayout.myName, Layout.SHOW_EDITOR_AND_PREVIEW.myName);
|
||||
adjustEditorsVisibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getLayoutPropertyName() {
|
||||
return myName + "Layout";
|
||||
}
|
||||
}
|
||||
|
||||
class SplitEditorToolbar extends JPanel implements Disposable {
|
||||
|
||||
private final ActionToolbar myRightToolbar;
|
||||
|
||||
public SplitEditorToolbar(@Nullable ActionToolbar leftToolbar, @NotNull ActionToolbar rightToolbar) {
|
||||
super(new GridBagLayout());
|
||||
myRightToolbar = rightToolbar;
|
||||
|
||||
if (leftToolbar != null) {
|
||||
add(leftToolbar.getComponent());
|
||||
}
|
||||
|
||||
final JPanel centerPanel = new JPanel(new BorderLayout());
|
||||
add(centerPanel, new GridBagConstraints(2, 0, 1, 1, 1.0, 1.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH, JBUI.emptyInsets(), 0, 0));
|
||||
|
||||
add(myRightToolbar.getComponent());
|
||||
|
||||
setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIUtil.CONTRAST_BORDER_COLOR));
|
||||
|
||||
if (leftToolbar != null) leftToolbar.updateActionsImmediately();
|
||||
rightToolbar.updateActionsImmediately();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public void addGutterToTrack(@NotNull EditorGutterComponentEx gutterComponentEx) {}
|
||||
|
||||
public void refresh() {
|
||||
myRightToolbar.updateActionsImmediately();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
@Override
|
||||
public void dispose() {}
|
||||
}
|
||||
@@ -11,5 +11,5 @@ import com.intellij.openapi.project.Project
|
||||
|
||||
// BUNCH: 193
|
||||
fun setTemplateTestingCompat(project: Project, disposable: Disposable) {
|
||||
TemplateManagerImpl.setTemplateTesting(project, disposable)
|
||||
TemplateManagerImpl.setTemplateTesting(disposable)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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.idea.liveTemplates
|
||||
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
// BUNCH: 193
|
||||
fun setTemplateTestingCompat(project: Project, disposable: Disposable) {
|
||||
TemplateManagerImpl.setTemplateTesting(project, disposable)
|
||||
}
|
||||
@@ -27,6 +27,12 @@ dependencies {
|
||||
|
||||
excludeInAndroidStudio(rootProject) { compileOnly(intellijPluginDep("maven")) }
|
||||
|
||||
excludeInAndroidStudio(rootProject) {
|
||||
Platform[202].orHigher {
|
||||
compileOnly(intellijPluginDep("maven-model"))
|
||||
}
|
||||
}
|
||||
|
||||
testCompile(projectTests(":idea"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(projectTests(":idea:idea-test-framework"))
|
||||
@@ -36,6 +42,11 @@ dependencies {
|
||||
testCompileOnly(intellijPluginDep("maven"))
|
||||
testRuntime(intellijPluginDep("maven"))
|
||||
|
||||
Platform[202].orHigher {
|
||||
testCompileOnly(intellijPluginDep("maven-model"))
|
||||
testRuntime(intellijPluginDep("maven-model"))
|
||||
}
|
||||
|
||||
if (Ide.IJ201.orHigher()) {
|
||||
testRuntime(intellijPluginDep("repository-search"))
|
||||
}
|
||||
|
||||
@@ -41,12 +41,14 @@ class ConsoleCompilerHelper(
|
||||
}
|
||||
|
||||
fun compileModule() {
|
||||
if (ExecutionManager.getInstance(project).contentManager.removeRunContent(executor, contentDescriptor)) {
|
||||
ProjectTaskManager.getInstance(project).build(module).onSuccess { executionResult ->
|
||||
if (!module.isDisposed) {
|
||||
KotlinConsoleKeeper.getInstance(project).run(module, previousCompilationFailed = executionResult.hasErrors())
|
||||
if (ExecutionManager.getInstance(project).getContentManager().removeRunContent(executor, contentDescriptor)) {
|
||||
ProjectTaskManager.getInstance(project).build(arrayOf(module), object : ProjectTaskNotification {
|
||||
override fun finished(context: ProjectTaskContext, executionResult: ProjectTaskResult) {
|
||||
if (!module.isDisposed) {
|
||||
KotlinConsoleKeeper.getInstance(project).run(module, previousCompilationFailed = executionResult.errors > 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.console
|
||||
|
||||
import com.intellij.execution.ExecutionManager
|
||||
import com.intellij.execution.Executor
|
||||
import com.intellij.execution.ui.RunContentDescriptor
|
||||
import com.intellij.openapi.compiler.CompilerManager
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.task.ProjectTaskContext
|
||||
import com.intellij.task.ProjectTaskManager
|
||||
import com.intellij.task.ProjectTaskNotification
|
||||
import com.intellij.task.ProjectTaskResult
|
||||
|
||||
class ConsoleCompilerHelper(
|
||||
private val project: Project,
|
||||
private val module: Module,
|
||||
private val executor: Executor,
|
||||
private val contentDescriptor: RunContentDescriptor
|
||||
) {
|
||||
|
||||
fun moduleIsUpToDate(): Boolean {
|
||||
val compilerManager = CompilerManager.getInstance(project)
|
||||
val compilerScope = compilerManager.createModuleCompileScope(module, true)
|
||||
return compilerManager.isUpToDate(compilerScope)
|
||||
}
|
||||
|
||||
fun compileModule() {
|
||||
if (ExecutionManager.getInstance(project).contentManager.removeRunContent(executor, contentDescriptor)) {
|
||||
ProjectTaskManager.getInstance(project).build(module).onSuccess { executionResult ->
|
||||
if (!module.isDisposed) {
|
||||
KotlinConsoleKeeper.getInstance(project).run(module, previousCompilationFailed = executionResult.hasErrors())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.LANGUAGE_VERSION_DI
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils.getAbsolutePath
|
||||
import org.jetbrains.kotlin.test.TestMetadata
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.rethrow
|
||||
@@ -70,9 +71,8 @@ abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFix
|
||||
|
||||
protected open fun fileName(): String = KotlinTestUtils.getTestDataFileName(this::class.java, this.name) ?: (getTestName(false) + ".kt")
|
||||
|
||||
override fun getTestDataPath(): String {
|
||||
return this::class.findAnnotation<TestMetadata>()?.value ?: super.getTestDataPath()
|
||||
}
|
||||
override fun getTestDataPath() =
|
||||
getAbsolutePath(this::class.findAnnotation<TestMetadata>()?.value ?: super.getTestDataPath())
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
@@ -13,8 +13,8 @@ import com.intellij.testFramework.propertyBased.MadTestingUtil
|
||||
|
||||
// BUNCH: 193
|
||||
fun enableAllInspectionsCompat(project: Project, disposable: Disposable) {
|
||||
MadTestingUtil.enableAllInspections(project, disposable)
|
||||
MadTestingUtil.enableAllInspections(project)
|
||||
}
|
||||
|
||||
// BUNCH: 193
|
||||
typealias TestApplicationManager = com.intellij.idea.IdeaTestApplication
|
||||
typealias TestApplicationManager = com.intellij.testFramework.TestApplicationManager
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("UNUSED_PARAMETER")
|
||||
|
||||
package org.jetbrains.kotlin.idea.perf
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.testFramework.propertyBased.MadTestingUtil
|
||||
|
||||
// BUNCH: 193
|
||||
fun enableAllInspectionsCompat(project: Project, disposable: Disposable) {
|
||||
MadTestingUtil.enableAllInspections(project, disposable)
|
||||
}
|
||||
|
||||
// BUNCH: 193
|
||||
typealias TestApplicationManager = com.intellij.idea.IdeaTestApplication
|
||||
@@ -11,5 +11,5 @@ import com.intellij.openapi.project.ex.ProjectManagerEx
|
||||
// BUNCH: 193
|
||||
fun ProjectManagerEx.forceCloseProjectEx(project: Project, dispose: Boolean): Boolean {
|
||||
if (!dispose) error("dispose should be true")
|
||||
return this.forceCloseProject(project, true)
|
||||
return this.forceCloseProject(project)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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.idea.testFramework
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx
|
||||
|
||||
// BUNCH: 193
|
||||
fun ProjectManagerEx.forceCloseProjectEx(project: Project, dispose: Boolean): Boolean {
|
||||
if (!dispose) error("dispose should be true")
|
||||
return this.forceCloseProject(project, true)
|
||||
}
|
||||
@@ -53,8 +53,6 @@ private fun _attachGradleProjectAndRefresh(
|
||||
ExternalSystemUtil.ensureToolWindowInitialized(project, GradleConstants.SYSTEM_ID)
|
||||
}
|
||||
}
|
||||
|
||||
ExternalProjectsManagerImpl.disableProjectWatcherAutoUpdate(project)
|
||||
val settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
|
||||
if (settings.getLinkedProjectSettings(externalProjectPath) == null) {
|
||||
settings.linkProject(gradleProjectSettings)
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.idea.testFramework
|
||||
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import org.jetbrains.plugins.gradle.service.project.open.setupGradleSettings
|
||||
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import org.jetbrains.plugins.gradle.util.GradleLog
|
||||
import java.io.File
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
fun refreshGradleProject(projectPath: String, project: Project) {
|
||||
_importProject(File(projectPath).absolutePath, project)
|
||||
|
||||
dispatchAllInvocationEvents()
|
||||
}
|
||||
|
||||
/**
|
||||
* inspired by org.jetbrains.plugins.gradle.service.project.open.importProject(projectDirectory, project)
|
||||
*/
|
||||
private fun _importProject(projectPath: String, project: Project) {
|
||||
GradleLog.LOG.info("Import project at $projectPath")
|
||||
val projectSdk = ProjectRootManager.getInstance(project).projectSdk
|
||||
assertNotNull(projectSdk, "project SDK not found for ${project.name} at $projectPath")
|
||||
val gradleProjectSettings = GradleProjectSettings()
|
||||
setupGradleSettings(gradleProjectSettings, projectPath, project, projectSdk)
|
||||
|
||||
_attachGradleProjectAndRefresh(gradleProjectSettings, project)
|
||||
}
|
||||
|
||||
/**
|
||||
* inspired by org.jetbrains.plugins.gradle.service.project.open.attachGradleProjectAndRefresh(gradleProjectSettings, project)
|
||||
* except everything is MODAL_SYNC
|
||||
*/
|
||||
private fun _attachGradleProjectAndRefresh(
|
||||
gradleProjectSettings: GradleProjectSettings,
|
||||
project: Project
|
||||
) {
|
||||
val externalProjectPath = gradleProjectSettings.externalProjectPath
|
||||
ExternalProjectsManagerImpl.getInstance(project).runWhenInitialized {
|
||||
DumbService.getInstance(project).runWhenSmart {
|
||||
ExternalSystemUtil.ensureToolWindowInitialized(project, GradleConstants.SYSTEM_ID)
|
||||
}
|
||||
}
|
||||
|
||||
ExternalProjectsManagerImpl.disableProjectWatcherAutoUpdate(project)
|
||||
val settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
|
||||
if (settings.getLinkedProjectSettings(externalProjectPath) == null) {
|
||||
settings.linkProject(gradleProjectSettings)
|
||||
}
|
||||
|
||||
StatefulTestGradleProjectRefreshCallback(externalProjectPath, project).use { callback ->
|
||||
ExternalSystemUtil.refreshProject(
|
||||
externalProjectPath,
|
||||
ImportSpecBuilder(project, GradleConstants.SYSTEM_ID)
|
||||
.use(ProgressExecutionMode.MODAL_SYNC)
|
||||
.callback(callback)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
<pluginDescriptions implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradlePluginDescription"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinNonJvmGutterConfigurator" />
|
||||
<projectResolve implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelResolver" order="first"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectResolverExtension" order="first"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleCoroutineDebugProjectResolver" order="last"/>
|
||||
|
||||
60
idea/resources/META-INF/gradle-java.xml.193
Normal file
60
idea/resources/META-INF/gradle-java.xml.193
Normal file
@@ -0,0 +1,60 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPSourceSetsFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinMPPFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
<pluginDescriptions implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradlePluginDescription"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinNonJvmGutterConfigurator" />
|
||||
<projectResolve implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelResolver" order="first"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectResolverExtension" order="first"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleCoroutineDebugProjectResolver" order="last"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.kapt.idea.KaptProjectResolverExtension" order="last"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.allopen.ide.AllOpenProjectResolverExtension" order="last"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.noarg.ide.NoArgProjectResolverExtension" order="last"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.samWithReceiver.ide.SamWithReceiverProjectResolverExtension" order="last"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleSourceSetDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleLibraryDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinTargetDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.KotlinJavaMPPSourceSetDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.klib.KotlinNativeLibraryDataService"/>
|
||||
<externalSystemTaskNotificationListener implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDefinitionsUpdater"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptOutOfSourceNotificationProvider"/>
|
||||
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinJvmTestClassGradleConfigurationProducer"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinMultiplatformJvmTestClassGradleConfigurationProducer"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinJvmTestMethodGradleConfigurationProducer"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinMultiplatformJvmTestMethodGradleConfigurationProducer"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.allopen.ide.AllOpenGradleProjectImportHandler"/>
|
||||
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.scripting.idea.plugin.ScriptingGradleProjectImportHandler"/>
|
||||
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.kapt.idea.KaptGradleProjectImportHandler"/>
|
||||
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.noarg.ide.NoArgGradleProjectImportHandler"/>
|
||||
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.samWithReceiver.ide.SamWithReceiverGradleProjectImportHandler"/>
|
||||
<gradleProjectImportHandler implementation="org.jetbrains.kotlinx.serialization.idea.KotlinSerializationGradleImportHandler"/>
|
||||
|
||||
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleModuleConfigurator"/>
|
||||
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinJsGradleModuleConfigurator"/>
|
||||
<gradleModelFacade implementation="org.jetbrains.kotlin.idea.inspections.gradle.DefaultGradleModelFacade"/>
|
||||
|
||||
<scriptDefinitionContributor implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDefinitionsContributor" order="first"/>
|
||||
<scriptAdditionalIdeaDependenciesProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptAdditionalIdeaDependenciesProvider"/>
|
||||
|
||||
<moduleBuilder implementation="org.jetbrains.kotlin.ide.konan.gradle.KotlinGradleNativeMultiplatformModuleBuilder"/>
|
||||
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleSharedMultiplatformModuleBuilder"/>
|
||||
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleWebMultiplatformModuleBuilder"/>
|
||||
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleMobileMultiplatformModuleBuilder"/>
|
||||
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleMobileSharedMultiplatformModuleBuilder"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -189,26 +189,15 @@
|
||||
description="Enable bytecode instrumentation for Kotlin classes"
|
||||
defaultValue="false"
|
||||
restartRequired="false"/>
|
||||
<registryKey key="kotlin.debugger.coroutines.standalone"
|
||||
description="Enable debugging for coroutines in Kotlin/JVM with no library support"
|
||||
<registryKey key="kotlin.debugger.coroutines"
|
||||
description="Enable debugging for coroutines in Kotlin/JVM"
|
||||
defaultValue="false"
|
||||
restartRequired="false"/>
|
||||
<registryKey key="kotlin.debugger.coroutines.trace"
|
||||
description="Trace coroutines debugger output"
|
||||
defaultValue="false"
|
||||
restartRequired="false"/>
|
||||
<registryKey key="kotlin.debugger.coroutines.max"
|
||||
description="Maximum amount of coroutines for debug"
|
||||
defaultValue="1000"
|
||||
restartRequired="false"/>
|
||||
<registryKey key="kotlin.debugger.coroutines.switch"
|
||||
description="Continuation information provider possible values are: DISPATCHED_CONTINUATION, CANCELLABLE_CONTINUATION."
|
||||
defaultValue="DISPATCHED_CONTINUATION"
|
||||
restartRequired="false"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.uast">
|
||||
<uastLanguagePlugin implementation="org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin"/>
|
||||
<generate.uastCodeGenerationPlugin implementation="org.jetbrains.uast.kotlin.generate.KotlinUastCodeGenerationPlugin"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
|
||||
242
idea/resources/META-INF/jvm.xml.193
Normal file
242
idea/resources/META-INF/jvm.xml.193
Normal file
@@ -0,0 +1,242 @@
|
||||
<idea-plugin>
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.JvmPluginStartupComponent</implementation-class>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<project-components>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.compiler.KotlinCompilerManager</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerComponent</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.scratch.ScratchFileModuleInfoProvider</implementation-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<actions>
|
||||
<!-- Kotlin Console REPL-->
|
||||
<action id="KotlinConsoleREPL" class="org.jetbrains.kotlin.console.actions.RunKotlinConsoleAction"
|
||||
text="Kotlin REPL"
|
||||
icon="/org/jetbrains/kotlin/idea/icons/kotlin_launch_configuration.png">
|
||||
<add-to-group group-id="KotlinToolsGroup" anchor="last"/>
|
||||
</action>
|
||||
|
||||
<action id="ConfigureKotlinInProject" class="org.jetbrains.kotlin.idea.actions.ConfigureKotlinJavaInProjectAction"
|
||||
text="Configure Kotlin in Project">
|
||||
<add-to-group group-id="KotlinToolsGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="ConfigureKotlinJsInProject" class="org.jetbrains.kotlin.idea.actions.ConfigureKotlinJsInProjectAction"
|
||||
text="Configure Kotlin (JavaScript) in Project">
|
||||
<add-to-group group-id="KotlinToolsGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="ShowKotlinBytecode" class="org.jetbrains.kotlin.idea.actions.ShowKotlinBytecodeAction"
|
||||
text="Show Kotlin Bytecode">
|
||||
<add-to-group group-id="KotlinToolsGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="CreateIncrementalCompilationBackup"
|
||||
class="org.jetbrains.kotlin.idea.internal.makeBackup.CreateIncrementalCompilationBackup" internal="true">
|
||||
<add-to-group group-id="KotlinInternalGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="ReactivePostOpenProjectActionsAction" class="org.jetbrains.kotlin.idea.actions.internal.ReactivePostOpenProjectActionsAction"
|
||||
text="Kotlin Project Post-Open Activity" internal="true">
|
||||
<add-to-group group-id="KotlinInternalGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="AddToProblemApiInspection" class="org.jetbrains.kotlin.idea.inspections.api.AddIncompatibleApiAction"
|
||||
text="Report as incompatible API">
|
||||
</action>
|
||||
|
||||
<group id="Kotlin.XDebugger.Actions">
|
||||
<!-- TODO(design)-->
|
||||
<action id="Kotlin.XDebugger.CoroutinesDump"
|
||||
class="org.jetbrains.kotlin.idea.debugger.coroutine.command.CoroutineDumpAction"
|
||||
text="Get Coroutines Dump"
|
||||
icon="/org/jetbrains/kotlin/idea/icons/kotlin.png"/>
|
||||
</group>
|
||||
|
||||
<action id="Kotlin.XDebugger.ToggleKotlinVariableView"
|
||||
class="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesView"
|
||||
text="Show Kotlin Variables Only">
|
||||
<add-to-group group-id="XDebugger.Settings" relative-to-action="XDebugger.Inline" anchor="after"/>
|
||||
</action>
|
||||
|
||||
<action id="InspectBreakpointApplicability" class="org.jetbrains.kotlin.idea.debugger.breakpoints.InspectBreakpointApplicabilityAction"
|
||||
text="Inspect Breakpoint Applicability" internal="true">
|
||||
<add-to-group group-id="KotlinInternalGroup"/>
|
||||
</action>
|
||||
</actions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.console.KotlinConsoleKeeper"
|
||||
serviceImplementation="org.jetbrains.kotlin.console.KotlinConsoleKeeper"/>
|
||||
|
||||
<buildProcess.parametersProvider implementation="org.jetbrains.kotlin.idea.compiler.configuration.KotlinBuildProcessParametersProvider"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.scratch.ScratchFileAutoRunner"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.scratch.ScratchFileAutoRunner"/>
|
||||
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.versions.SuppressNotificationState"/>
|
||||
|
||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesState"/>
|
||||
|
||||
<debugger.asyncStackTraceProvider implementation="org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineAsyncStackTraceProvider"/>
|
||||
<debugger.jvmSmartStepIntoHandler implementation="org.jetbrains.kotlin.idea.debugger.stepping.smartStepInto.KotlinSmartStepIntoHandler"/>
|
||||
<debugger.positionManagerFactory implementation="org.jetbrains.kotlin.idea.debugger.KotlinPositionManagerFactory"/>
|
||||
<debugger.codeFragmentFactory implementation="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory"/>
|
||||
<debuggerEditorTextProvider language="kotlin" implementationClass="org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider"/>
|
||||
<debuggerClassFilterProvider implementation="org.jetbrains.kotlin.idea.debugger.filter.KotlinDebuggerInternalClassesFilterProvider"/>
|
||||
<debugger.nodeRenderer implementation="org.jetbrains.kotlin.idea.debugger.render.KotlinClassWithDelegatedPropertyRenderer"/>
|
||||
<debugger.sourcePositionProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionProvider"/>
|
||||
<debugger.sourcePositionHighlighter implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionHighlighter"/>
|
||||
<debugger.frameExtraVarsProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinFrameExtraVariablesProvider"/>
|
||||
<debugger.extraSteppingFilter implementation="org.jetbrains.kotlin.idea.KotlinExtraSteppingFilter"/>
|
||||
<xdebugger.settings implementation="org.jetbrains.kotlin.idea.debugger.KotlinDebuggerSettings"/>
|
||||
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointType"/>
|
||||
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinLineBreakpointType" order="first"/>
|
||||
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFunctionBreakpointType"/>
|
||||
<debugger.syntheticProvider implementation="org.jetbrains.kotlin.idea.debugger.filter.KotlinSyntheticTypeComponentProvider"/>
|
||||
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointHandlerFactory"/>
|
||||
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinLineBreakpointHandlerFactory"/>
|
||||
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFunctionBreakpointHandlerFactory"/>
|
||||
<debugger.jvmSteppingCommandProvider implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSteppingCommandProvider"/>
|
||||
<debugger.simplePropertyGetterProvider implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSimpleGetterProvider"/>
|
||||
<runConfigurationExtension implementation="org.jetbrains.kotlin.idea.debugger.coroutine.CoroutineDebugConfigurationExtension"/>
|
||||
|
||||
<framework.type implementation="org.jetbrains.kotlin.idea.framework.JavaFrameworkType"/>
|
||||
<projectTemplatesFactory implementation="org.jetbrains.kotlin.idea.framework.KotlinTemplatesFactory" />
|
||||
|
||||
<library.presentationProvider implementation="org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider"/>
|
||||
|
||||
<configurationType implementation="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationType"/>
|
||||
<configurationType implementation="org.jetbrains.kotlin.idea.run.script.standalone.KotlinStandaloneScriptRunConfigurationType"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationProducer"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.script.standalone.KotlinStandaloneScriptRunConfigurationProducer"/>
|
||||
|
||||
<library.type implementation="org.jetbrains.kotlin.idea.framework.JSLibraryType"/>
|
||||
<library.javaSourceRootDetector implementation="org.jetbrains.kotlin.idea.configuration.KotlinSourceRootDetector"/>
|
||||
|
||||
<multipleRunLocationsProvider implementation="org.jetbrains.kotlin.idea.run.multiplatform.KotlinMultiplatformRunLocationsProvider"/>
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.configuration.KotlinSetupEnvironmentNotificationProvider"/>
|
||||
<postStartupActivity implementation="org.jetbrains.kotlin.idea.configuration.JvmStartupActivity"/>
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinAlternativeSourceNotificationProvider"/>
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.inspections.JavaOutsideModuleDetector"/>
|
||||
|
||||
<consoleFilterProvider implementation="org.jetbrains.kotlin.idea.run.KotlinConsoleFilterProvider"/>
|
||||
|
||||
<exceptionFilter implementation="org.jetbrains.kotlin.idea.filters.KotlinExceptionFilterFactory" order="first"/>
|
||||
|
||||
<externalSystemTaskNotificationListener implementation="org.jetbrains.kotlin.idea.configuration.KotlinExternalSystemSyncListener"/>
|
||||
|
||||
<lang.surroundDescriptor language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.debugger.evaluate.surroundWith.KotlinDebuggerExpressionSurroundDescriptor"/>
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanelProvider"/>
|
||||
|
||||
<scratch.creationHelper language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.scratch.KtScratchFileCreationHelper"/>
|
||||
<runLineMarkerContributor language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.scratch.actions.ScratchRunLineMarkerContributor"/>
|
||||
|
||||
<localInspection
|
||||
groupName="Plugin DevKit"
|
||||
shortName="IncompatibleAPI"
|
||||
enabledByDefault="false"
|
||||
level="ERROR"
|
||||
displayName="Incompatible API usage"
|
||||
implementationClass="org.jetbrains.kotlin.idea.inspections.api.IncompatibleAPIInspection"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.uast.kotlin.KotlinUastResolveProviderService"
|
||||
serviceImplementation="org.jetbrains.uast.kotlin.internal.IdeaKotlinUastResolveProviderService"/>
|
||||
|
||||
<applicationService
|
||||
serviceInterface="org.jetbrains.kotlin.platform.DefaultIdeTargetPlatformKindProvider"
|
||||
serviceImplementation="org.jetbrains.kotlin.platform.impl.IdeaDefaultIdeTargetPlatformKindProvider"/>
|
||||
|
||||
<applicationService
|
||||
serviceInterface="org.jetbrains.kotlin.idea.j2k.J2KPostProcessingRegistrar"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.j2k.J2KPostProcessingRegistrarImpl"/>
|
||||
|
||||
<registryKey key="kotlin.use.ultra.light.classes"
|
||||
description="Whether to use an experimental implementation of Kotlin-as-Java classes"
|
||||
defaultValue="true"
|
||||
restartRequired="false"/>
|
||||
|
||||
<registryKey key="kotlin.ultra.light.classes.empty.text.range"
|
||||
description="Return 'null' text range as in old light class implementation"
|
||||
defaultValue="true"
|
||||
restartRequired="false"/>
|
||||
|
||||
<registryKey key="kotlin.uast.force.uinjectionhost"
|
||||
description="Whether to convert `KtStringTemplateExpression` to `KotlinStringTemplateUPolyadicExpression` in all cases"
|
||||
defaultValue="true"
|
||||
restartRequired="false"/>
|
||||
|
||||
<registryKey key="kotlin.jps.instrument.bytecode"
|
||||
description="Enable bytecode instrumentation for Kotlin classes"
|
||||
defaultValue="false"
|
||||
restartRequired="false"/>
|
||||
<registryKey key="kotlin.debugger.coroutines.standalone"
|
||||
description="Enable debugging for coroutines in Kotlin/JVM with no library support"
|
||||
defaultValue="false"
|
||||
restartRequired="false"/>
|
||||
<registryKey key="kotlin.debugger.coroutines.trace"
|
||||
description="Trace coroutines debugger output"
|
||||
defaultValue="false"
|
||||
restartRequired="false"/>
|
||||
<registryKey key="kotlin.debugger.coroutines.max"
|
||||
description="Maximum amount of coroutines for debug"
|
||||
defaultValue="1000"
|
||||
restartRequired="false"/>
|
||||
<registryKey key="kotlin.debugger.coroutines.switch"
|
||||
description="Continuation information provider possible values are: DISPATCHED_CONTINUATION, CANCELLABLE_CONTINUATION."
|
||||
defaultValue="DISPATCHED_CONTINUATION"
|
||||
restartRequired="false"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.uast">
|
||||
<uastLanguagePlugin implementation="org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<diagnosticSuppressor implementation="org.jetbrains.kotlin.idea.debugger.DiagnosticSuppressorForDebugger"/>
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
|
||||
|
||||
<declarationAttributeAltererExtension implementation="org.jetbrains.kotlin.allopen.ide.IdeAllOpenDeclarationAttributeAltererExtension"/>
|
||||
<ultraLightClassModifierExtension implementation="org.jetbrains.kotlin.allopen.ide.AllOpenUltraLightClassModifierExtension"/>
|
||||
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.noarg.ide.IdeNoArgComponentContainerContributor"/>
|
||||
<expressionCodegenExtension implementation="org.jetbrains.kotlin.noarg.ide.IdeNoArgExpressionCodegenExtension"/>
|
||||
<ultraLightClassModifierExtension implementation="org.jetbrains.kotlin.noarg.ide.NoArgUltraLightClassModifierExtension"/>
|
||||
<defaultErrorMessages implementation="org.jetbrains.kotlin.noarg.diagnostic.DefaultErrorMessagesNoArg"/>
|
||||
|
||||
<completionExtension implementation="org.jetbrains.kotlin.idea.properties.PropertyKeyCompletion"/>
|
||||
<newFileHook implementation="org.jetbrains.kotlin.idea.configuration.NewKotlinFileConfigurationHook"/>
|
||||
<quickFixContributor implementation="org.jetbrains.kotlin.idea.quickfix.JvmQuickFixRegistrar"/>
|
||||
<clearBuildState implementation="org.jetbrains.kotlin.idea.compiler.configuration.ClearBuildManagerState"/>
|
||||
<facetValidatorCreator implementation="org.jetbrains.kotlin.idea.facet.KotlinLibraryValidatorCreator"/>
|
||||
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleJavaFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJavaFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJSFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleGroovyFrameworkSupportProvider" />
|
||||
|
||||
<syntheticScopeProviderExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldSyntheticScopeProvider"/>
|
||||
<expressionCodegenExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldExpressionCodegenExtension"/>
|
||||
<completionInformationProvider implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldCompletionInformationProvider" />
|
||||
<kotlinIndicesHelperExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldKotlinIndicesHelperExtension"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -13,7 +13,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<version>@snapshot@</version>
|
||||
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
|
||||
|
||||
<idea-version since-build="193.4099.13" until-build="193.*"/>
|
||||
<idea-version since-build="201.6487" until-build="202.*"/>
|
||||
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
|
||||
@@ -69,26 +69,29 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<declarationSearcher language="kotlin" implementationClass="org.jetbrains.kotlin.idea.jvm.KotlinDeclarationSearcher"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="2"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.action.refactoring" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.j2k" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.editor" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.new.wizard" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.performance" version="1"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.statistics.IDESettingsFUSCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.formatter.KotlinFormatterUsageCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.statistics.ProjectConfigurationCollector"/>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="2"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.action.refactoring" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.j2k" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.editor" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.new.wizard" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.performance" version="1"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.statistics.IDESettingsFUSCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.formatter.KotlinFormatterUsageCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.statistics.ProjectConfigurationCollector"/>
|
||||
|
||||
<fileTypeUsageSchemaDescriptor schema="Gradle Script" implementationClass="org.jetbrains.kotlin.idea.core.script.KotlinGradleScriptFileTypeSchemaDetector"/>
|
||||
<fileTypeUsageSchemaDescriptor schema="Gradle Script" implementationClass="org.jetbrains.kotlin.idea.core.script.KotlinGradleScriptFileTypeSchemaDetector"/>
|
||||
|
||||
<completion.ml.model implementation="org.jetbrains.kotlin.idea.completion.ml.KotlinMLRankingProvider"/>
|
||||
<completion.ml.contextFeatures language="kotlin" implementationClass="org.jetbrains.kotlin.idea.completion.ml.KotlinContextFeatureProvider"/>
|
||||
</extensions>
|
||||
<completion.ml.model implementation="org.jetbrains.kotlin.idea.completion.ml.KotlinMLRankingProvider"/>
|
||||
<suggestedRefactoringSupport language="kotlin" implementationClass="org.jetbrains.kotlin.idea.refactoring.suggested.KotlinSuggestedRefactoringSupport"/>
|
||||
|
||||
<refactoring.moveInnerHandler language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveKotlinInnerHandler"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
94
idea/resources/META-INF/plugin.xml.193
Normal file
94
idea/resources/META-INF/plugin.xml.193
Normal file
@@ -0,0 +1,94 @@
|
||||
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude" version="2" url="http://kotlinlang.org" allow-bundled-update="true">
|
||||
<id>org.jetbrains.kotlin</id>
|
||||
|
||||
<name>Kotlin</name>
|
||||
<description><![CDATA[
|
||||
The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<br>
|
||||
<a href="http://kotlinlang.org/docs/tutorials/getting-started.html">Getting Started in IntelliJ IDEA</a><br>
|
||||
<a href="http://kotlinlang.org/docs/tutorials/kotlin-android.html">Getting Started in Android Studio</a><br>
|
||||
<a href="http://slack.kotlinlang.org/">Public Slack</a><br>
|
||||
<a href="https://youtrack.jetbrains.com/issues/KT">Issue tracker</a><br>
|
||||
]]></description>
|
||||
<version>@snapshot@</version>
|
||||
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
|
||||
|
||||
<idea-version since-build="193.4099.13" until-build="193.*"/>
|
||||
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
|
||||
<depends optional="true" config-file="junit.xml">JUnit</depends>
|
||||
<depends optional="true" config-file="gradle.xml">com.intellij.gradle</depends>
|
||||
<depends optional="true" config-file="gradle-java.xml">org.jetbrains.plugins.gradle</depends>
|
||||
<depends optional="true" config-file="kotlin-gradle-testing.xml">org.jetbrains.plugins.gradle</depends>
|
||||
<depends optional="true" config-file="gradle-groovy.xml">org.intellij.groovy</depends>
|
||||
<depends optional="true" config-file="maven.xml">org.jetbrains.idea.maven</depends>
|
||||
<depends optional="true" config-file="testng-j.xml">TestNG-J</depends>
|
||||
<depends optional="true" config-file="coverage.xml">Coverage</depends>
|
||||
<depends optional="true" config-file="i18n.xml">com.intellij.java-i18n</depends>
|
||||
<depends optional="true" config-file="decompiler.xml">org.jetbrains.java.decompiler</depends>
|
||||
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
|
||||
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
|
||||
<depends optional="true" config-file="completion-stats.xml">com.intellij.stats.completion</depends>
|
||||
|
||||
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
|
||||
|
||||
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
|
||||
<depends>com.intellij.modules.idea</depends>
|
||||
<depends>com.intellij.modules.java</depends>
|
||||
<depends optional="true" config-file="javaScriptDebug.xml">JavaScriptDebugger</depends>
|
||||
<depends optional="true" config-file="kotlin-copyright.xml">com.intellij.copyright</depends>
|
||||
<depends optional="true" config-file="injection.xml">org.intellij.intelliLang</depends>
|
||||
<!-- CIDR-PLUGIN-PLACEHOLDER-END -->
|
||||
|
||||
<xi:include href="plugin-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<!-- CIDR-PLUGIN-EXCLUDE-START -->
|
||||
<xi:include href="jvm.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<!-- CIDR-PLUGIN-EXCLUDE-END -->
|
||||
|
||||
<xi:include href="native.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="tipsAndTricks.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="extensions/ide.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="kotlinx-serialization.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="scripting-support.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<extensionPoints>
|
||||
<xi:include href="extensions/compiler.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.pluginUpdateVerifier"
|
||||
interface="org.jetbrains.kotlin.idea.update.PluginUpdateVerifier"/>
|
||||
</extensionPoints>
|
||||
|
||||
<xi:include href="plugin-kotlin-extensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij.jvm">
|
||||
<declarationSearcher language="kotlin" implementationClass="org.jetbrains.kotlin.idea.jvm.KotlinDeclarationSearcher"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="2"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.action.refactoring" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.j2k" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.editor" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.new.wizard" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.performance" version="1"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.statistics.IDESettingsFUSCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.formatter.KotlinFormatterUsageCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.statistics.ProjectConfigurationCollector"/>
|
||||
|
||||
<fileTypeUsageSchemaDescriptor schema="Gradle Script" implementationClass="org.jetbrains.kotlin.idea.core.script.KotlinGradleScriptFileTypeSchemaDetector"/>
|
||||
|
||||
<completion.ml.model implementation="org.jetbrains.kotlin.idea.completion.ml.KotlinMLRankingProvider"/>
|
||||
<completion.ml.contextFeatures language="kotlin" implementationClass="org.jetbrains.kotlin.idea.completion.ml.KotlinContextFeatureProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -24,8 +24,8 @@ import org.jetbrains.kotlin.idea.codeInsight.shorten.prepareDelayedRequests
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
|
||||
class KotlinRefactoringHelperForDelayedRequests : RefactoringHelper<Any> {
|
||||
override fun prepareOperation(usages: Array<out UsageInfo>?): Any? {
|
||||
if (usages != null && usages.isNotEmpty()) {
|
||||
override fun prepareOperation(usages: Array<out UsageInfo>): Any? {
|
||||
if (usages.isNotEmpty()) {
|
||||
val project = usages[0].project
|
||||
prepareDelayedRequests(project)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeInsight
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.refactoring.RefactoringHelper
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.prepareDelayedRequests
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
|
||||
class KotlinRefactoringHelperForDelayedRequests : RefactoringHelper<Any> {
|
||||
override fun prepareOperation(usages: Array<out UsageInfo>?): Any? {
|
||||
if (usages != null && usages.isNotEmpty()) {
|
||||
val project = usages[0].project
|
||||
prepareDelayedRequests(project)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun performOperation(project: Project, operationData: Any?) {
|
||||
runWriteAction { performDelayedRefactoringRequests(project) }
|
||||
}
|
||||
}
|
||||
@@ -75,35 +75,35 @@ object KotlinUsageTypeProvider : UsageTypeProviderEx {
|
||||
|
||||
object KotlinUsageTypes {
|
||||
// types
|
||||
val TYPE_CONSTRAINT = UsageType(KotlinBundle.message("find.usages.type.type.constraint"))
|
||||
val VALUE_PARAMETER_TYPE = UsageType(KotlinBundle.message("find.usages.type.value.parameter.type"))
|
||||
val NON_LOCAL_PROPERTY_TYPE = UsageType(KotlinBundle.message("find.usages.type.nonLocal.property.type"))
|
||||
val FUNCTION_RETURN_TYPE = UsageType(KotlinBundle.message("find.usages.type.function.return.type"))
|
||||
val SUPER_TYPE = UsageType(KotlinBundle.message("find.usages.type.superType"))
|
||||
val IS = UsageType(KotlinBundle.message("find.usages.type.is"))
|
||||
val CLASS_OBJECT_ACCESS = UsageType(KotlinBundle.message("find.usages.type.class.object"))
|
||||
val COMPANION_OBJECT_ACCESS = UsageType(KotlinBundle.message("find.usages.type.companion.object"))
|
||||
val EXTENSION_RECEIVER_TYPE = UsageType(KotlinBundle.message("find.usages.type.extension.receiver.type"))
|
||||
val SUPER_TYPE_QUALIFIER = UsageType(KotlinBundle.message("find.usages.type.super.type.qualifier"))
|
||||
val TYPE_ALIAS = UsageType(KotlinBundle.message("find.usages.type.type.alias"))
|
||||
val TYPE_CONSTRAINT = UsageType(KotlinBundle.lazyMessage("find.usages.type.type.constraint"))
|
||||
val VALUE_PARAMETER_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.value.parameter.type"))
|
||||
val NON_LOCAL_PROPERTY_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.nonLocal.property.type"))
|
||||
val FUNCTION_RETURN_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.function.return.type"))
|
||||
val SUPER_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.superType"))
|
||||
val IS = UsageType(KotlinBundle.lazyMessage("find.usages.type.is"))
|
||||
val CLASS_OBJECT_ACCESS = UsageType(KotlinBundle.lazyMessage("find.usages.type.class.object"))
|
||||
val COMPANION_OBJECT_ACCESS = UsageType(KotlinBundle.lazyMessage("find.usages.type.companion.object"))
|
||||
val EXTENSION_RECEIVER_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.extension.receiver.type"))
|
||||
val SUPER_TYPE_QUALIFIER = UsageType(KotlinBundle.lazyMessage("find.usages.type.super.type.qualifier"))
|
||||
val TYPE_ALIAS = UsageType(KotlinBundle.lazyMessage("find.usages.type.type.alias"))
|
||||
|
||||
// functions
|
||||
val FUNCTION_CALL = UsageType(KotlinBundle.message("find.usages.type.function.call"))
|
||||
val IMPLICIT_GET = UsageType(KotlinBundle.message("find.usages.type.implicit.get"))
|
||||
val IMPLICIT_SET = UsageType(KotlinBundle.message("find.usages.type.implicit.set"))
|
||||
val IMPLICIT_INVOKE = UsageType(KotlinBundle.message("find.usages.type.implicit.invoke"))
|
||||
val IMPLICIT_ITERATION = UsageType(KotlinBundle.message("find.usages.type.implicit.iteration"))
|
||||
val PROPERTY_DELEGATION = UsageType(KotlinBundle.message("find.usages.type.property.delegation"))
|
||||
val FUNCTION_CALL = UsageType(KotlinBundle.lazyMessage("find.usages.type.function.call"))
|
||||
val IMPLICIT_GET = UsageType(KotlinBundle.lazyMessage("find.usages.type.implicit.get"))
|
||||
val IMPLICIT_SET = UsageType(KotlinBundle.lazyMessage("find.usages.type.implicit.set"))
|
||||
val IMPLICIT_INVOKE = UsageType(KotlinBundle.lazyMessage("find.usages.type.implicit.invoke"))
|
||||
val IMPLICIT_ITERATION = UsageType(KotlinBundle.lazyMessage("find.usages.type.implicit.iteration"))
|
||||
val PROPERTY_DELEGATION = UsageType(KotlinBundle.lazyMessage("find.usages.type.property.delegation"))
|
||||
|
||||
// values
|
||||
val RECEIVER = UsageType(KotlinBundle.message("find.usages.type.receiver"))
|
||||
val DELEGATE = UsageType(KotlinBundle.message("find.usages.type.delegate"))
|
||||
val RECEIVER = UsageType(KotlinBundle.lazyMessage("find.usages.type.receiver"))
|
||||
val DELEGATE = UsageType(KotlinBundle.lazyMessage("find.usages.type.delegate"))
|
||||
|
||||
// packages
|
||||
val PACKAGE_DIRECTIVE = UsageType(KotlinBundle.message("find.usages.type.packageDirective"))
|
||||
val PACKAGE_MEMBER_ACCESS = UsageType(KotlinBundle.message("find.usages.type.packageMemberAccess"))
|
||||
val PACKAGE_DIRECTIVE = UsageType(KotlinBundle.lazyMessage("find.usages.type.packageDirective"))
|
||||
val PACKAGE_MEMBER_ACCESS = UsageType(KotlinBundle.lazyMessage("find.usages.type.packageMemberAccess"))
|
||||
|
||||
// common usage types
|
||||
val CALLABLE_REFERENCE = UsageType(KotlinBundle.message("find.usages.type.callable.reference"))
|
||||
val NAMED_ARGUMENT = UsageType(KotlinBundle.message("find.usages.type.named.argument"))
|
||||
val CALLABLE_REFERENCE = UsageType(KotlinBundle.lazyMessage("find.usages.type.callable.reference"))
|
||||
val NAMED_ARGUMENT = UsageType(KotlinBundle.lazyMessage("find.usages.type.named.argument"))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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.idea.findUsages
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.usages.UsageTarget
|
||||
import com.intellij.usages.impl.rules.UsageType
|
||||
import com.intellij.usages.impl.rules.UsageTypeProviderEx
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum.*
|
||||
|
||||
object KotlinUsageTypeProvider : UsageTypeProviderEx {
|
||||
override fun getUsageType(element: PsiElement?): UsageType? = getUsageType(element, UsageTarget.EMPTY_ARRAY)
|
||||
|
||||
override fun getUsageType(element: PsiElement?, targets: Array<out UsageTarget>): UsageType? {
|
||||
val usageType = UsageTypeUtils.getUsageType(element) ?: return null
|
||||
return convertEnumToUsageType(usageType)
|
||||
}
|
||||
|
||||
private fun convertEnumToUsageType(usageType: UsageTypeEnum): UsageType = when (usageType) {
|
||||
TYPE_CONSTRAINT -> KotlinUsageTypes.TYPE_CONSTRAINT
|
||||
VALUE_PARAMETER_TYPE -> KotlinUsageTypes.VALUE_PARAMETER_TYPE
|
||||
NON_LOCAL_PROPERTY_TYPE -> KotlinUsageTypes.NON_LOCAL_PROPERTY_TYPE
|
||||
FUNCTION_RETURN_TYPE -> KotlinUsageTypes.FUNCTION_RETURN_TYPE
|
||||
SUPER_TYPE -> KotlinUsageTypes.SUPER_TYPE
|
||||
IS -> KotlinUsageTypes.IS
|
||||
CLASS_OBJECT_ACCESS -> KotlinUsageTypes.CLASS_OBJECT_ACCESS
|
||||
COMPANION_OBJECT_ACCESS -> KotlinUsageTypes.COMPANION_OBJECT_ACCESS
|
||||
EXTENSION_RECEIVER_TYPE -> KotlinUsageTypes.EXTENSION_RECEIVER_TYPE
|
||||
SUPER_TYPE_QUALIFIER -> KotlinUsageTypes.SUPER_TYPE_QUALIFIER
|
||||
TYPE_ALIAS -> KotlinUsageTypes.TYPE_ALIAS
|
||||
|
||||
FUNCTION_CALL -> KotlinUsageTypes.FUNCTION_CALL
|
||||
IMPLICIT_GET -> KotlinUsageTypes.IMPLICIT_GET
|
||||
IMPLICIT_SET -> KotlinUsageTypes.IMPLICIT_SET
|
||||
IMPLICIT_INVOKE -> KotlinUsageTypes.IMPLICIT_INVOKE
|
||||
IMPLICIT_ITERATION -> KotlinUsageTypes.IMPLICIT_ITERATION
|
||||
PROPERTY_DELEGATION -> KotlinUsageTypes.PROPERTY_DELEGATION
|
||||
|
||||
RECEIVER -> KotlinUsageTypes.RECEIVER
|
||||
DELEGATE -> KotlinUsageTypes.DELEGATE
|
||||
|
||||
PACKAGE_DIRECTIVE -> KotlinUsageTypes.PACKAGE_DIRECTIVE
|
||||
PACKAGE_MEMBER_ACCESS -> KotlinUsageTypes.PACKAGE_MEMBER_ACCESS
|
||||
|
||||
CALLABLE_REFERENCE -> KotlinUsageTypes.CALLABLE_REFERENCE
|
||||
|
||||
READ -> UsageType.READ
|
||||
WRITE -> UsageType.WRITE
|
||||
CLASS_IMPORT -> UsageType.CLASS_IMPORT
|
||||
CLASS_LOCAL_VAR_DECLARATION -> UsageType.CLASS_LOCAL_VAR_DECLARATION
|
||||
TYPE_PARAMETER -> UsageType.TYPE_PARAMETER
|
||||
CLASS_CAST_TO -> UsageType.CLASS_CAST_TO
|
||||
ANNOTATION -> UsageType.ANNOTATION
|
||||
CLASS_NEW_OPERATOR -> UsageType.CLASS_NEW_OPERATOR
|
||||
NAMED_ARGUMENT -> KotlinUsageTypes.NAMED_ARGUMENT
|
||||
|
||||
USAGE_IN_STRING_LITERAL -> UsageType.LITERAL_USAGE
|
||||
}
|
||||
}
|
||||
|
||||
object KotlinUsageTypes {
|
||||
// types
|
||||
val TYPE_CONSTRAINT = UsageType(KotlinBundle.message("find.usages.type.type.constraint"))
|
||||
val VALUE_PARAMETER_TYPE = UsageType(KotlinBundle.message("find.usages.type.value.parameter.type"))
|
||||
val NON_LOCAL_PROPERTY_TYPE = UsageType(KotlinBundle.message("find.usages.type.nonLocal.property.type"))
|
||||
val FUNCTION_RETURN_TYPE = UsageType(KotlinBundle.message("find.usages.type.function.return.type"))
|
||||
val SUPER_TYPE = UsageType(KotlinBundle.message("find.usages.type.superType"))
|
||||
val IS = UsageType(KotlinBundle.message("find.usages.type.is"))
|
||||
val CLASS_OBJECT_ACCESS = UsageType(KotlinBundle.message("find.usages.type.class.object"))
|
||||
val COMPANION_OBJECT_ACCESS = UsageType(KotlinBundle.message("find.usages.type.companion.object"))
|
||||
val EXTENSION_RECEIVER_TYPE = UsageType(KotlinBundle.message("find.usages.type.extension.receiver.type"))
|
||||
val SUPER_TYPE_QUALIFIER = UsageType(KotlinBundle.message("find.usages.type.super.type.qualifier"))
|
||||
val TYPE_ALIAS = UsageType(KotlinBundle.message("find.usages.type.type.alias"))
|
||||
|
||||
// functions
|
||||
val FUNCTION_CALL = UsageType(KotlinBundle.message("find.usages.type.function.call"))
|
||||
val IMPLICIT_GET = UsageType(KotlinBundle.message("find.usages.type.implicit.get"))
|
||||
val IMPLICIT_SET = UsageType(KotlinBundle.message("find.usages.type.implicit.set"))
|
||||
val IMPLICIT_INVOKE = UsageType(KotlinBundle.message("find.usages.type.implicit.invoke"))
|
||||
val IMPLICIT_ITERATION = UsageType(KotlinBundle.message("find.usages.type.implicit.iteration"))
|
||||
val PROPERTY_DELEGATION = UsageType(KotlinBundle.message("find.usages.type.property.delegation"))
|
||||
|
||||
// values
|
||||
val RECEIVER = UsageType(KotlinBundle.message("find.usages.type.receiver"))
|
||||
val DELEGATE = UsageType(KotlinBundle.message("find.usages.type.delegate"))
|
||||
|
||||
// packages
|
||||
val PACKAGE_DIRECTIVE = UsageType(KotlinBundle.message("find.usages.type.packageDirective"))
|
||||
val PACKAGE_MEMBER_ACCESS = UsageType(KotlinBundle.message("find.usages.type.packageMemberAccess"))
|
||||
|
||||
// common usage types
|
||||
val CALLABLE_REFERENCE = UsageType(KotlinBundle.message("find.usages.type.callable.reference"))
|
||||
val NAMED_ARGUMENT = UsageType(KotlinBundle.message("find.usages.type.named.argument"))
|
||||
}
|
||||
@@ -10,5 +10,5 @@ import com.intellij.usageView.UsageInfo
|
||||
import com.intellij.util.Processor
|
||||
|
||||
// BUNCH: 193
|
||||
typealias UsageInfoProcessor = Processor<UsageInfo>
|
||||
typealias SliceUsageProcessor = Processor<SliceUsage>
|
||||
typealias UsageInfoProcessor = Processor<in UsageInfo>
|
||||
typealias SliceUsageProcessor = Processor<in SliceUsage>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user